Merge remote-tracking branch 'origin/dev' into dev

feature/top10
Razmig Sarkissian 7 years ago
commit e696716b73
  1. 2
      app/src/androidTest/java/net/pokeranalytics/android/components/RealmInstrumentedUnitTest.kt
  2. 101
      app/src/androidTest/java/net/pokeranalytics/android/unitTests/BankrollInstrumentedUnitTest.kt
  3. 2
      app/src/androidTest/java/net/pokeranalytics/android/unitTests/DeleteInstrumentedUnitTest.kt
  4. 2
      app/src/androidTest/java/net/pokeranalytics/android/unitTests/StatsInstrumentedUnitTest.kt
  5. 2
      app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt
  6. 10
      app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt
  7. 2
      app/src/main/java/net/pokeranalytics/android/calculus/Report.kt
  8. 14
      app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt
  9. 74
      app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollCalculator.kt
  10. 209
      app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt
  11. 11
      app/src/main/java/net/pokeranalytics/android/calculus/interfaces/Datable.kt
  12. 2
      app/src/main/java/net/pokeranalytics/android/model/filter/Filterable.kt
  13. 15
      app/src/main/java/net/pokeranalytics/android/model/interfaces/Dated.kt
  14. 4
      app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt
  15. 57
      app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt
  16. 14
      app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt
  17. 27
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  18. 7
      app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt
  19. 24
      app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt
  20. 18
      app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt
  21. 9
      app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt
  22. 6
      app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt
  23. 11
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/BankrollRow.kt
  24. 1
      app/src/main/res/values/strings.xml

