Skip to content
This repository was archived by the owner on Jun 27, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,5 @@ dependencies {
annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
provided 'org.glassfish:javax.annotation:10.0-b28'
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:cardview-v7:27.1.1'
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ import android.view.View
import com.blogspot.e_kanivets.moneytracker.R
import com.blogspot.e_kanivets.moneytracker.activity.base.BaseFragment
import com.blogspot.e_kanivets.moneytracker.adapter.RecordAdapter
import com.blogspot.e_kanivets.moneytracker.controller.FormatController
import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController
import com.blogspot.e_kanivets.moneytracker.controller.data.RecordController
import com.blogspot.e_kanivets.moneytracker.controller.data.TransferController
import com.blogspot.e_kanivets.moneytracker.entity.HeaderItem
import com.blogspot.e_kanivets.moneytracker.entity.RecordAdapterData
import com.blogspot.e_kanivets.moneytracker.entity.RecordItem
import com.blogspot.e_kanivets.moneytracker.entity.data.Account
import com.blogspot.e_kanivets.moneytracker.entity.data.Category
import com.blogspot.e_kanivets.moneytracker.entity.data.Record
Expand All @@ -23,6 +27,8 @@ class AccountOperationsFragment : BaseFragment() {
internal lateinit var recordController: RecordController
@Inject
internal lateinit var transferController: TransferController
@Inject
internal lateinit var formatController: FormatController

private lateinit var account: Account

Expand All @@ -34,17 +40,30 @@ class AccountOperationsFragment : BaseFragment() {
}

override fun initViews(view: View) {
recyclerView.adapter = RecordAdapter(requireContext(), getRecords(), false, null)
recyclerView.adapter = RecordAdapter(requireContext(), getRecordAdapterDataList(), false, null)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getRecordItems will be more appropriate, I believe :)

}

private fun getRecords(): List<Record> {
private fun getRecordAdapterDataList(): List<RecordAdapterData> {
val accountRecords = recordController.getRecordsForAccount(account)
val accountTransfers = transferController.getTransfersForAccount(account)

accountRecords += obtainRecordsFromTransfers(accountTransfers)
accountRecords.sortByDescending { it.time }

return accountRecords
val recordAdapterData: MutableList<RecordAdapterData> = mutableListOf()

var lastDate = EMPTY_DATE

for (record in accountRecords) {
if (formatController.formatDateToString(record.time) != lastDate) {
lastDate = formatController.formatDateToString(record.time)
recordAdapterData.add(HeaderItem(lastDate))
}

recordAdapterData.add(RecordItem(record))
}

return recordAdapterData
}

private fun obtainRecordsFromTransfers(transfers: List<Transfer>): List<Record> {
Expand Down Expand Up @@ -73,6 +92,7 @@ class AccountOperationsFragment : BaseFragment() {
companion object {

private const val KEY_ACCOUNT = "key_account"
private const val EMPTY_DATE = "empty_date"

This comment was marked as resolved.


fun newInstance(account: Account): AccountOperationsFragment {
val fragment = AccountOperationsFragment()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ private boolean addRecord() {
}

private void updateDateAndTime() {
tvDate.setText(formatController.formatDate(timestamp));
tvDate.setText(formatController.formatDateToNumber(timestamp));
tvTime.setText(formatController.formatTime(timestamp));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ import com.blogspot.e_kanivets.moneytracker.controller.PreferenceController
import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController
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.RecordAdapterData
import com.blogspot.e_kanivets.moneytracker.entity.HeaderItem
import com.blogspot.e_kanivets.moneytracker.entity.Period
import com.blogspot.e_kanivets.moneytracker.entity.RecordItem
import com.blogspot.e_kanivets.moneytracker.entity.data.Record
import com.blogspot.e_kanivets.moneytracker.report.ReportMaker
import com.blogspot.e_kanivets.moneytracker.ui.AppRateDialog
Expand All @@ -26,6 +29,7 @@ import javax.inject.Inject
class MainActivity : BaseDrawerActivity() {

private lateinit var recordList: List<Record>
private val recordAdapterDataList: MutableList<RecordAdapterData> = mutableListOf()
private lateinit var period: Period
private lateinit var recordAdapter: RecordAdapter

Expand Down Expand Up @@ -91,8 +95,7 @@ class MainActivity : BaseDrawerActivity() {
private fun editRecord(position: Int) {
AnswersProxy.get().logButton("Edit Record")

// Minus one because of list view's header view
val record = recordList[position - 1]
val record = recordList[position - 1 - getCountHeadersItems(position - 1)]
startAddRecordActivity(record, AddRecordActivity.Mode.MODE_EDIT, record.type)
}

Expand Down Expand Up @@ -134,17 +137,43 @@ class MainActivity : BaseDrawerActivity() {
override fun update() {
recordList = recordController.getRecordsForPeriod(period)
recordList = recordList.reversed()
updateRecordAdapterDataList()

val currency = currencyController.readDefaultCurrency()

val reportMaker = ReportMaker(rateController)
val report = reportMaker.getRecordReport(currency, period, recordList)

recordAdapter.setRecords(recordList, report, currency, reportMaker.currencyNeeded(currency, recordList))
recordAdapter.setRecords(recordAdapterDataList, report, currency, reportMaker.currencyNeeded(currency, recordList))

fillDefaultAccount()
}

private fun getCountHeadersItems(position: Int): Int {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smart, but I would take one more look on the places where we use getCountHeadersItems. Probably we can get a record without this magic :)

var countHeadersItems = 0
for (inOfData in 0 until position) {
if (recordAdapterDataList[inOfData] is HeaderItem) {
countHeadersItems++
}
}
return countHeadersItems
}

private fun updateRecordAdapterDataList() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated code.

recordAdapterDataList.clear()

var lastDate = EMPTY_DATE
for (record in recordList) {
if (formatController.formatDateToString(record.time) != lastDate) {
lastDate = formatController.formatDateToString(record.time)
recordAdapterDataList.add(HeaderItem(lastDate))
}

recordAdapterDataList.add(RecordItem(record))
}
}


private fun showAppRateDialog() {
AnswersProxy.get().logEvent("Show App Rate Dialog")
val dialog = AppRateDialog(this)
Expand All @@ -170,6 +199,7 @@ class MainActivity : BaseDrawerActivity() {

companion object {
private const val REQUEST_ACTION_RECORD = 6
private const val EMPTY_DATE = "empty_date"

This comment was marked as resolved.

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ import android.widget.TextView
import com.blogspot.e_kanivets.moneytracker.MtApp
import com.blogspot.e_kanivets.moneytracker.R
import com.blogspot.e_kanivets.moneytracker.controller.FormatController
import com.blogspot.e_kanivets.moneytracker.entity.data.Record
import com.blogspot.e_kanivets.moneytracker.entity.RecordAdapterData
import com.blogspot.e_kanivets.moneytracker.entity.HeaderItem
import com.blogspot.e_kanivets.moneytracker.entity.RecordItem
import com.blogspot.e_kanivets.moneytracker.report.record.IRecordReport
import com.blogspot.e_kanivets.moneytracker.ui.presenter.ShortSummaryPresenter
import kotlinx.android.synthetic.main.view_header_date.view.*
import kotlinx.android.synthetic.main.view_record.view.*
import kotlinx.android.synthetic.main.view_record.view.container
import kotlinx.android.synthetic.main.view_summary_records.view.*
import javax.inject.Inject

Expand All @@ -30,16 +34,16 @@ class RecordAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder> {
private var red: Int
private var green: Int

private var records: List<Record>
private var items: List<RecordAdapterData>
private var context: Context

private var summaryPresenter: ShortSummaryPresenter
private var isHeaderViewNeeded: Boolean = false
private var headerViewHolder: HeaderViewHolder
private var isSummaryViewNeeded: Boolean = false

This comment was marked as resolved.

private var summaryViewHolder: SummaryViewHolder

constructor(context: Context, records: List<Record>, isHeaderViewNeeded: Boolean, itemClickListener: ((Int) -> Unit)?) {
constructor(context: Context, items: List<RecordAdapterData>, isSummaryViewNeeded: Boolean, itemClickListener: ((Int) -> Unit)?) {
this.context = context
this.records = records
this.items = items

MtApp.get().appComponent.inject(this)

Expand All @@ -51,68 +55,71 @@ class RecordAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder> {
summaryPresenter = ShortSummaryPresenter(context)

this.itemClickListener = itemClickListener
this.isHeaderViewNeeded = isHeaderViewNeeded
this.isSummaryViewNeeded = isSummaryViewNeeded

headerViewHolder = HeaderViewHolder(LayoutInflater.from(context).inflate(R.layout.view_summary_records, null), itemClickListener)
summaryPresenter.create(true, headerViewHolder)
summaryViewHolder = SummaryViewHolder(LayoutInflater.from(context).inflate(R.layout.view_summary_records, null), itemClickListener)
summaryPresenter.create(true, summaryViewHolder)
}

override fun getItemCount() = records.size + if (isHeaderViewNeeded) 1 else 0
override fun getItemCount() = items.size + if (isSummaryViewNeeded) 1 else 0

override fun getItemViewType(position: Int): Int = if (position == 0 && isHeaderViewNeeded) {
override fun getItemViewType(position: Int): Int = if (position == 0 && isSummaryViewNeeded) {
TYPE_SUMMARY
} else if (items[position - if (isSummaryViewNeeded) 1 else 0] is HeaderItem) {
TYPE_HEADER
} else {
TYPE_ITEM
TYPE_RECORD
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder =
if (viewType == TYPE_HEADER) {
headerViewHolder
} else {
ViewHolder(LayoutInflater.from(context).inflate(R.layout.view_record, parent, false), itemClickListener)
when (viewType) {
TYPE_RECORD -> RecordViewHolder(LayoutInflater.from(context).inflate(R.layout.view_record, parent, false), itemClickListener)

This comment was marked as resolved.

TYPE_HEADER -> HeaderViewHolder(LayoutInflater.from(context).inflate(R.layout.view_header_date, parent, false))
else -> summaryViewHolder
}

override fun onBindViewHolder(rvViewHolder: RecyclerView.ViewHolder, position: Int) {
if (position == 0 && isHeaderViewNeeded) {
if (position == 0 && isSummaryViewNeeded) {
//adapter already bound to view
return
}

val viewHolder = rvViewHolder as ViewHolder
val record: Record = records[position - if (isHeaderViewNeeded) 1 else 0]
viewHolder.container.setBackgroundColor(if (record.isIncome) whiteGreen else whiteRed)
viewHolder.tvPrice.setTextColor(if (record.isIncome) green else red)

viewHolder.tvDateAndTime.text = formatController.formatDateAndTime(record.time)
val price = (if (record.isIncome) record.fullPrice else getNegative(record.fullPrice))
viewHolder.tvPrice.text = formatController.formatSignedAmount(price)
viewHolder.tvTitle.text = record.title
viewHolder.tvCategory.text = record.category?.name
viewHolder.tvCurrency.text = record.currency
if (rvViewHolder is RecordViewHolder) {

This comment was marked as resolved.

val record = items[position - if (isSummaryViewNeeded) 1 else 0] as RecordItem
rvViewHolder.tvPrice.setTextColor(if (record.isIncome) green else red)

val price = (if (record.isIncome) record.fullPrice else getNegative(record.fullPrice))
rvViewHolder.tvPrice.text = formatController.formatSignedAmount(price)
rvViewHolder.tvTitle.text = record.title
rvViewHolder.tvCategory.text = record.categoryName
rvViewHolder.tvCurrency.text = record.currency
} else {
val headerViewHolder = rvViewHolder as HeaderViewHolder
val header = items[position - if (isSummaryViewNeeded) 1 else 0] as HeaderItem
headerViewHolder.tvDate.text = header.date
}
}

private fun getNegative(number: Double): Double {
return -1 * number
}

fun setRecords(recordsList: List<Record>, report: IRecordReport?, currency: String, ratesNeeded: List<String>) {
records = recordsList
fun setRecords(itemsList: List<RecordAdapterData>, report: IRecordReport?, currency: String, ratesNeeded: List<String>) {
items = itemsList
summaryPresenter.update(report, currency, ratesNeeded)
notifyDataSetChanged()
}

class ViewHolder : RecyclerView.ViewHolder {
class RecordViewHolder : RecyclerView.ViewHolder {

var container: LinearLayout
var tvDateAndTime: TextView
var tvPrice: TextView
var tvTitle: TextView
var tvCategory: TextView
var tvCurrency: TextView

constructor(view: View, itemClickListener: ((Int) -> Unit)?) : super(view) {
container = view.container
tvDateAndTime = view.tvDateAndTime
tvPrice = view.tvPrice
tvTitle = view.tvTitle
tvCategory = view.tvCategory
Expand All @@ -124,7 +131,11 @@ class RecordAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder> {
}
}

class HeaderViewHolder : RecyclerView.ViewHolder, ShortSummaryPresenter.SummaryViewInterface {
class HeaderViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val tvDate: TextView = view.tvDate
}

class SummaryViewHolder : RecyclerView.ViewHolder, ShortSummaryPresenter.SummaryViewInterface {

private var tvPeriod: TextView
private var tvTotalIncome: TextView
Expand All @@ -145,15 +156,15 @@ class RecordAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder> {
tvTotalExpense = view.tvTotalExpense
tvTotal = view.tvTotal

view.setOnClickListener {
view.cvSummary.setOnClickListener {
itemClickListener?.invoke(0)
}
}
}

companion object {

private const val TYPE_HEADER = 0
private const val TYPE_ITEM = 1
private const val TYPE_SUMMARY = 0
private const val TYPE_HEADER = 1
private const val TYPE_RECORD = 2
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ public class FormatController {
public static final String PRECISION_NONE = "precision_none";

@SuppressLint("SimpleDateFormat")
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
private static final SimpleDateFormat dateInNumberFormat = new SimpleDateFormat("yyyy-MM-dd");

This comment was marked as resolved.

@SuppressLint("SimpleDateFormat")
private static final SimpleDateFormat dateInStringFormat = new SimpleDateFormat("d MMMM yyyy");
@SuppressLint("SimpleDateFormat")
private static final SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
@SuppressLint("SimpleDateFormat")
Expand Down Expand Up @@ -72,8 +74,12 @@ public String formatExpense(double amount, String currency) {
return (amount > 0 ? "+ " : "- ") + formatAmount(Math.abs(amount)) + " " + currency;
}

public String formatDate(long timestamp) {
return dateFormat.format(new Date(timestamp));
public String formatDateToNumber(long timestamp) {

This comment was marked as resolved.

return dateInNumberFormat.format(new Date(timestamp));
}

public String formatDateToString(long timestamp) {
return dateInStringFormat.format(new Date(timestamp));
}

public String formatTime(long timestamp) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,15 @@ public Period yearPeriod() {
public Period allTimePeriod() {
Calendar cal = Calendar.getInstance();

// set start of time by Jesus
// set start of date by Jesus

This comment was marked as resolved.

cal.set(Calendar.YEAR, 2000);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH, 1);
setDayStart(cal);

Date first = cal.getTime();

// set possible end of time
// set possible end of date
cal.set(Calendar.YEAR, 3000);
cal.set(Calendar.MONTH, Calendar.DECEMBER);
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ record = validateRecord(record);
@NonNull @Override public List<Record> readWithCondition(String condition, String[] args) {
List<Record> recordList = super.readWithCondition(condition, args);

// Sort record list by time field from smallest to biggest
// Sort record list by date field from smallest to biggest
Collections.sort(recordList, new Comparator<Record>() {
@Override public int compare(Record lhs, Record rhs) {
return lhs.getTime() < rhs.getTime() ? -1 : (lhs.getTime() == rhs.getTime() ? 0 : 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @author Evgenii Kanivets
*/
public interface Head {
String TIME = "time";
String TIME = "date";

This comment was marked as resolved.

String TITLE = "title";
String CATEGORY = "category";
String PRICE = "price";
Expand Down
Loading