From 6e2ad6ea520c425a4df9eb72dfad6444a0a27e6f Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Wed, 27 Apr 2016 15:57:04 +0300 Subject: [PATCH 1/4] #68[30m]. Add charts option to nav drawer. --- app/src/main/res/drawable-xxxhdpi/ic_charts.png | Bin 0 -> 360 bytes app/src/main/res/menu/menu_nav_drawer.xml | 9 ++++++++- app/src/main/res/values-ru/strings.xml | 2 ++ app/src/main/res/values-uk/strings.xml | 2 ++ app/src/main/res/values/strings.xml | 3 ++- 5 files changed, 14 insertions(+), 2 deletions(-) create mode 100755 app/src/main/res/drawable-xxxhdpi/ic_charts.png diff --git a/app/src/main/res/drawable-xxxhdpi/ic_charts.png b/app/src/main/res/drawable-xxxhdpi/ic_charts.png new file mode 100755 index 0000000000000000000000000000000000000000..b7c5e7d13ca24cc83ea325a323e3e764cba7c1ab GIT binary patch literal 360 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoY)RhkE(}8pX7+2iB`31=M?CIhdQgQ3;T}Q5F0}%(u=&Gl44modEUlHl? zOY2fhrm998LaqNaAtrmzw+EUrN<{Ut?ZS&UA#OgHu3QLCwLZVFrUC zV-iSU?bP0l+XkKlRs~B literal 0 HcmV?d00001 diff --git a/app/src/main/res/menu/menu_nav_drawer.xml b/app/src/main/res/menu/menu_nav_drawer.xml index 7a8b4a4..2865924 100644 --- a/app/src/main/res/menu/menu_nav_drawer.xml +++ b/app/src/main/res/menu/menu_nav_drawer.xml @@ -9,13 +9,20 @@ android:id="@+id/nav_rates" android:icon="@drawable/ic_exchange_rates" android:title="@string/title_exchange_rates" /> + + + + - + Счет по умолчанию Валюта по умолчанию + Графики + diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 6700f77..dc54b18 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -59,4 +59,6 @@ Рахунок за замовчуванням Валюта за замовчуванням + Графіки + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 04a347c..e29da69 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -65,6 +65,7 @@ %1$s - %2$s Default currency - + Charts + From d2167d846d0e55c55d2de8b53ebabe738123e29c Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Wed, 27 Apr 2016 16:30:24 +0300 Subject: [PATCH 2/4] #68[1h]. Add MpCharts dependency. Change Log to Timber. --- app/build.gradle | 6 ++++++ .../blogspot/e_kanivets/moneytracker/MtApp.java | 13 +++++++++++++ .../moneytracker/activity/ExportActivity.java | 4 ++-- .../moneytracker/repo/base/BaseRepo.java | 15 +++++++-------- app/src/main/res/values/strings.xml | 2 +- build.gradle | 5 ++--- 6 files changed, 31 insertions(+), 14 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 508e08a..6a7902c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -48,8 +48,14 @@ dependencies { compile 'com.android.support:support-v4:23.2.1' compile 'com.android.support:appcompat-v7:23.2.1' compile 'com.android.support:design:23.2.1' + // View annotation bindings compile 'com.jakewharton:butterknife:7.0.1' + // Dependency injection tool compile 'com.google.dagger:dagger:2.0.1' + // Charts + compile 'com.github.PhilJay:MPAndroidChart:v2.2.4' + // Advanced logging tool + compile 'com.jakewharton.timber:timber:4.1.2' apt 'com.google.dagger:dagger-compiler:2.0.1' provided 'org.glassfish:javax.annotation:10.0-b28' diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/MtApp.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/MtApp.java index 32fa592..f5c0e0a 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/MtApp.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/MtApp.java @@ -7,6 +7,8 @@ import com.blogspot.e_kanivets.moneytracker.di.module.ControllerModule; import com.blogspot.e_kanivets.moneytracker.di.module.repo.CachedRepoModule; +import timber.log.Timber; + /** * Custom application implementation. * Created on 29/08/14. @@ -29,6 +31,9 @@ public void onCreate() { mtApp = this; component = buildComponent(); + + if (BuildConfig.DEBUG) Timber.plant(new Timber.DebugTree()); + else Timber.plant(new ReleaseTree()); } public AppComponent getAppComponent() { @@ -41,4 +46,12 @@ private AppComponent buildComponent() { .controllerModule(new ControllerModule(get())) .build(); } + + private static class ReleaseTree extends Timber.Tree { + + @Override + protected void log(int priority, String tag, String message, Throwable t) { + // Do nothing fot now + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/ExportActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/ExportActivity.java index 0842275..7fd3cad 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/ExportActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/ExportActivity.java @@ -4,7 +4,6 @@ import android.net.Uri; import android.support.annotation.NonNull; import android.support.v4.content.FileProvider; -import android.util.Log; import com.blogspot.e_kanivets.moneytracker.R; import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity; @@ -18,6 +17,7 @@ import javax.inject.Inject; import butterknife.OnClick; +import timber.log.Timber; public class ExportActivity extends BaseBackActivity { @SuppressWarnings("unused") @@ -46,7 +46,7 @@ public void exportRecords() { File exportDir = new File(getCacheDir(), "export"); boolean exportDirCreated = exportDir.mkdirs(); - Log.d(TAG, "exportDirCreated: " + exportDirCreated); + Timber.d("ExportDirCreated: %b", exportDirCreated); File outFile; if (exportDir.exists()) outFile = new File(exportDir, DEFAULT_EXPORT_FILE_NAME); diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/repo/base/BaseRepo.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/repo/base/BaseRepo.java index 632d353..349d407 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/repo/base/BaseRepo.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/repo/base/BaseRepo.java @@ -5,13 +5,14 @@ import android.database.sqlite.SQLiteDatabase; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.util.Log; import com.blogspot.e_kanivets.moneytracker.repo.DbHelper; import com.blogspot.e_kanivets.moneytracker.entity.base.IEntity; import java.util.List; +import timber.log.Timber; + /** * Base implementation of {@link IRepo}. * No need to call db.close() at all, because SQLiteOpenHelper manage it for us + cache instances. @@ -21,8 +22,6 @@ * @author Evgenii Kanivets */ public abstract class BaseRepo implements IRepo { - private static final String TAG = "BaseRepo"; - protected DbHelper dbHelper; public BaseRepo(DbHelper dbHelper) { @@ -46,11 +45,11 @@ public T create(@Nullable T instance) { long id = db.insert(getTable(), null, contentValues(instance)); if (id == -1) { - Log.d(TAG, "Couldn't create record : " + instance); + Timber.d("Couldn't create record: %s", instance); return null; } else { T createdInstance = read(id); - Log.d(TAG, "Created record : " + createdInstance); + Timber.d("Created record: %s", createdInstance); return createdInstance; } } @@ -75,11 +74,11 @@ public T update(@Nullable T instance) { long rowsAffected = db.update(getTable(), contentValues(instance), "id=?", args); if (rowsAffected == 0) { - Log.d(TAG, "Couldn't update record : " + instance); + Timber.d("Couldn't update record: %s", instance); return null; } else { T updatedInstance = read(instance.getId()); - Log.d(TAG, "Updated record : " + updatedInstance); + Timber.d("Updated record: %s", updatedInstance); return updatedInstance; } } @@ -99,7 +98,7 @@ public boolean delete(@Nullable T instance) { String[] args = new String[]{Long.toString(instance.getId())}; long rowsAffected = db.delete(getTable(), "id=?", args); - Log.d(TAG, instance + (rowsAffected == 0 ? " didn't " : " ") + "deleted"); + Timber.d("%s %s deleted", instance, (rowsAffected == 0 ? " didn't " : " ")); return rowsAffected != 0; } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e29da69..b4a224a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -45,7 +45,7 @@ To Exchange rates Add exchange rate - "]]> + " -> " Account was removed 1 = diff --git a/build.gradle b/build.gradle index b180567..9ebcc91 100644 --- a/build.gradle +++ b/build.gradle @@ -11,8 +11,7 @@ buildscript { allprojects { repositories { mavenCentral() - maven{ - url 'https://oss.sonatype.org/content/repositories/snapshots/' - } + maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } + maven { url "https://jitpack.io" } } } \ No newline at end of file From d08677b55f1ec33f80c73b989e997fba2c723455 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Wed, 27 Apr 2016 18:54:46 +0300 Subject: [PATCH 3/4] #68[2h]. Add Charts screen with BarChart. Add mock data. --- app/src/main/AndroidManifest.xml | 5 + .../moneytracker/activity/ChartsActivity.java | 37 ++++++ .../moneytracker/activity/ReportActivity.java | 10 +- .../activity/base/BaseDrawerActivity.java | 5 + .../activity/record/MainActivity.java | 4 +- .../adapter/ExpandableListReportAdapter.java | 8 +- .../moneytracker/report/ReportMaker.java | 9 +- .../report/chart/BarChartConverter.java | 105 ++++++++++++++++++ .../IRecordReport.java} | 6 +- .../{Report.java => record/RecordReport.java} | 15 ++- .../RecordReportConverter.java} | 15 ++- .../{ => record}/model/CategoryRecord.java | 2 +- .../{ => record}/model/SummaryRecord.java | 2 +- .../ui/presenter/ShortSummaryPresenter.java | 4 +- app/src/main/res/layout/activity_charts.xml | 37 ++++++ .../moneytracker/report/ReportTest.java | 37 +++--- 16 files changed, 245 insertions(+), 56 deletions(-) create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/ChartsActivity.java create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/BarChartConverter.java rename app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/{base/IReport.java => record/IRecordReport.java} (82%) rename app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/{Report.java => record/RecordReport.java} (92%) rename app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/{ReportConverter.java => record/RecordReportConverter.java} (82%) rename app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/{ => record}/model/CategoryRecord.java (95%) rename app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/{ => record}/model/SummaryRecord.java (95%) create mode 100644 app/src/main/res/layout/activity_charts.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 49cd21d..5054471 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -68,6 +68,11 @@ android:label="@string/title_settings" android:screenOrientation="portrait" android:theme="@style/Theme.Default" /> + values, boolean groupV if (viewHolder == null) viewHolder = new ViewHolder(view); /* Customize view to fit to model and UI */ - Double price = Double.parseDouble(values.get(ReportConverter.PRICE_PARAM_NAME)); + Double price = Double.parseDouble(values.get(RecordReportConverter.PRICE_PARAM_NAME)); if (groupView) view.setBackgroundColor(price < 0 ? whiteRed : whiteGreen); else view.setBackgroundColor(white); @@ -83,7 +83,7 @@ private void customizeView(View view, Map values, boolean groupV //Set color of total viewHolder.tvTotal.setTextColor(price >= 0 ? green : red); - viewHolder.tvCategory.setText(values.get(ReportConverter.TITLE_PARAM_NAME)); + viewHolder.tvCategory.setText(values.get(RecordReportConverter.TITLE_PARAM_NAME)); viewHolder.tvTotal.setText(format(price)); } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/ReportMaker.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/ReportMaker.java index 9e6b5f7..c22fd5b 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/ReportMaker.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/ReportMaker.java @@ -10,7 +10,8 @@ import com.blogspot.e_kanivets.moneytracker.entity.data.Record; import com.blogspot.e_kanivets.moneytracker.report.base.IAccountsReport; import com.blogspot.e_kanivets.moneytracker.report.base.IExchangeRateProvider; -import com.blogspot.e_kanivets.moneytracker.report.base.IReport; +import com.blogspot.e_kanivets.moneytracker.report.record.IRecordReport; +import com.blogspot.e_kanivets.moneytracker.report.record.RecordReport; import java.util.ArrayList; import java.util.List; @@ -18,7 +19,7 @@ import java.util.TreeSet; /** - * Util class to encapsulate {@link Report} generation logic. + * Util class to encapsulate {@link RecordReport} generation logic. * Created on 2/26/16. * * @author Evgenii Kanivets @@ -31,11 +32,11 @@ public ReportMaker(ExchangeRateController exchangeRateController) { } @Nullable - public IReport getReport(String currency, Period period, List recordList) { + public IRecordReport getReport(String currency, Period period, List recordList) { if (currencyNeeded(currency, recordList).size() != 0) return null; IExchangeRateProvider rateProvider = new ExchangeRateProvider(currency, rateController); - return new Report(currency, period, recordList, rateProvider); + return new RecordReport(currency, period, recordList, rateProvider); } @Nullable diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/BarChartConverter.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/BarChartConverter.java new file mode 100644 index 0000000..9cc1417 --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/BarChartConverter.java @@ -0,0 +1,105 @@ +package com.blogspot.e_kanivets.moneytracker.report.chart; + +import android.content.Context; +import android.support.annotation.NonNull; + +import com.blogspot.e_kanivets.moneytracker.R; +import com.github.mikephil.charting.data.BarDataSet; +import com.github.mikephil.charting.data.BarEntry; +import com.github.mikephil.charting.interfaces.datasets.IBarDataSet; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Util class to convert {@link BarChartReport} + * to {@link com.github.mikephil.charting.charts.BarChart} input data. + * Created on 4/27/16. + * + * @author Evgenii Kanivets + */ +public class BarChartConverter { + private final int green; + private final int red; + + public BarChartConverter(Context context) { + green = context.getResources().getColor(R.color.green_light); + red = context.getResources().getColor(R.color.red_light); + } + + @NonNull + public List getXAxisValueList() { + List valueList = new ArrayList<>(); + String[] xVals = {"Jan 16", "Feb 16", "Mar 16", "Apr 16", "May 16", "Jun 16", "Jul 16", + "Aug 16", "Sep 16", "Oct 16", "Nov 16", "Dec 16", "Jan 17", "Feb 17", "Mar 17", + "Apr 17", "May 17", "Jun 17", "Jul 17", "Aug 17", "Sep 17", "Oct 17", "Nov 17", "Dec 17"}; + valueList.addAll(Arrays.asList(xVals)); + return valueList; + } + + @NonNull + public List getBarDataSetList() { + List list1 = new ArrayList<>(); + list1.add(new BarEntry(100, 0)); + list1.add(new BarEntry(110, 1)); + list1.add(new BarEntry(60, 2)); + list1.add(new BarEntry(90, 3)); + list1.add(new BarEntry(150, 4)); + list1.add(new BarEntry(50, 5)); + list1.add(new BarEntry(100, 6)); + list1.add(new BarEntry(110, 7)); + list1.add(new BarEntry(60, 8)); + list1.add(new BarEntry(90, 9)); + list1.add(new BarEntry(150, 10)); + list1.add(new BarEntry(50, 11)); + list1.add(new BarEntry(100, 12)); + list1.add(new BarEntry(110, 13)); + list1.add(new BarEntry(60, 14)); + list1.add(new BarEntry(90, 15)); + list1.add(new BarEntry(150, 16)); + list1.add(new BarEntry(50, 17)); + list1.add(new BarEntry(100, 18)); + list1.add(new BarEntry(110, 19)); + list1.add(new BarEntry(60, 20)); + list1.add(new BarEntry(90, 21)); + list1.add(new BarEntry(150, 22)); + list1.add(new BarEntry(50, 23)); + BarDataSet dataSet1 = new BarDataSet(list1, "Incomes"); + dataSet1.setColor(green); + + List list2 = new ArrayList<>(); + list2.add(new BarEntry(50, 0)); + list2.add(new BarEntry(10, 1)); + list2.add(new BarEntry(30, 2)); + list2.add(new BarEntry(30, 3)); + list2.add(new BarEntry(50, 4)); + list2.add(new BarEntry(10, 5)); + list2.add(new BarEntry(50, 6)); + list2.add(new BarEntry(10, 7)); + list2.add(new BarEntry(30, 8)); + list2.add(new BarEntry(30, 9)); + list2.add(new BarEntry(50, 10)); + list2.add(new BarEntry(10, 11)); + list2.add(new BarEntry(100, 12)); + list2.add(new BarEntry(110, 13)); + list2.add(new BarEntry(60, 14)); + list2.add(new BarEntry(90, 15)); + list2.add(new BarEntry(150, 16)); + list2.add(new BarEntry(50, 17)); + list2.add(new BarEntry(100, 18)); + list2.add(new BarEntry(110, 19)); + list2.add(new BarEntry(60, 20)); + list2.add(new BarEntry(90, 21)); + list2.add(new BarEntry(150, 22)); + list2.add(new BarEntry(50, 23)); + BarDataSet dataSet2 = new BarDataSet(list2, "Expenses"); + dataSet2.setColor(red); + + List list = new ArrayList<>(); + list.add(dataSet1); + list.add(dataSet2); + + return list; + } +} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/base/IReport.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/record/IRecordReport.java similarity index 82% rename from app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/base/IReport.java rename to app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/record/IRecordReport.java index 086bfd7..90d8e72 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/base/IReport.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/record/IRecordReport.java @@ -1,9 +1,9 @@ -package com.blogspot.e_kanivets.moneytracker.report.base; +package com.blogspot.e_kanivets.moneytracker.report.record; import android.support.annotation.NonNull; import com.blogspot.e_kanivets.moneytracker.entity.Period; -import com.blogspot.e_kanivets.moneytracker.report.model.CategoryRecord; +import com.blogspot.e_kanivets.moneytracker.report.record.model.CategoryRecord; import java.util.List; @@ -13,7 +13,7 @@ * * @author Evgenii Kanivets */ -public interface IReport { +public interface IRecordReport { /** * @return code of report currency */ diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/Report.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/record/RecordReport.java similarity index 92% rename from app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/Report.java rename to app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/record/RecordReport.java index cc4a4d2..bac23af 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/Report.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/record/RecordReport.java @@ -1,4 +1,4 @@ -package com.blogspot.e_kanivets.moneytracker.report; +package com.blogspot.e_kanivets.moneytracker.report.record; import android.support.annotation.NonNull; @@ -6,9 +6,8 @@ import com.blogspot.e_kanivets.moneytracker.entity.Period; import com.blogspot.e_kanivets.moneytracker.entity.data.Record; import com.blogspot.e_kanivets.moneytracker.report.base.IExchangeRateProvider; -import com.blogspot.e_kanivets.moneytracker.report.base.IReport; -import com.blogspot.e_kanivets.moneytracker.report.model.CategoryRecord; -import com.blogspot.e_kanivets.moneytracker.report.model.SummaryRecord; +import com.blogspot.e_kanivets.moneytracker.report.record.model.CategoryRecord; +import com.blogspot.e_kanivets.moneytracker.report.record.model.SummaryRecord; import java.util.ArrayList; import java.util.Collections; @@ -18,14 +17,14 @@ import java.util.TreeMap; /** - * First {@link IReport} implementation. + * First {@link IRecordReport} implementation. * Created on 2/25/16. * * @author Evgenii Kanivets */ -public class Report implements IReport { +public class RecordReport implements IRecordReport { @SuppressWarnings("unused") - private static final String TAG = "Report"; + private static final String TAG = "RecordReport"; private String currency; private Period period; @@ -35,7 +34,7 @@ public class Report implements IReport { private double totalExpense; private List categoryRecordList; - public Report(String currency, Period period, List recordList, IExchangeRateProvider rateProvider) { + public RecordReport(String currency, Period period, List recordList, IExchangeRateProvider rateProvider) { if (currency == null || period == null || recordList == null || rateProvider == null) throw new NullPointerException("Params can't be null"); diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/ReportConverter.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/record/RecordReportConverter.java similarity index 82% rename from app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/ReportConverter.java rename to app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/record/RecordReportConverter.java index 912c602..07ad91a 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/ReportConverter.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/record/RecordReportConverter.java @@ -1,12 +1,11 @@ -package com.blogspot.e_kanivets.moneytracker.report; +package com.blogspot.e_kanivets.moneytracker.report.record; import android.support.annotation.LayoutRes; import android.support.annotation.NonNull; import com.blogspot.e_kanivets.moneytracker.R; -import com.blogspot.e_kanivets.moneytracker.report.base.IReport; -import com.blogspot.e_kanivets.moneytracker.report.model.CategoryRecord; -import com.blogspot.e_kanivets.moneytracker.report.model.SummaryRecord; +import com.blogspot.e_kanivets.moneytracker.report.record.model.CategoryRecord; +import com.blogspot.e_kanivets.moneytracker.report.record.model.SummaryRecord; import java.util.ArrayList; import java.util.HashMap; @@ -14,18 +13,18 @@ import java.util.Map; /** - * Util class to convert {@link Report} to {@link android.widget.ExpandableListView} input data. + * Util class to convert {@link RecordReport} to {@link android.widget.ExpandableListView} input data. * Created on 2/26/16. * * @author Evgenii Kanivets */ -public class ReportConverter { +public class RecordReportConverter { public static final String TITLE_PARAM_NAME = "title"; public static final String PRICE_PARAM_NAME = "price"; - private final IReport report; + private final IRecordReport report; - public ReportConverter(@NonNull IReport report) { + public RecordReportConverter(@NonNull IRecordReport report) { this.report = report; } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/model/CategoryRecord.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/record/model/CategoryRecord.java similarity index 95% rename from app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/model/CategoryRecord.java rename to app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/record/model/CategoryRecord.java index 306a59d..3563c06 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/model/CategoryRecord.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/record/model/CategoryRecord.java @@ -1,4 +1,4 @@ -package com.blogspot.e_kanivets.moneytracker.report.model; +package com.blogspot.e_kanivets.moneytracker.report.record.model; import android.support.annotation.NonNull; diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/model/SummaryRecord.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/record/model/SummaryRecord.java similarity index 95% rename from app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/model/SummaryRecord.java rename to app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/record/model/SummaryRecord.java index 94bd588..e60ab03 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/model/SummaryRecord.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/record/model/SummaryRecord.java @@ -1,4 +1,4 @@ -package com.blogspot.e_kanivets.moneytracker.report.model; +package com.blogspot.e_kanivets.moneytracker.report.record.model; import android.support.annotation.NonNull; diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/ui/presenter/ShortSummaryPresenter.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/ui/presenter/ShortSummaryPresenter.java index 20b329f..2faeea6 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/ui/presenter/ShortSummaryPresenter.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/ui/presenter/ShortSummaryPresenter.java @@ -6,7 +6,7 @@ import android.widget.TextView; import com.blogspot.e_kanivets.moneytracker.R; -import com.blogspot.e_kanivets.moneytracker.report.base.IReport; +import com.blogspot.e_kanivets.moneytracker.report.record.IRecordReport; import com.blogspot.e_kanivets.moneytracker.ui.presenter.base.BaseSummaryPresenter; import java.util.List; @@ -46,7 +46,7 @@ public View create(boolean shortSummary) { return view; } - public void update(IReport report, String currency, List ratesNeeded) { + public void update(IRecordReport report, String currency, List ratesNeeded) { ViewHolder viewHolder = (ViewHolder) view.getTag(); if (report == null) { diff --git a/app/src/main/res/layout/activity_charts.xml b/app/src/main/res/layout/activity_charts.xml new file mode 100644 index 0000000..9c3df6a --- /dev/null +++ b/app/src/main/res/layout/activity_charts.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/test/java/com/blogspot/e_kanivets/moneytracker/report/ReportTest.java b/app/src/test/java/com/blogspot/e_kanivets/moneytracker/report/ReportTest.java index 68e743e..9ab1d7f 100644 --- a/app/src/test/java/com/blogspot/e_kanivets/moneytracker/report/ReportTest.java +++ b/app/src/test/java/com/blogspot/e_kanivets/moneytracker/report/ReportTest.java @@ -9,9 +9,10 @@ import com.blogspot.e_kanivets.moneytracker.entity.data.Record; import com.blogspot.e_kanivets.moneytracker.entity.Period; import com.blogspot.e_kanivets.moneytracker.report.base.IExchangeRateProvider; -import com.blogspot.e_kanivets.moneytracker.report.base.IReport; -import com.blogspot.e_kanivets.moneytracker.report.model.CategoryRecord; -import com.blogspot.e_kanivets.moneytracker.report.model.SummaryRecord; +import com.blogspot.e_kanivets.moneytracker.report.record.IRecordReport; +import com.blogspot.e_kanivets.moneytracker.report.record.model.CategoryRecord; +import com.blogspot.e_kanivets.moneytracker.report.record.model.SummaryRecord; +import com.blogspot.e_kanivets.moneytracker.report.record.RecordReport; import org.junit.After; import org.junit.Before; @@ -47,13 +48,13 @@ public void tearDown() throws Exception { @Test public void testForNulls() throws Exception { - IReport report; + IRecordReport report; Period period = new Period(new Date(1), new Date(), Period.TYPE_CUSTOM); List recordList = new ArrayList<>(); try { - report = new Report(null, period, recordList, rateProvider); + report = new RecordReport(null, period, recordList, rateProvider); } catch (NullPointerException e) { report = null; } @@ -61,7 +62,7 @@ public void testForNulls() throws Exception { assertNull(report); try { - report = new Report(currency, null, recordList, rateProvider); + report = new RecordReport(currency, null, recordList, rateProvider); } catch (NullPointerException e) { report = null; } @@ -69,7 +70,7 @@ public void testForNulls() throws Exception { assertNull(report); try { - report = new Report(currency, period, null, rateProvider); + report = new RecordReport(currency, period, null, rateProvider); } catch (NullPointerException e) { report = null; } @@ -77,7 +78,7 @@ public void testForNulls() throws Exception { assertNull(report); try { - report = new Report(currency, period, recordList, null); + report = new RecordReport(currency, period, recordList, null); } catch (NullPointerException e) { report = null; } @@ -85,7 +86,7 @@ public void testForNulls() throws Exception { assertNull(report); try { - report = new Report(null, null, null, null); + report = new RecordReport(null, null, null, null); } catch (NullPointerException e) { report = null; } @@ -93,7 +94,7 @@ public void testForNulls() throws Exception { assertNull(report); try { - report = new Report(currency, period, recordList, rateProvider); + report = new RecordReport(currency, period, recordList, rateProvider); } catch (NullPointerException e) { report = null; } @@ -106,12 +107,12 @@ public void testGetCurrency() throws Exception { Period period = new Period(new Date(1), new Date(), Period.TYPE_CUSTOM); List recordList = new ArrayList<>(); - IReport report = new Report(currency, period, recordList, rateProvider); + IRecordReport report = new RecordReport(currency, period, recordList, rateProvider); assertEquals(currency, report.getCurrency()); currency = "KHI"; - report = new Report(currency, period, recordList, rateProvider); + report = new RecordReport(currency, period, recordList, rateProvider); assertEquals(currency, report.getCurrency()); } @@ -121,12 +122,12 @@ public void testGetPeriod() throws Exception { Period period = new Period(new Date(1), new Date(), Period.TYPE_CUSTOM); List recordList = new ArrayList<>(); - IReport report = new Report(currency, period, recordList, rateProvider); + IRecordReport report = new RecordReport(currency, period, recordList, rateProvider); assertEquals(period, report.getPeriod()); period = new Period(new Date(3), new Date(100), Period.TYPE_CUSTOM); - report = new Report(currency, period, recordList, rateProvider); + report = new RecordReport(currency, period, recordList, rateProvider); assertEquals(period, report.getPeriod()); } @@ -137,7 +138,7 @@ public void testGetTotal() throws Exception { List recordList = getRecordList(); - IReport report = new Report(currency, period, recordList, rateProvider); + IRecordReport report = new RecordReport(currency, period, recordList, rateProvider); double expectedTotal = 10 * 4 - 2 + 5 - 10 * 4; assertEquals(expectedTotal, report.getTotal(), 0.0000000001); @@ -149,7 +150,7 @@ public void testGetTotalIncome() throws Exception { List recordList = getRecordList(); - IReport report = new Report(currency, period, recordList, rateProvider); + IRecordReport report = new RecordReport(currency, period, recordList, rateProvider); double expectedTotal = 10 * 4 + 5; assertEquals(expectedTotal, report.getTotalIncome(), 0.0000000001); @@ -161,7 +162,7 @@ public void testGetTotalExpense() throws Exception { List recordList = getRecordList(); - IReport report = new Report(currency, period, recordList, rateProvider); + IRecordReport report = new RecordReport(currency, period, recordList, rateProvider); double expectedTotal = -2 - 10 * 4; assertEquals(expectedTotal, report.getTotalExpense(), 0.0000000001); @@ -186,7 +187,7 @@ public void testGetSummary() throws Exception { Record record4 = new Record(4, 3, Record.TYPE_EXPENSE, "4", category, 10, account2, "USD"); recordList.add(record4); - IReport report = new Report(currency, period, recordList, rateProvider); + IRecordReport report = new RecordReport(currency, period, recordList, rateProvider); List categoryRecordList = new ArrayList<>(); From 07f2dbcaf8d7b9d4bae55cac833ad09f935f2ca1 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Thu, 28 Apr 2016 12:57:58 +0300 Subject: [PATCH 4/4] #68[2h]. Add MonthReport. Finish bar chart. --- .../moneytracker/activity/ChartsActivity.java | 66 ++++++- .../moneytracker/activity/ReportActivity.java | 2 +- .../activity/record/MainActivity.java | 2 +- .../moneytracker/di/AppComponent.java | 3 + .../moneytracker/report/ReportMaker.java | 15 +- .../report/{ => account}/AccountsReport.java | 4 +- .../{base => account}/IAccountsReport.java | 2 +- .../report/chart/BarChartConverter.java | 99 ++++------- .../report/chart/IMonthReport.java | 37 ++++ .../report/chart/MonthReport.java | 167 ++++++++++++++++++ .../presenter/AccountsSummaryPresenter.java | 2 +- app/src/main/res/values-ru/strings.xml | 2 + app/src/main/res/values-uk/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + 14 files changed, 325 insertions(+), 80 deletions(-) rename app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/{ => account}/AccountsReport.java (92%) rename app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/{base => account}/IAccountsReport.java (87%) create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/IMonthReport.java create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/MonthReport.java diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/ChartsActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/ChartsActivity.java index ff9aa24..28ba5d2 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/ChartsActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/ChartsActivity.java @@ -2,14 +2,31 @@ import com.blogspot.e_kanivets.moneytracker.R; import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity; +import com.blogspot.e_kanivets.moneytracker.controller.CurrencyController; +import com.blogspot.e_kanivets.moneytracker.controller.data.ExchangeRateController; +import com.blogspot.e_kanivets.moneytracker.controller.data.RecordController; +import com.blogspot.e_kanivets.moneytracker.entity.data.Record; +import com.blogspot.e_kanivets.moneytracker.report.ReportMaker; import com.blogspot.e_kanivets.moneytracker.report.chart.BarChartConverter; +import com.blogspot.e_kanivets.moneytracker.report.chart.IMonthReport; import com.github.mikephil.charting.charts.BarChart; import com.github.mikephil.charting.data.BarData; +import java.util.List; + +import javax.inject.Inject; + import butterknife.Bind; public class ChartsActivity extends BaseBackActivity { + @Inject + RecordController recordController; + @Inject + ExchangeRateController exchangeRateController; + @Inject + CurrencyController currencyController; + @Bind(R.id.bar_chart) BarChart barChart; @@ -18,20 +35,51 @@ protected int getContentViewId() { return R.layout.activity_charts; } + @Override + protected boolean initData() { + boolean result = super.initData(); + getAppComponent().inject(ChartsActivity.this); + return result; + } + @Override protected void initViews() { super.initViews(); - BarChartConverter barChartConverter = new BarChartConverter(ChartsActivity.this); + ReportMaker reportMaker = new ReportMaker(exchangeRateController); + String currency = currencyController.readDefaultCurrency(); + List recordList = recordController.readAll(); + List currencyNeeded = reportMaker.currencyNeeded(currency, recordList); + + IMonthReport monthReport = null; + if (currencyNeeded.isEmpty()) monthReport = reportMaker.getMonthReport(currency, recordList); + else barChart.setNoDataText(createRatesNeededList(currency, currencyNeeded)); + + if (monthReport != null) { + BarChartConverter barChartConverter = new BarChartConverter(ChartsActivity.this, + monthReport); + + BarData barData = new BarData(barChartConverter.getXAxisValueList(), + barChartConverter.getBarDataSetList()); + barData.setDrawValues(false); + + barChart.setData(barData); + barChart.setDescription(null); + barChart.setVisibleXRangeMinimum(8); + barChart.setScaleYEnabled(false); + barChart.setVisibleXRangeMaximum(34); + barChart.setHighlightPerDragEnabled(false); + barChart.setHighlightPerTapEnabled(false); + } + } + + protected String createRatesNeededList(String currency, List ratesNeeded) { + StringBuilder sb = new StringBuilder(getString(R.string.error_exchange_rates)); - BarData barData = new BarData(barChartConverter.getXAxisValueList(), - barChartConverter.getBarDataSetList()); - barData.setDrawValues(false); + for (String str : ratesNeeded) { + sb.append("\n").append(str).append(getString(R.string.arrow)).append(currency); + } - barChart.setData(barData); - barChart.setDescription(null); - barChart.setVisibleXRangeMinimum(8); - barChart.setScaleYEnabled(false); - barChart.setVisibleXRangeMaximum(34); + return sb.toString(); } } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/ReportActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/ReportActivity.java index 9345d2d..02be4fc 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/ReportActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/ReportActivity.java @@ -77,7 +77,7 @@ protected void initViews() { private void update(String currency) { ReportMaker reportMaker = new ReportMaker(rateController); - IRecordReport report = reportMaker.getReport(currency, period, recordList); + IRecordReport report = reportMaker.getRecordReport(currency, period, recordList); ExpandableListReportAdapter adapter = null; diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/MainActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/MainActivity.java index 98f3844..9177242 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/MainActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/MainActivity.java @@ -194,7 +194,7 @@ protected void update() { String currency = currencyController.readDefaultCurrency(); ReportMaker reportMaker = new ReportMaker(rateController); - IRecordReport report = reportMaker.getReport(currency, period, recordList); + IRecordReport report = reportMaker.getRecordReport(currency, period, recordList); summaryPresenter.update(report, currency, reportMaker.currencyNeeded(currency, recordList)); fillDefaultAccount(); diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java index 3d58913..1e9ef3d 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java @@ -1,5 +1,6 @@ package com.blogspot.e_kanivets.moneytracker.di; +import com.blogspot.e_kanivets.moneytracker.activity.ChartsActivity; import com.blogspot.e_kanivets.moneytracker.activity.ExportActivity; import com.blogspot.e_kanivets.moneytracker.activity.ReportActivity; import com.blogspot.e_kanivets.moneytracker.activity.SettingsActivity; @@ -47,6 +48,8 @@ public interface AppComponent { void inject(ReportActivity reportActivity); + void inject(ChartsActivity chartsActivity); + void inject(SettingsActivity.SettingsFragment settingsFragment); void inject(AccountsSummaryPresenter accountsSummaryPresenter); diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/ReportMaker.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/ReportMaker.java index c22fd5b..261cacf 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/ReportMaker.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/ReportMaker.java @@ -8,8 +8,11 @@ import com.blogspot.e_kanivets.moneytracker.entity.data.ExchangeRate; import com.blogspot.e_kanivets.moneytracker.entity.Period; import com.blogspot.e_kanivets.moneytracker.entity.data.Record; -import com.blogspot.e_kanivets.moneytracker.report.base.IAccountsReport; +import com.blogspot.e_kanivets.moneytracker.report.account.AccountsReport; +import com.blogspot.e_kanivets.moneytracker.report.account.IAccountsReport; import com.blogspot.e_kanivets.moneytracker.report.base.IExchangeRateProvider; +import com.blogspot.e_kanivets.moneytracker.report.chart.IMonthReport; +import com.blogspot.e_kanivets.moneytracker.report.chart.MonthReport; import com.blogspot.e_kanivets.moneytracker.report.record.IRecordReport; import com.blogspot.e_kanivets.moneytracker.report.record.RecordReport; @@ -32,7 +35,7 @@ public ReportMaker(ExchangeRateController exchangeRateController) { } @Nullable - public IRecordReport getReport(String currency, Period period, List recordList) { + public IRecordReport getRecordReport(String currency, Period period, List recordList) { if (currencyNeeded(currency, recordList).size() != 0) return null; IExchangeRateProvider rateProvider = new ExchangeRateProvider(currency, rateController); @@ -47,6 +50,14 @@ public IAccountsReport getAccountsReport(String currency, List accountL return new AccountsReport(currency, accountList, rateProvider); } + @Nullable + public IMonthReport getMonthReport(String currency, List recordList) { + if (currencyNeeded(currency, recordList).size() != 0) return null; + + IExchangeRateProvider rateProvider = new ExchangeRateProvider(currency, rateController); + return new MonthReport(recordList, currency, rateProvider); + } + @NonNull public List currencyNeeded(String currency, List recordList) { Set currencies = new TreeSet<>(); diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/AccountsReport.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/account/AccountsReport.java similarity index 92% rename from app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/AccountsReport.java rename to app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/account/AccountsReport.java index 69a9ff8..50f3635 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/AccountsReport.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/account/AccountsReport.java @@ -1,10 +1,10 @@ -package com.blogspot.e_kanivets.moneytracker.report; +package com.blogspot.e_kanivets.moneytracker.report.account; import android.support.annotation.NonNull; import com.blogspot.e_kanivets.moneytracker.entity.data.Account; import com.blogspot.e_kanivets.moneytracker.entity.data.ExchangeRate; -import com.blogspot.e_kanivets.moneytracker.report.base.IAccountsReport; +import com.blogspot.e_kanivets.moneytracker.report.account.IAccountsReport; import com.blogspot.e_kanivets.moneytracker.report.base.IExchangeRateProvider; import java.util.List; diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/base/IAccountsReport.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/account/IAccountsReport.java similarity index 87% rename from app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/base/IAccountsReport.java rename to app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/account/IAccountsReport.java index 3fbcfa0..e046e61 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/base/IAccountsReport.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/account/IAccountsReport.java @@ -1,4 +1,4 @@ -package com.blogspot.e_kanivets.moneytracker.report.base; +package com.blogspot.e_kanivets.moneytracker.report.account; import android.support.annotation.NonNull; diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/BarChartConverter.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/BarChartConverter.java index 9cc1417..8855acb 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/BarChartConverter.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/BarChartConverter.java @@ -1,5 +1,6 @@ package com.blogspot.e_kanivets.moneytracker.report.chart; +import android.annotation.SuppressLint; import android.content.Context; import android.support.annotation.NonNull; @@ -8,96 +9,68 @@ import com.github.mikephil.charting.data.BarEntry; import com.github.mikephil.charting.interfaces.datasets.IBarDataSet; +import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Date; import java.util.List; /** - * Util class to convert {@link BarChartReport} - * to {@link com.github.mikephil.charting.charts.BarChart} input data. + * Util class to convert {@link IMonthReport} to {@link com.github.mikephil.charting.charts.BarChart} + * input data. * Created on 4/27/16. * * @author Evgenii Kanivets */ public class BarChartConverter { + private final IMonthReport report; + private final int green; private final int red; + private final String incomesTitle; + private final String expensesTitle; + + @SuppressWarnings("deprecation") + public BarChartConverter(@NonNull Context context, @NonNull IMonthReport report) { + this.report = report; - public BarChartConverter(Context context) { green = context.getResources().getColor(R.color.green_light); red = context.getResources().getColor(R.color.red_light); + incomesTitle = context.getString(R.string.incomes); + expensesTitle = context.getString(R.string.expenses); } @NonNull public List getXAxisValueList() { List valueList = new ArrayList<>(); - String[] xVals = {"Jan 16", "Feb 16", "Mar 16", "Apr 16", "May 16", "Jun 16", "Jul 16", - "Aug 16", "Sep 16", "Oct 16", "Nov 16", "Dec 16", "Jan 17", "Feb 17", "Mar 17", - "Apr 17", "May 17", "Jun 17", "Jul 17", "Aug 17", "Sep 17", "Oct 17", "Nov 17", "Dec 17"}; - valueList.addAll(Arrays.asList(xVals)); + + @SuppressLint("SimpleDateFormat") SimpleDateFormat sdf = new SimpleDateFormat("MMM yy"); + for (long timestamp : report.getMonthList()) { + valueList.add(sdf.format(new Date(timestamp))); + } + return valueList; } @NonNull public List getBarDataSetList() { - List list1 = new ArrayList<>(); - list1.add(new BarEntry(100, 0)); - list1.add(new BarEntry(110, 1)); - list1.add(new BarEntry(60, 2)); - list1.add(new BarEntry(90, 3)); - list1.add(new BarEntry(150, 4)); - list1.add(new BarEntry(50, 5)); - list1.add(new BarEntry(100, 6)); - list1.add(new BarEntry(110, 7)); - list1.add(new BarEntry(60, 8)); - list1.add(new BarEntry(90, 9)); - list1.add(new BarEntry(150, 10)); - list1.add(new BarEntry(50, 11)); - list1.add(new BarEntry(100, 12)); - list1.add(new BarEntry(110, 13)); - list1.add(new BarEntry(60, 14)); - list1.add(new BarEntry(90, 15)); - list1.add(new BarEntry(150, 16)); - list1.add(new BarEntry(50, 17)); - list1.add(new BarEntry(100, 18)); - list1.add(new BarEntry(110, 19)); - list1.add(new BarEntry(60, 20)); - list1.add(new BarEntry(90, 21)); - list1.add(new BarEntry(150, 22)); - list1.add(new BarEntry(50, 23)); - BarDataSet dataSet1 = new BarDataSet(list1, "Incomes"); - dataSet1.setColor(green); - - List list2 = new ArrayList<>(); - list2.add(new BarEntry(50, 0)); - list2.add(new BarEntry(10, 1)); - list2.add(new BarEntry(30, 2)); - list2.add(new BarEntry(30, 3)); - list2.add(new BarEntry(50, 4)); - list2.add(new BarEntry(10, 5)); - list2.add(new BarEntry(50, 6)); - list2.add(new BarEntry(10, 7)); - list2.add(new BarEntry(30, 8)); - list2.add(new BarEntry(30, 9)); - list2.add(new BarEntry(50, 10)); - list2.add(new BarEntry(10, 11)); - list2.add(new BarEntry(100, 12)); - list2.add(new BarEntry(110, 13)); - list2.add(new BarEntry(60, 14)); - list2.add(new BarEntry(90, 15)); - list2.add(new BarEntry(150, 16)); - list2.add(new BarEntry(50, 17)); - list2.add(new BarEntry(100, 18)); - list2.add(new BarEntry(110, 19)); - list2.add(new BarEntry(60, 20)); - list2.add(new BarEntry(90, 21)); - list2.add(new BarEntry(150, 22)); - list2.add(new BarEntry(50, 23)); - BarDataSet dataSet2 = new BarDataSet(list2, "Expenses"); + List incomeList = new ArrayList<>(); + for (int i = 0; i < report.getIncomeList().size(); i++) { + incomeList.add(new BarEntry(report.getIncomeList().get(i).floatValue(), i)); + } + + BarDataSet incomeDataSet = new BarDataSet(incomeList, incomesTitle); + incomeDataSet.setColor(green); + + List expenseList = new ArrayList<>(); + for (int i = 0; i < report.getExpenseList().size(); i++) { + expenseList.add(new BarEntry(report.getExpenseList().get(i).floatValue(), i)); + } + + BarDataSet dataSet2 = new BarDataSet(expenseList, expensesTitle); dataSet2.setColor(red); List list = new ArrayList<>(); - list.add(dataSet1); + list.add(incomeDataSet); list.add(dataSet2); return list; diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/IMonthReport.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/IMonthReport.java new file mode 100644 index 0000000..00e449a --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/IMonthReport.java @@ -0,0 +1,37 @@ +package com.blogspot.e_kanivets.moneytracker.report.chart; + +import android.support.annotation.NonNull; + +import java.util.List; + +/** + * Interface that represents a contract of access to record report data grouped by month + * for all records. All three methods must return list of the same size. + * Created on 4/28/16. + * + * @author Evgenii Kanivets + */ +public interface IMonthReport { + /** + * @return code of report currency + */ + @NonNull String getCurrency(); + + /** + * @return list of month timestamps with not zero record count + */ + @NonNull + List getMonthList(); + + /** + * @return list of summary month incomes + */ + @NonNull + List getIncomeList(); + + /** + * @return list of summary month expenses + */ + @NonNull + List getExpenseList(); +} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/MonthReport.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/MonthReport.java new file mode 100644 index 0000000..8f582e1 --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/report/chart/MonthReport.java @@ -0,0 +1,167 @@ +package com.blogspot.e_kanivets.moneytracker.report.chart; + +import android.support.annotation.NonNull; + +import com.blogspot.e_kanivets.moneytracker.entity.data.ExchangeRate; +import com.blogspot.e_kanivets.moneytracker.entity.data.Record; +import com.blogspot.e_kanivets.moneytracker.report.base.IExchangeRateProvider; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.SortedMap; +import java.util.TreeMap; + +/** + * First {@link IMonthReport} implementation. + * Created on 4/28/16. + * + * @author Evgenii Kanivets + */ +public class MonthReport implements IMonthReport { + private final String currency; + private final IExchangeRateProvider rateProvider; + + private final List monthList; + + public MonthReport(List recordList, String currency, IExchangeRateProvider rateProvider) { + if (recordList == null || currency == null || rateProvider == null) + throw new NullPointerException("Params can't be null"); + + this.currency = currency; + this.rateProvider = rateProvider; + + monthList = generateReport(recordList); + } + + @NonNull + @Override + public String getCurrency() { + return currency; + } + + @NonNull + @Override + public List getMonthList() { + List resultList = new ArrayList<>(); + + for (MonthNode node : monthList) { + resultList.add(node.getTimestamp()); + } + + return resultList; + } + + @NonNull + @Override + public List getIncomeList() { + List resultList = new ArrayList<>(); + + for (MonthNode node : monthList) { + resultList.add(node.getTotalIncome()); + } + + return resultList; + } + + @NonNull + @Override + public List getExpenseList() { + List resultList = new ArrayList<>(); + + for (MonthNode node : monthList) { + resultList.add(node.getTotalExpense()); + } + + return resultList; + } + + /** + * @param recordList to generate report on + * @return sorted by timestamp list of {@link MonthNode} + */ + @NonNull + private List generateReport(List recordList) { + SortedMap monthMap = new TreeMap<>(); + + for (Record record : recordList) { + long timestamp = getMonthTimestamp(record.getTime()); + + if (monthMap.get(timestamp) == null) monthMap.put(timestamp, new MonthNode(timestamp)); + MonthNode node = monthMap.get(timestamp); + + double convertedPrice = record.getPrice(); + if (!currency.equals(record.getCurrency())) { + ExchangeRate exchangeRate = rateProvider.getRate(record); + if (exchangeRate == null) throw new NullPointerException("No exchange rate found"); + convertedPrice *= exchangeRate.getAmount(); + } + + switch (record.getType()) { + case Record.TYPE_INCOME: + node.addIncome(convertedPrice); + break; + + case Record.TYPE_EXPENSE: + node.addExpense(convertedPrice); + break; + + default: + break; + } + } + + List resultList = new ArrayList<>(); + for (Long timestamp : monthMap.keySet()) { + resultList.add(monthMap.get(timestamp)); + } + + return resultList; + } + + private long getMonthTimestamp(long timestamp) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date(timestamp)); + + calendar.set(Calendar.DAY_OF_MONTH, 0); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + + return calendar.getTimeInMillis(); + } + + private static class MonthNode { + private long timestamp; + private double totalIncome; + private double totalExpense; + + public MonthNode(long timestamp) { + this.timestamp = timestamp; + totalExpense = 0; + totalIncome = 0; + } + + public void addIncome(double income) { + totalIncome += income; + } + + public void addExpense(double expense) { + totalExpense += expense; + } + + public long getTimestamp() { + return timestamp; + } + + public double getTotalIncome() { + return totalIncome; + } + + public double getTotalExpense() { + return totalExpense; + } + } +} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/ui/presenter/AccountsSummaryPresenter.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/ui/presenter/AccountsSummaryPresenter.java index a0c75b2..31534ff 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/ui/presenter/AccountsSummaryPresenter.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/ui/presenter/AccountsSummaryPresenter.java @@ -14,7 +14,7 @@ import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController; import com.blogspot.e_kanivets.moneytracker.controller.data.ExchangeRateController; import com.blogspot.e_kanivets.moneytracker.report.ReportMaker; -import com.blogspot.e_kanivets.moneytracker.report.base.IAccountsReport; +import com.blogspot.e_kanivets.moneytracker.report.account.IAccountsReport; import com.blogspot.e_kanivets.moneytracker.ui.presenter.base.BaseSummaryPresenter; import java.util.List; diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index bd4d544..35b792c 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -60,5 +60,7 @@ Валюта по умолчанию Графики + Доходы + Расходы diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index dc54b18..85db8a6 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -60,5 +60,7 @@ Валюта за замовчуванням Графіки + Доходи + Витрати \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b4a224a..65223a1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -66,6 +66,8 @@ Default currency Charts + Incomes + Expenses