@ -11,6 +11,8 @@ import java.util.*
open class RealmInstrumentedUnitTest {
val EPSILON = 0.0001
lateinit var mockRealm: Realm
companion object {

@ -1,11 +1,10 @@
package net.pokeranalytics.android.unitTests
import androidx.test.ext.junit.runners.AndroidJUnit4
import net.pokeranalytics.android.components.RealmInstrumentedUnitTest
import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.ComputableGroup
import net.pokeranalytics.android.calculus.ComputedResults
import net.pokeranalytics.android.calculus.Stat
import io.realm.Realm
import net.pokeranalytics.android.calculus.bankroll.BankrollCalculator
import net.pokeranalytics.android.calculus.bankroll.BankrollReportSetup
import net.pokeranalytics.android.components.SessionInstrumentedUnitTest
import net.pokeranalytics.android.model.realm.*
import net.pokeranalytics.android.model.realm.Currency
import org.junit.Assert
@ -14,7 +13,17 @@ import org.junit.runner.RunWith
import java.util.*
@RunWith(AndroidJUnit4::class)
class BankrollInstrumentedUnitTest : RealmInstrumentedUnitTest() {
class BankrollInstrumentedUnitTest : SessionInstrumentedUnitTest() {
private fun createDefaultTransactionTypes(realm: Realm) {
TransactionType.Value.values().forEachIndexed { index, value ->
val type = TransactionType()
type.additive = value.additive
type.kind = index
type.lock = true
realm.insertOrUpdate(type)
}
}
// convenience extension
fun Session.Companion.testInstance(netResult: Double, startDate: Date, endDate: Date?): Session {
@ -26,10 +35,88 @@ class BankrollInstrumentedUnitTest : RealmInstrumentedUnitTest() {
}
@Test
fun testSessionStats() {
fun testReport() {
val realm = mockRealm
realm.executeTransaction {
this.createDefaultTransactionTypes(realm)
var br1 = realm.createObject(Bankroll::class.java, "1")
var br2 = realm.createObject(Bankroll::class.java, "2")
br1.initialValue = 100.0
br2.initialValue = 1000.0
val t1 = realm.createObject(Transaction::class.java, UUID.randomUUID().toString())
t1.amount = 100.0
t1.bankroll = br1
t1.type = TransactionType.getByValue(TransactionType.Value.BONUS, realm)
val t2 = realm.createObject(Transaction::class.java, UUID.randomUUID().toString())
t2.amount = 500.0
t2.bankroll = br2
t2.type = TransactionType.getByValue(TransactionType.Value.BONUS, realm)
val s1 = newSessionInstance(realm)
s1.bankroll = br1
s1.result?.cashout = 200.0
val s2 = newSessionInstance(realm)
s2.bankroll = br2
s2.result?.cashout = 500.0
val brSetup1 = BankrollReportSetup(br1)
val report1 = BankrollCalculator.computeReport(brSetup1)
Assert.assertEquals(400.0, report1.total, EPSILON)
val brSetup2 = BankrollReportSetup(br2)
val report2 = BankrollCalculator.computeReport(brSetup2)
Assert.assertEquals(2000.0, report2.total, EPSILON)
val brSetupAll = BankrollReportSetup()
val reportAll = BankrollCalculator.computeReport(brSetupAll)
Assert.assertEquals(2400.0, reportAll.total, EPSILON)
}
}
@Test
fun testReportWithRate() {
val realm = mockRealm
var br1: Bankroll? = null
realm.executeTransaction {
this.createDefaultTransactionTypes(realm)
val c1 = realm.createObject(Currency::class.java, UUID.randomUUID().toString())
c1.rate = 10.0
br1 = realm.createObject(Bankroll::class.java, "1")
br1?.currency = c1
br1?.initialValue = 100.0
val t1 = realm.createObject(Transaction::class.java, UUID.randomUUID().toString())
t1.amount = 100.0
t1.type = TransactionType.getByValue(TransactionType.Value.BONUS, realm)
br1?.transactions?.add(t1)
val s1 = newSessionInstance(realm)
s1.bankroll = br1
s1.result?.cashout = 200.0
}
val brSetup1 = BankrollReportSetup(br1)
val report1 = BankrollCalculator.computeReport(brSetup1)
Assert.assertEquals(400.0, report1.total, EPSILON)
val brSetupAll = BankrollReportSetup()
val reportAll = BankrollCalculator.computeReport(brSetupAll)
Assert.assertEquals(4000.0, reportAll.total, EPSILON)
}
}

@ -18,7 +18,9 @@ class DeleteInstrumentedUnitTest : RealmInstrumentedUnitTest() {
val s2 = newSessionInstance(realm)
val br1 = realm.createObject(Bankroll::class.java, "1")
br1.live = false
val br2 = realm.createObject(Bankroll::class.java, "2")
br2.live = false
val c1 = realm.createObject(Currency::class.java, "1")
val c2 = realm.createObject(Currency::class.java, "2")

@ -571,7 +571,7 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() {
}
@Test
// @Test
fun testRatedNetResultSessions() {
val realm = this.mockRealm

@ -52,7 +52,7 @@ class PokerAnalyticsApplication : Application() {
if (BuildConfig.DEBUG) {
Timber.d("UserPreferences.defaultCurrency: ${UserDefaults.currency.symbol}")
this.createFakeSessions()
// this.createFakeSessions()
}
Patcher.patchBreaks()

@ -134,7 +134,7 @@ class Calculator {
realm: Realm,
criteria: List<Criteria> = listOf(),
conditions: List<QueryCondition> = listOf(),
options: Options
options: Options = Options()
): Report {
val computableGroups: MutableList<ComputableGroup> = mutableListOf()
@ -161,7 +161,7 @@ class Calculator {
/**
* Computes all stats for list of Session sessionGroup
*/
fun computeGroups(realm: Realm, groups: List<ComputableGroup>, options: Options): Report {
fun computeGroups(realm: Realm, groups: List<ComputableGroup>, options: Options = Options()): Report {
val report = Report(options)
groups.forEach { group ->
@ -171,12 +171,12 @@ class Calculator {
group.cleanup()
// Computes actual sessionGroup stats
val results: ComputedResults = this.compute(realm, group, options = options)
val results: ComputedResults = this.compute(realm, group, options)
// Computes the compared sessionGroup if existing
val comparedGroup = group.comparedGroup
if (comparedGroup != null) {
val comparedResults = this.compute(realm, comparedGroup, options = options)
val comparedResults = this.compute(realm, comparedGroup, options)
group.comparedComputedResults = comparedResults
results.computeStatVariations(comparedResults)
}
@ -200,7 +200,7 @@ class Calculator {
/**
* Computes stats for a SessionSet
*/
fun compute(realm: Realm, computableGroup: ComputableGroup, options: Options): ComputedResults {
fun compute(realm: Realm, computableGroup: ComputableGroup, options: Options = Options()): ComputedResults {
val results = ComputedResults(computableGroup, options.shouldManageMultiGroupProgressValues)

@ -92,7 +92,7 @@ class Report(var options: Calculator.Options) {
/**
* A sessionGroup of computable items identified by a name
*/
class ComputableGroup(name: String, conditions: List<QueryCondition> = listOf(), stats: List<Stat>? = null) {
class ComputableGroup(name: String = "", conditions: List<QueryCondition> = listOf(), stats: List<Stat>? = null) {
/**
* The display name of the group

@ -14,6 +14,7 @@ import net.pokeranalytics.android.util.extensions.formatted
import net.pokeranalytics.android.util.extensions.formattedHourlyDuration
import net.pokeranalytics.android.util.extensions.toCurrency
import java.util.*
import kotlin.math.exp
class StatFormattingException(message: String) : Exception(message) {
@ -128,6 +129,19 @@ enum class Stat : RowRepresentable {
return netBB / numberOfHands * 100
}
fun riskOfRuin(hourlyRate: Double, hourlyStandardDeviation: Double, bankrollValue: Double) : Double? {
if (bankrollValue <= 0.0) {
return null
}
val numerator = -2 * hourlyRate * bankrollValue
val denominator = Math.pow(hourlyStandardDeviation, 2.0)
val ratio = numerator / denominator
return exp(ratio)
}
}
override val resId: Int?

@ -1,9 +1,11 @@
package net.pokeranalytics.android.calculus.bankroll
import io.realm.Realm
import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.Transaction
import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.ComputableGroup
import net.pokeranalytics.android.calculus.ComputedResults
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.model.realm.*
class BankrollCalculator {
@ -14,22 +16,80 @@ class BankrollCalculator {
val realm = Realm.getDefaultInstance()
val report = BankrollReport(setup)
val bankrolls: List<Bankroll> = if (setup.bankroll != null) listOf(setup.bankroll) else realm.where(Bankroll::class.java).findAll()
val sessions = Filter.queryOn<Session>(realm, setup.queryConditions)
val transactions = Filter.queryOn<Transaction>(realm, setup.queryConditions)
var initialValue = 0.0
var transactionNet = 0.0
val sessionsNet = sessions.sum("result.net")
val transactionsNet = transactions.sum("value")
bankrolls.forEach { bankroll ->
val rate = if (setup.virtualBankroll) bankroll.rate else 1.0
initialValue += bankroll.initialValue * rate
transactionNet += bankroll.transactions.sumByDouble { it.amount } * rate
}
report.transactionsNet = transactionNet
report.initial = initialValue
val queryConditions = setup.queryConditions
val transactions = Filter.queryOn<Transaction>(realm, queryConditions)
report.addDatedItems(transactions)
transactions.forEach {
report.addTransaction(it)
}
val sessions = Filter.queryOn<Session>(realm, queryConditions)
report.addDatedItems(sessions)
if (setup.virtualBankroll) {
val options = Calculator.Options(stats = listOf(Stat.NET_RESULT, Stat.HOURLY_RATE, Stat.STANDARD_DEVIATION_HOURLY))
val group = ComputableGroup(conditions = queryConditions)
val result = Calculator.compute(realm, group, options)
result.computedStat(Stat.NET_RESULT)?.let {
report.netResult = it.value
}
this.computeRiskOfRuin(report, result)
} else {
val results = Filter.queryOn<Result>(realm, queryConditions)
report.netResult = results.sum("net").toDouble()
}
val depositType = TransactionType.getByValue(TransactionType.Value.DEPOSIT, realm)
report.transactionBuckets[depositType.id]?.let { bucket ->
report.depositTotal = bucket.transactions.sumByDouble { it.amount }
}
val withdrawalType = TransactionType.getByValue(TransactionType.Value.WITHDRAWAL, realm)
report.transactionBuckets[withdrawalType.id]?.let { bucket ->
report.withdrawalTotal = bucket.transactions.sumByDouble { it.amount }
}
report.generateGraphPointsIfNecessary()
realm.close()
return report
}
private fun computeRiskOfRuin(report: BankrollReport, results: ComputedResults) {
val hourlyRate = results.computedStat(Stat.HOURLY_RATE)?.value
val hourlyStandardDeviation = results.computedStat(Stat.STANDARD_DEVIATION_HOURLY)?.value
if (hourlyRate != null && hourlyStandardDeviation != null) {
report.riskOfRuin = Stat.riskOfRuin(hourlyRate, hourlyStandardDeviation, report.total)
}
}
}
}

@ -1,71 +1,16 @@
package net.pokeranalytics.android.calculus.bankroll
import net.pokeranalytics.android.calculus.interfaces.DatableValue
import android.content.Context
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineDataSet
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.interfaces.DatedValue
import net.pokeranalytics.android.model.realm.Bankroll
import net.pokeranalytics.android.model.realm.Transaction
import net.pokeranalytics.android.ui.graph.PALineDataSet
import java.util.*
import kotlin.collections.HashMap
/**
* A class describing the parameters required to launch a bankroll report
*
*/
class BankrollReportSetup(val bankroll: Bankroll?, val from: Date? = null, val to: Date? = null) {
val queryConditions: List<QueryCondition>
get() {
val conditions = mutableListOf<QueryCondition>()
this.bankroll?.let {
val bankrollCondition = QueryCondition.AnyBankroll(bankroll)
conditions.add(bankrollCondition)
}
this.from?.let {
val fromCondition = QueryCondition.StartedFromDate()
fromCondition.singleValue = it
conditions.add(fromCondition)
}
this.to?.let {
val toCondition = QueryCondition.StartedToDate()
toCondition.singleValue = it
conditions.add(toCondition)
}
return conditions
}
}
class TransactionBucket(useRate: Boolean = false) {
var transactions: MutableList<Transaction> = mutableListOf()
private set
var total: Double = 0.0
private set
var useRate: Boolean = useRate
private set
fun addTransaction(transaction: Transaction) {
this.transactions.add(transaction)
var rate = 1.0
if (this.useRate) {
rate = transaction.bankroll?.currency?.rate ?: 1.0
}
val ratedAmount = rate * transaction.amount
this.total += ratedAmount
}
}
class BRGraphPoint {
var value: Double = 0.0
var variation: Double = 0.0
var date: Date? = null
}
class BankrollReport(setup: BankrollReportSetup) {
@ -80,11 +25,50 @@ class BankrollReport(setup: BankrollReportSetup) {
var total: Double = 0.0
private set
/**
* The initial value of the bankroll, or of all bankrolls if virtual is computed
*/
var initial: Double = 0.0
/**
* The net result from poker computables
*/
var netResult: Double = 0.0
private set
set(value) {
field = value
this.computeBankrollTotal()
}
/**
* The net result from transactions
*/
var transactionsNet: Double = 0.0
set(value) {
field = value
this.computeBankrollTotal()
}
fun computeBankrollTotal() {
this.total = this.initial + this.netResult + this.transactionsNet
}
/**
* The sum of all deposits
*/
var depositTotal: Double = 0.0
set(value) {
field = value
this.netBanked = this.depositTotal + this.withdrawalTotal
}
/**
* The sum of all withdrawals
*/
var withdrawalTotal: Double = 0.0
set(value) {
field = value
this.netBanked = this.depositTotal + this.withdrawalTotal
}
/**
* The difference between withdrawals and deposits
@ -95,16 +79,21 @@ class BankrollReport(setup: BankrollReportSetup) {
/**
* The risk of ruin
*/
var riskOfRuin: Double = 0.0
private set
var riskOfRuin: Double? = null
var transactions: List<Transaction> = mutableListOf()
private set
var transactionBuckets: HashMap<String, TransactionBucket> = HashMap()
private set
var evolutionPoints: Array<BRGraphPoint> = arrayOf()
var evolutionItems: Array<DatableValue> = arrayOf()
var evolutionPoints: MutableList<BRGraphPoint> = mutableListOf()
var evolutionItems: MutableList<DatedValue> = mutableListOf()
private set
fun addDatedItems(items: Collection<DatedValue>) {
this.evolutionItems.addAll(items)
}
fun addTransaction(transaction: Transaction) {
@ -113,7 +102,7 @@ class BankrollReport(setup: BankrollReportSetup) {
var bucket = this.transactionBuckets[type.id]
if (bucket == null) {
val b = TransactionBucket(this.setup.bankroll == null)
val b = TransactionBucket(this.setup.virtualBankroll)
this.transactionBuckets[type.id] = b
bucket = b
}
@ -126,5 +115,93 @@ class BankrollReport(setup: BankrollReportSetup) {
}
fun generateGraphPointsIfNecessary() {
if (!this.setup.virtualBankroll) {
return
}
this.evolutionItems.sortBy { it.date }
this.evolutionItems.forEach {
val point = BRGraphPoint(it.amount, it.date, it)
this.evolutionPoints.add(point)
}
}
fun lineDataSet(context: Context): LineDataSet {
val entries = mutableListOf<Entry>()
this.evolutionPoints.forEach {
val entry = Entry(it.date.time.toFloat(), it.value.toFloat(), it.data)
entries.add(entry)
}
return PALineDataSet(entries, "", context)
}
}
/**
* A class describing the parameters required to launch a bankroll report
*
*/
class BankrollReportSetup(val bankroll: Bankroll? = null, val from: Date? = null, val to: Date? = null) {
val virtualBankroll: Boolean
get() {
return this.bankroll == null
}
val queryConditions: List<QueryCondition>
get() {
val conditions = mutableListOf<QueryCondition>()
this.bankroll?.let {
val bankrollCondition = QueryCondition.AnyBankroll(bankroll)
conditions.add(bankrollCondition)
}
this.from?.let {
val fromCondition = QueryCondition.StartedFromDate()
fromCondition.singleValue = it
conditions.add(fromCondition)
}
this.to?.let {
val toCondition = QueryCondition.StartedToDate()
toCondition.singleValue = it
conditions.add(toCondition)
}
return conditions
}
}
class TransactionBucket(useRate: Boolean = false) {
var transactions: MutableList<Transaction> = mutableListOf()
private set
var total: Double = 0.0
private set
var useRate: Boolean = useRate
private set
fun addTransaction(transaction: Transaction) {
this.transactions.add(transaction)
var rate = 1.0
if (this.useRate) {
rate = transaction.bankroll?.currency?.rate ?: 1.0
}
val ratedAmount = rate * transaction.amount
this.total += ratedAmount
}
}
data class BRGraphPoint(var value: Double, var date: Date, var data: Any? = null) {
var variation: Double = 0.0
}

@ -1,11 +0,0 @@
package net.pokeranalytics.android.calculus.interfaces
import java.util.*
interface Datable {
var date: Date
}
interface DatableValue : Datable {
var value: Double
}

@ -7,6 +7,7 @@ import net.pokeranalytics.android.model.realm.ComputableResult
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.SessionSet
import net.pokeranalytics.android.model.realm.Transaction
import net.pokeranalytics.android.model.realm.Result
/**
* We want to be able to store filters in the database:
@ -65,6 +66,7 @@ class FilterHelper {
ComputableResult::class.java -> ComputableResult.fieldNameForQueryType(queryCondition)
SessionSet::class.java -> SessionSet.fieldNameForQueryType(queryCondition)
Transaction::class.java -> Transaction.fieldNameForQueryType(queryCondition)
Result::class.java -> Result.fieldNameForQueryType(queryCondition)
else -> {
throw UnmanagedFilterField("Filterable type fields are not defined for class ${T::class}")
}

@ -0,0 +1,15 @@
package net.pokeranalytics.android.model.interfaces
import java.util.*
interface Dated {
var date: Date
}
interface DatedValue : Dated {
var amount: Double
}

@ -64,6 +64,10 @@ class PokerAnalyticsMigration : RealmMigration {
it.removeField("sessionSet")
}
schema.get("Bankroll")?.let {
it.addField("initialValue", Double::class.java).setRequired("initialValue", true)
}
currentVersion++
}

@ -8,29 +8,12 @@ import io.realm.kotlin.where
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.BankrollRow
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow
import net.pokeranalytics.android.util.NULL_TEXT
import java.util.*
import kotlin.collections.ArrayList
open class Bankroll() : RealmObject(), NameManageable, StaticRowRepresentableDataSource, RowRepresentable {
companion object {
val rowRepresentation : List<RowRepresentable> by lazy {
val rows = ArrayList<RowRepresentable>()
rows.add(SimpleRow.NAME)
rows.add(BankrollRow.LIVE)
rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.currency))
rows.add(BankrollRow.CURRENCY)
rows
}
}
open class Bankroll() : RealmObject(), NameManageable, RowRepresentable {
@PrimaryKey
override var id = UUID.randomUUID().toString()
@ -46,37 +29,16 @@ open class Bankroll() : RealmObject(), NameManageable, StaticRowRepresentableDat
// The currency of the bankroll
var currency: Currency? = null
override fun getDisplayName(): String {
return this.name
}
// Row Representable Datasource
override fun adapterRows(): List<RowRepresentable>? {
return Bankroll.rowRepresentation
}
// The initial value of the bankroll
var initialValue: Double = 0.0
override fun stringForRow(row: RowRepresentable): String {
return when (row) {
SimpleRow.NAME -> if (this.name.isNotEmpty()) this.name else NULL_TEXT
else -> return super.stringForRow(row)
}
val rate: Double
get() {
return this.currency?.rate ?: 1.0
}
override fun boolForRow(row: RowRepresentable): Boolean {
return when (row) {
BankrollRow.LIVE -> !this.live
else -> super.boolForRow(row)
}
}
override fun editDescriptors(row: RowRepresentable): ArrayList<RowRepresentableEditDescriptor>? {
return when (row) {
SimpleRow.NAME -> row.editingDescriptors(mapOf("defaultValue" to this.name))
BankrollRow.RATE -> row.editingDescriptors(mapOf())
else -> {
row.editingDescriptors(mapOf())
}
}
override fun getDisplayName(): String {
return this.name
}
override fun updateValue(value: Any?, row: RowRepresentable) {
@ -84,6 +46,9 @@ open class Bankroll() : RealmObject(), NameManageable, StaticRowRepresentableDat
SimpleRow.NAME -> this.name = value as String? ?: ""
BankrollRow.LIVE -> {
this.live = if (value is Boolean) !value else false
}
BankrollRow.INITIAL_VALUE -> {
this.initialValue = value as Double? ?: 0.0
}
BankrollRow.CURRENCY -> {
//TODO handle a use default currency option

@ -6,10 +6,22 @@ import io.realm.RealmResults
import io.realm.annotations.Ignore
import io.realm.annotations.LinkingObjects
import io.realm.annotations.RealmClass
import net.pokeranalytics.android.model.filter.Filterable
import net.pokeranalytics.android.model.filter.QueryCondition
@RealmClass
open class Result : RealmObject() {
open class Result : RealmObject(), Filterable {
companion object {
fun fieldNameForQueryType(queryCondition: Class < out QueryCondition>): String? {
Session.fieldNameForQueryType(queryCondition)?.let {
return "sessions.$it"
}
return null
}
}
/**
* The buyin amount
*/

@ -45,7 +45,7 @@ import kotlin.collections.ArrayList
typealias BB = Double
open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDataSource, RowRepresentable, Timed,
TimeFilterable, Filterable {
TimeFilterable, Filterable, DatedValue {
enum class Type {
CASH_GAME,
@ -308,10 +308,10 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
get() {
val bb = this.cgBigBlind
val result = this.result
if (bb != null && result != null) {
return result.net / bb
return if (bb != null && result != null) {
result.net / bb
} else {
return 0.0
0.0
}
}
@ -326,6 +326,21 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
return noh * hd
}
// DatedValue
@Ignore
override var date: Date = Date()
get() {
return this.startDate ?: this.creationDate
}
@Ignore
override var amount: Double = 0.0
get() {
return this.computableResult?.ratedNet ?: 0.0
}
/**
* Pre-compute various stats
*/
@ -973,10 +988,10 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
}
}
return LegendView.Values(this.entryTitle, left, right)
LegendView.Values(this.entryTitle, left, right)
}
else -> {
return super.legendValues(stat, entry)
super.legendValues(stat, entry)
}
}

@ -7,6 +7,7 @@ import io.realm.annotations.PrimaryKey
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.filter.Filterable
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.interfaces.DatedValue
import net.pokeranalytics.android.model.interfaces.Manageable
import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
@ -17,7 +18,7 @@ import java.util.*
import kotlin.collections.ArrayList
open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSource, RowRepresentable, Filterable {
open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSource, RowRepresentable, Filterable, DatedValue {
companion object {
val rowRepresentation: List<RowRepresentable> by lazy {
@ -42,10 +43,10 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo
var bankroll: Bankroll? = null
// The amount of the transaction
var amount: Double = 0.0
override var amount: Double = 0.0
// The date of the transaction
var date: Date = Date()
override var date: Date = Date()
// The type of the transaction
var type: TransactionType? = null

@ -14,13 +14,29 @@ import kotlin.collections.ArrayList
open class TransactionType : RealmObject(), NameManageable, StaticRowRepresentableDataSource, RowRepresentable {
enum class Value(val additive: Boolean) {
WITHDRAWAL(false),
DEPOSIT(true),
BONUS(true)
}
companion object {
val rowRepresentation : List<RowRepresentable> by lazy {
val rowRepresentation: List<RowRepresentable> by lazy {
val rows = ArrayList<RowRepresentable>()
rows.add(SimpleRow.NAME)
rows.addAll(TransactionTypeRow.values())
rows
}
fun getByValue(value: Value, realm: Realm): TransactionType {
val type = realm.where(TransactionType::class.java).equalTo("kind", value.ordinal).findFirst()
type?.let {
return it
}
throw IllegalStateException("Transaction type ${value.name} should exist in database!")
}
}
@PrimaryKey
@ -43,7 +59,7 @@ open class TransactionType : RealmObject(), NameManageable, StaticRowRepresentab
}
override fun adapterRows(): List<RowRepresentable>? {
return TransactionType.rowRepresentation
return rowRepresentation
}
override fun stringForRow(row: RowRepresentable): String {
@ -72,7 +88,3 @@ open class TransactionType : RealmObject(), NameManageable, StaticRowRepresentab
}
}
enum class TransactionKind {
WITHDRAWAL,
DEPOSIT
}

@ -3,12 +3,10 @@ package net.pokeranalytics.android.model.utils
import android.content.Context
import io.realm.Realm
import io.realm.kotlin.where
import net.pokeranalytics.android.model.realm.Bankroll
import net.pokeranalytics.android.model.realm.*
import net.pokeranalytics.android.model.realm.Currency
import net.pokeranalytics.android.model.realm.TournamentFeature
import java.util.*
import net.pokeranalytics.android.model.realm.Game
import net.pokeranalytics.android.util.UserDefaults
import java.util.*
class Seed(var context:Context) : Realm.Transaction {
@ -17,6 +15,7 @@ class Seed(var context:Context) : Realm.Transaction {
this.createDefaultGames(realm)
this.createDefaultTournamentFeatures(realm)
this.createDefaultCurrencyAndBankroll(realm)
this.createDefaultTransactionTypes(realm)
}
private fun createDefaultTournamentFeatures(realm: Realm) {
@ -55,4 +54,15 @@ class Seed(var context:Context) : Realm.Transaction {
realm.insertOrUpdate(game)
}
}
private fun createDefaultTransactionTypes(realm: Realm) {
TransactionType.Value.values().forEachIndexed { index, value ->
val type = TransactionType()
type.additive = value.additive
type.kind = index
type.lock = true
realm.insertOrUpdate(type)
}
}
}

@ -18,8 +18,8 @@ import net.pokeranalytics.android.ui.view.rowrepresentable.BankrollRow
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow
import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.UserDefaults
import net.pokeranalytics.android.util.extensions.toCurrency
import net.pokeranalytics.android.util.extensions.toRate
import retrofit2.Call
import retrofit2.Response
@ -95,6 +95,9 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS
NULL_TEXT
}
}
BankrollRow.INITIAL_VALUE -> {
this.bankroll.initialValue.toCurrency()
}
BankrollRow.RATE -> {
val rate = this.bankroll.currency?.rate ?: 1.0
rate.toRate()
@ -114,6 +117,9 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS
override fun editDescriptors(row: RowRepresentable): ArrayList<RowRepresentableEditDescriptor>? {
return when (row) {
SimpleRow.NAME -> row.editingDescriptors(mapOf("defaultValue" to this.bankroll.name))
BankrollRow.INITIAL_VALUE -> {
row.editingDescriptors(mapOf("defaultValue" to this.bankroll.initialValue))
}
BankrollRow.RATE -> {
val rate = this.bankroll.currency?.rate
row.editingDescriptors(mapOf("defaultValue" to rate))
@ -163,6 +169,7 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS
rows.clear()
rows.add(SimpleRow.NAME)
rows.add(BankrollRow.LIVE)
rows.add(BankrollRow.INITIAL_VALUE)
rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.currency))
rows.add(BankrollRow.CURRENCY)
if (this.shouldShowCurrencyRate) {

@ -159,12 +159,6 @@ open class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDele
finishActivityWithResult(uniqueIdentifier)
}
// if (managedItem is Bankroll) {
// managedItem.currency?.refreshRelatedRatedValues(it)
// }
//
// val uniqueIdentifier = (managedItem as Savable).id
// finishActivityWithResult(uniqueIdentifier)
}
}
else -> {

@ -11,6 +11,7 @@ import net.pokeranalytics.android.ui.view.RowViewType
enum class BankrollRow : RowRepresentable, DefaultEditDataSource {
LIVE,
INITIAL_VALUE,
CURRENCY,
RATE,
REFRESH_RATE;
@ -19,6 +20,7 @@ enum class BankrollRow : RowRepresentable, DefaultEditDataSource {
get() {
return when (this) {
LIVE -> R.string.online
INITIAL_VALUE -> R.string.initial_value
CURRENCY -> R.string.currency
RATE -> R.string.rate
REFRESH_RATE -> R.string.refresh_rate
@ -29,6 +31,7 @@ enum class BankrollRow : RowRepresentable, DefaultEditDataSource {
get() {
return when (this) {
LIVE -> RowViewType.TITLE_SWITCH.ordinal
INITIAL_VALUE -> RowViewType.TITLE_VALUE.ordinal
CURRENCY -> RowViewType.TITLE_VALUE_ARROW.ordinal
RATE -> RowViewType.TITLE_VALUE.ordinal
REFRESH_RATE -> RowViewType.ROW_BUTTON.ordinal
@ -39,6 +42,7 @@ enum class BankrollRow : RowRepresentable, DefaultEditDataSource {
get() {
return when (this) {
LIVE -> BottomSheetType.NONE
INITIAL_VALUE -> BottomSheetType.NUMERIC_TEXT
CURRENCY -> BottomSheetType.NONE
RATE -> BottomSheetType.NUMERIC_TEXT
REFRESH_RATE -> BottomSheetType.NONE
@ -47,6 +51,13 @@ enum class BankrollRow : RowRepresentable, DefaultEditDataSource {
override fun editingDescriptors(map: Map<String, Any?>): ArrayList<RowRepresentableEditDescriptor>? {
return when (this) {
INITIAL_VALUE -> {
val defaultValue : Any? by map
arrayListOf(
RowRepresentableEditDescriptor(defaultValue, R.string.initial_value, InputType.TYPE_CLASS_NUMBER
or InputType.TYPE_NUMBER_FLAG_DECIMAL)
)
}
RATE -> {
val defaultValue : Any? by map
arrayListOf(

@ -8,6 +8,7 @@
<string name="more">More</string>
<string name="variant">Variant</string>
<string name="line">Line</string>
<string name="initial_value">Initial Value</string>
<!--<string name="session_missing_end_date">Please set the end date for the session</string>-->
<!--<string name="default_error_message">Sorry, something went wrong...please contact us!</string>-->

Loading…
Cancel
Save