Improve deletion system and add deletion for bankroll

dev
Aurelien Hubert 7 years ago
parent 91c9973ee0
commit 0bc502e468
  1. 32
      app/src/main/java/net/pokeranalytics/android/model/interfaces/Manageable.kt
  2. 118
      app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt
  3. 9
      app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt
  4. 9
      app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt
  5. 6
      app/src/main/java/net/pokeranalytics/android/ui/activity/BankrollActivity.kt
  6. 7
      app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollEditDataFragment.kt
  7. 15
      app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt
  8. 3
      app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt

@ -12,12 +12,19 @@ enum class SaveValidityStatus {
DATA_INVALID; DATA_INVALID;
} }
enum class DeleteValidityStatus {
VALID,
INVALID,
SESSIONS_LINKED,
TRANSACTIONS_LINKED;
}
/** /**
* An interface to grouped object which are managed by the database * An interface to grouped object which are managed by the database
*/ */
interface Manageable : Savable, Deletable, Editable interface Manageable : Savable, Deletable, Editable
interface NameManageable: Manageable { interface NameManageable : Manageable {
var name: String var name: String
override fun isValidForSave(): Boolean { override fun isValidForSave(): Boolean {
@ -25,16 +32,16 @@ interface NameManageable: Manageable {
} }
override fun alreadyExists(realm: Realm): Boolean { override fun alreadyExists(realm: Realm): Boolean {
return realm.where(this::class.java).equalTo("name", this.name).and().notEqualTo("id", this.id).findAll().isNotEmpty() return realm.where(this::class.java).equalTo("name", this.name).and().notEqualTo("id", this.id).findAll().isNotEmpty()
} }
override fun getFailedSaveMessage(status: SaveValidityStatus): Int { override fun getFailedSaveMessage(status: SaveValidityStatus): Int {
throw ModelException("${this::class.java} getFailedSaveMessage for $status not handled") throw ModelException("${this::class.java} getFailedSaveMessage for $status not handled")
} }
override fun getFailedDeleteMessage(): Int { override fun getFailedDeleteMessage(status: DeleteValidityStatus): Int {
return R.string.relationship_error return R.string.relationship_error
} }
} }
@ -87,7 +94,7 @@ interface Savable : Identifiable {
/** /**
* A method to get the reason why the object can't be saved * A method to get the reason why the object can't be saved
*/ */
fun getFailedSaveMessage(status:SaveValidityStatus): Int fun getFailedSaveMessage(status: SaveValidityStatus): Int
} }
@ -101,8 +108,17 @@ interface Deletable : Identifiable {
*/ */
fun isValidForDelete(realm: Realm): Boolean fun isValidForDelete(realm: Realm): Boolean
fun getDeleteStatus(realm: Realm): DeleteValidityStatus {
if (!isValidForDelete(realm)) {
return DeleteValidityStatus.INVALID
}
return DeleteValidityStatus.VALID
}
/** /**
* A method to get the reason why the object can't be deleted * A method to get the reason why the object can't be deleted
*/ */
fun getFailedDeleteMessage(): Int fun getFailedDeleteMessage(status: DeleteValidityStatus): Int
} }

@ -7,6 +7,7 @@ import io.realm.annotations.LinkingObjects
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
import io.realm.kotlin.where import io.realm.kotlin.where
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus
import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.model.interfaces.SaveValidityStatus import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
@ -16,69 +17,82 @@ import java.util.*
open class Bankroll : RealmObject(), NameManageable, RowRepresentable { open class Bankroll : RealmObject(), NameManageable, RowRepresentable {
@PrimaryKey @PrimaryKey
override var id = UUID.randomUUID().toString() override var id = UUID.randomUUID().toString()
override var name: String = "" override var name: String = ""
// Indicates whether the bankroll is live or online // Indicates whether the bankroll is live or online
var live: Boolean = true var live: Boolean = true
/** /**
* The list of transactions of the bankroll * The list of transactions of the bankroll
*/ */
@LinkingObjects("bankroll") @LinkingObjects("bankroll")
val transactions: RealmResults<Transaction>? = null val transactions: RealmResults<Transaction>? = null
// The currency of the bankroll // The currency of the bankroll
var currency: Currency? = null var currency: Currency? = null
// The initial value of the bankroll // The initial value of the bankroll
var initialValue: Double = 0.0 var initialValue: Double = 0.0
val rate: Double val rate: Double
get() { get() {
return this.currency?.rate ?: 1.0 return this.currency?.rate ?: 1.0
} }
override fun getDisplayName(): String { override fun getDisplayName(): String {
return this.name return this.name
} }
override fun updateValue(value: Any?, row: RowRepresentable) { override fun updateValue(value: Any?, row: RowRepresentable) {
when (row) { when (row) {
SimpleRow.NAME -> this.name = value as String? ?: "" SimpleRow.NAME -> this.name = value as String? ?: ""
BankrollRow.LIVE -> { BankrollRow.LIVE -> {
this.live = if (value is Boolean) !value else false this.live = if (value is Boolean) !value else false
} }
BankrollRow.INITIAL_VALUE -> { BankrollRow.INITIAL_VALUE -> {
this.initialValue = value as Double? ?: 0.0 this.initialValue = value as Double? ?: 0.0
} }
BankrollRow.CURRENCY -> { BankrollRow.CURRENCY -> {
//TODO handle a use default currency option //TODO handle a use default currency option
this.currency?.code = value as String? this.currency?.code = value as String?
} }
BankrollRow.RATE -> { BankrollRow.RATE -> {
this.currency?.rate = value as Double? this.currency?.rate = value as Double?
} }
} }
} }
override fun isValidForDelete(realm: Realm): Boolean { override fun isValidForDelete(realm: Realm): Boolean {
return realm.where<Session>().equalTo("bankroll.id", id).findAll().isEmpty() return realm.where<Session>().equalTo("bankroll.id", id).findAll().isEmpty()
//TODO: Check transactions && realm.where<Transaction>().equalTo("bankroll.id", id).findAll().isEmpty()
//&& realm.where<Transaction>().equalTo("bankroll.id", id).findAll().isEmpty() }
override fun getDeleteStatus(realm: Realm): DeleteValidityStatus {
return if (!realm.where<Session>().equalTo("bankroll.id", id).findAll().isEmpty()) {
DeleteValidityStatus.SESSIONS_LINKED
} else if (!realm.where<Transaction>().equalTo("bankroll.id", id).findAll().isEmpty()) {
DeleteValidityStatus.TRANSACTIONS_LINKED
} else {
DeleteValidityStatus.VALID
}
} }
override fun getFailedDeleteMessage(): Int { override fun getFailedDeleteMessage(status: DeleteValidityStatus): Int {
return R.string.bankroll_relationship_error return when (status) {
} DeleteValidityStatus.SESSIONS_LINKED -> R.string.bankroll_relationship_error
DeleteValidityStatus.TRANSACTIONS_LINKED -> R.string.bankroll_relationship_error_transactions
else -> super.getFailedDeleteMessage(status)
}
}
override fun getFailedSaveMessage(status: SaveValidityStatus): Int { override fun getFailedSaveMessage(status: SaveValidityStatus): Int {
return when (status) { return when (status) {
SaveValidityStatus.DATA_INVALID -> R.string.empty_name_for_br_error SaveValidityStatus.DATA_INVALID -> R.string.empty_name_for_br_error
SaveValidityStatus.ALREADY_EXISTS -> R.string.duplicate_bankroll_name_error SaveValidityStatus.ALREADY_EXISTS -> R.string.duplicate_bankroll_name_error
else -> super.getFailedSaveMessage(status) else -> super.getFailedSaveMessage(status)
} }
} }
} }

@ -10,10 +10,7 @@ import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.calculus.TextFormat import net.pokeranalytics.android.calculus.TextFormat
import net.pokeranalytics.android.model.filter.Filterable import net.pokeranalytics.android.model.filter.Filterable
import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.interfaces.DatedValue import net.pokeranalytics.android.model.interfaces.*
import net.pokeranalytics.android.model.interfaces.Manageable
import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.model.interfaces.TimeFilterable
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.graph.GraphUnderlyingEntry import net.pokeranalytics.android.ui.graph.GraphUnderlyingEntry
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
@ -115,8 +112,8 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo
return true return true
} }
override fun getFailedDeleteMessage(): Int { override fun getFailedDeleteMessage(status: DeleteValidityStatus): Int {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates. return R.string.relationship_error
} }
override fun getSaveValidityStatus(realm: Realm): SaveValidityStatus { override fun getSaveValidityStatus(realm: Realm): SaveValidityStatus {

@ -3,6 +3,8 @@ package net.pokeranalytics.android.model.realm
import io.realm.Realm import io.realm.Realm
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus
import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
@ -88,11 +90,12 @@ open class TransactionType : RealmObject(), NameManageable, StaticRowRepresentab
} }
override fun isValidForDelete(realm: Realm): Boolean { override fun isValidForDelete(realm: Realm): Boolean {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates. return true
} }
override fun getFailedDeleteMessage(): Int { override fun getFailedDeleteMessage(status: DeleteValidityStatus): Int {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates. return R.string.relationship_error
} }
} }

@ -69,8 +69,10 @@ class BankrollActivity : PokerAnalyticsActivity() {
indexes.addAll(changeSet.insertions.toList()) indexes.addAll(changeSet.insertions.toList())
indexes.addAll(changeSet.deletions.toList()) indexes.addAll(changeSet.deletions.toList())
indexes.forEach { index -> indexes.forEach { index ->
t[index]?.bankroll?.let { br -> if (t.isNotEmpty()) {
bankrolls.add(br) t[index]?.bankroll?.let { br ->
bankrolls.add(br)
}
} }
} }
this.computeBankrollReports(bankrolls) this.computeBankrollReports(bankrolls)

@ -3,8 +3,6 @@ package net.pokeranalytics.android.ui.fragment
import android.app.Activity.RESULT_OK import android.app.Activity.RESULT_OK
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.View import android.view.View
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.api.CurrencyConverterApi import net.pokeranalytics.android.api.CurrencyConverterApi
@ -56,11 +54,6 @@ class BankrollEditDataFragment : EditableDataFragment(), StaticRowRepresentableD
} ?: false } ?: false
} }
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
super.onCreateOptionsMenu(menu, inflater)
menu?.findItem(R.id.delete)?.isVisible = false
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)

@ -9,6 +9,7 @@ import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.github.mikephil.charting.data.LineDataSet import com.github.mikephil.charting.data.LineDataSet
import io.realm.Realm
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.RealmResults import io.realm.RealmResults
import kotlinx.android.synthetic.main.fragment_bankroll.* import kotlinx.android.synthetic.main.fragment_bankroll.*
@ -34,7 +35,6 @@ import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
@ -43,7 +43,7 @@ import timber.log.Timber
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
class BankrollFragment : RealmFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate { class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate {
companion object { companion object {
@ -153,6 +153,9 @@ class BankrollFragment : RealmFragment(), StaticRowRepresentableDataSource, RowR
val bankrolls = LiveData.BANKROLL.items(getRealm()) as RealmResults<Bankroll> val bankrolls = LiveData.BANKROLL.items(getRealm()) as RealmResults<Bankroll>
bankrolls.forEach { bankrolls.forEach {
Timber.d("Bankroll: ${it.name} => isValidForDelete: ${it.isValidForDelete(Realm.getDefaultInstance())}")
val bankrollReportSetup = BankrollReportSetup(it) val bankrollReportSetup = BankrollReportSetup(it)
val bankrollReport = BankrollCalculator.computeReport(getRealm(), bankrollReportSetup) val bankrollReport = BankrollCalculator.computeReport(getRealm(), bankrollReportSetup)
val computedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.total) val computedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.total)
@ -217,8 +220,10 @@ class BankrollFragment : RealmFragment(), StaticRowRepresentableDataSource, RowR
if (mRecentlyDeletedItem is Bankroll) { if (mRecentlyDeletedItem is Bankroll) {
val deletableItem = (mRecentlyDeletedItem as Deletable)
// Check if the object is valid for the deletion // Check if the object is valid for the deletion
if ((mRecentlyDeletedItem as Deletable).isValidForDelete(this.getRealm())) { if (deletableItem.isValidForDelete(this.getRealm())) {
deletedItem = getRealm().copyFromRealm(mRecentlyDeletedItem) deletedItem = getRealm().copyFromRealm(mRecentlyDeletedItem)
getRealm().executeTransaction { getRealm().executeTransaction {
mRecentlyDeletedItem.deleteFromRealm() mRecentlyDeletedItem.deleteFromRealm()
@ -231,8 +236,10 @@ class BankrollFragment : RealmFragment(), StaticRowRepresentableDataSource, RowR
} else { } else {
bankrollAdapter.notifyItemChanged(position) bankrollAdapter.notifyItemChanged(position)
val status = deletableItem.getDeleteStatus(this.getRealm())
val errorMessage = deletableItem.getFailedDeleteMessage(status)
val builder = AlertDialog.Builder(requireContext()) val builder = AlertDialog.Builder(requireContext())
.setMessage((mRecentlyDeletedItem as Deletable).getFailedDeleteMessage()) .setMessage(errorMessage)
.setNegativeButton(R.string.ok, null) .setNegativeButton(R.string.ok, null)
builder.show() builder.show()
} }

@ -192,7 +192,8 @@ open class EditableDataFragment : RealmFragment(), RowRepresentableDelegate {
activity?.setResult(RESULT_OK, intent) activity?.setResult(RESULT_OK, intent)
activity?.finish() activity?.finish()
} else { } else {
val message = deletable.getFailedDeleteMessage() val status = deletable.getDeleteStatus(realm)
val message = deletable.getFailedDeleteMessage(status)
val builder = AlertDialog.Builder(requireContext()) val builder = AlertDialog.Builder(requireContext())
.setMessage(message) .setMessage(message)
.setNegativeButton(R.string.ok, null) .setNegativeButton(R.string.ok, null)

Loading…
Cancel
Save