diff --git a/app/src/androidTest/java/net/pokeranalytics/android/model/CriteriaTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/model/CriteriaTest.kt index f2a1621b..c0040e5c 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/model/CriteriaTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/model/CriteriaTest.kt @@ -23,10 +23,10 @@ class CriteriaTest : BaseFilterInstrumentedUnitTest() { val cal = Calendar.getInstance() cal.time = Date() val s1 = Session.testInstance(100.0, false, cal.time) + val firstValue = cal.get(Calendar.YEAR) cal.add(Calendar.YEAR, 1) Session.testInstance(100.0, true, cal.time) cal.add(Calendar.YEAR, -11) - val firstValue = cal.get(Calendar.YEAR) Session.testInstance(100.0, true, cal.time) cal.add(Calendar.YEAR, 7) Session.testInstance(100.0, true, cal.time) @@ -35,23 +35,23 @@ class CriteriaTest : BaseFilterInstrumentedUnitTest() { cal.add(Calendar.YEAR, 10) Session.testInstance(100.0, true, cal.time) - val lastValue = firstValue + 10 + val lastValue = firstValue + 5 realm.commitTransaction() val years = Criteria.Years.queryConditions as List println("years = ${years.map { it.getDisplayName() }}") - assertEquals(11, years.size) - assertEquals(firstValue, years.first().listOfValues.first()) + assertEquals(16, years.size) + assertEquals(firstValue-10, years.first().listOfValues.first()) assertEquals(lastValue, years.last().listOfValues.first()) } @Test fun combined() { - val critierias = listOf(Criteria.MonthsOfYear, Criteria.DaysOfWeek) - val combined = critierias.combined() + val criterias = listOf(Criteria.MonthsOfYear, Criteria.DaysOfWeek) + val combined = criterias.combined() combined.forEach { it.forEach {qc-> println(qc.getDisplayName()) @@ -82,23 +82,12 @@ class CriteriaTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val critierias = listOf(Criteria.Years, Criteria.MonthsOfYear) - val combined = critierias.combined() - combined.forEach { + val allMonths = Criteria.AllMonthsUpToNow.predicates + allMonths.forEach { it.forEach {qc-> println("<<<<< ${qc.getDisplayName()}") } } - - println("<<<<< reduced") - - val reduced= critierias.combined().upToNow() - reduced.forEach { - it.forEach {qc-> - println("<<<<< ${qc.getDisplayName()}") - } - } - } } \ No newline at end of file diff --git a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/SessionFilterInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/SessionFilterInstrumentedUnitTest.kt index 8a477114..5d2cab7b 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/SessionFilterInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/SessionFilterInstrumentedUnitTest.kt @@ -541,4 +541,36 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Assert.assertTrue(result.contains((it as Session).id)) } } + + @Test + fun testNumberOfRebuys() { + val realm = this.mockRealm + realm.beginTransaction() + val s1 = Session.testInstance(netResult = 200.0, isTournament = true) + s1.result!!.buyin = 50.0 + s1.tournamentEntryFee = 10.0 + val s2 = Session.testInstance(netResult = 50.0, isTournament = true) + s2.result!!.buyin = 10.0 + s2.tournamentEntryFee = 10.0 + + + val s3 = Session.testInstance(netResult = 500.0) + s3.cgBigBlind = 2.0 + s3.result!!.buyin = 1000.0 + + val s4 = Session.testInstance(netResult = 570.0) + s4.cgBigBlind = 5.0 + s4.result!!.buyin = 200.0 + realm.commitTransaction() + + val filterMore = QueryCondition.NumberOfRebuy(QueryCondition.Operator.MORE, 5.0) + val sessions = Filter.queryOn(realm, arrayListOf(filterMore)) + + Assert.assertEquals(2, sessions.size) + + val result = arrayListOf(s1.id, s3.id) + sessions.forEach { + Assert.assertTrue(result.contains((it as Session).id)) + } + } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt index a16c0963..8abd764e 100644 --- a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt +++ b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt @@ -30,7 +30,7 @@ class PokerAnalyticsApplication : Application() { Realm.init(this) val realmConfiguration = RealmConfiguration.Builder() .name(Realm.DEFAULT_REALM_NAME) - .schemaVersion(3) + .schemaVersion(4) .migration(PokerAnalyticsMigration()) .initialData(Seed(this)) .build() diff --git a/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt b/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt index 9df897ab..24071bfb 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt @@ -24,6 +24,13 @@ fun List>.upToNow(): List> { val currentYear = calendar.get(Calendar.YEAR) val currentMonth = calendar.get(Calendar.MONTH) + val realm = Realm.getDefaultInstance() + val firstSession = realm.where().sort("year", Sort.ASCENDING).findFirst() + realm.close() + + val firstYear = firstSession?.year ?: currentYear + val firstMonth = firstSession?.month ?: currentMonth + val toRemove = this.filter { list -> list.any { it is QueryCondition.AnyYear && it.listOfValues.first() == currentYear } }.filter { list -> @@ -32,6 +39,14 @@ fun List>.upToNow(): List> { } } + val toRemoveBefore = this.filter { list -> + list.any { it is QueryCondition.AnyYear && it.listOfValues.first() == firstYear } + }.filter { list -> + list.any { + it is QueryCondition.AnyMonthOfYear && it.listOfValues.first() < firstMonth + } + } + return this.filter{ list -> var keep = true toRemove.forEach { @@ -39,6 +54,13 @@ fun List>.upToNow(): List> { keep = false } } + firstSession?.let { + toRemoveBefore.forEach { + if (list.containsAll(it)) { + keep = false + } + } + } keep } } @@ -126,11 +148,50 @@ sealed class Criteria { object BankrollTypes: SimpleCriteria(listOf(QueryCondition.IsLive, QueryCondition.IsOnline)) object DayPeriods: SimpleCriteria(listOf(QueryCondition.IsWeekDay, QueryCondition.IsWeekEnd)) object Years: ListCriteria() + object AllMonthsUpToNow: ListCriteria() object Blinds: ListCriteria() object TournamentFees: ListCriteria() object Cash: SimpleCriteria(listOf(QueryCondition.IsCash)) object Tournament: SimpleCriteria(listOf(QueryCondition.IsTournament)) + val predicates: List> + get() { + return when (this) { + is AllMonthsUpToNow -> { + val realm = Realm.getDefaultInstance() + val firstSession= realm.where().sort("startDate", Sort.ASCENDING).findFirst() + val lastSession = realm.where().sort("startDate", Sort.DESCENDING).findFirst() + realm.close() + + val years: ArrayList> = arrayListOf() + + val firstYear = firstSession?.year ?: return years + val firstMonth = firstSession.month ?: return years + val lastYear = lastSession?.year ?: return years + val lastMonth = lastSession.month ?: return years + + for (year in firstYear..lastYear) { + val currentYear = QueryCondition.AnyYear(year) + for (month in 0..11) { + + if (year == firstYear && month < firstMonth) { + continue + } + if (year == lastYear && month > lastMonth) { + continue + } + + val currentMonth = QueryCondition.AnyMonthOfYear(month) + val currentList = listOf(currentYear, currentMonth) + years.add(currentList) + } + } + years + } + else -> listOf(listOf()) + } + } + val queryConditions: List get() { return when (this) { @@ -146,10 +207,10 @@ sealed class Criteria { is TournamentFees -> comparison() is Years -> { val years = arrayListOf() - val calendar = Calendar.getInstance() - calendar.time = Date() - val yearNow = calendar.get(Calendar.YEAR) val realm = Realm.getDefaultInstance() + val lastSession = realm.where().sort("startDate", Sort.DESCENDING).findFirst() + val yearNow = lastSession?.year ?: return years + realm.where().sort("year", Sort.ASCENDING).findFirst()?.year?.let { for (index in 0..(yearNow - it)) { years.add(QueryCondition.AnyYear().apply { diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt index 0f44e1ae..b5166458 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt @@ -330,8 +330,16 @@ sealed class QueryCondition : FilterElementRow { class NumberOfTable: ListOfInt() - open class NetAmountWon: ListOfDouble() - class NetAmountLost: NetAmountWon() { override var sign: Int = -1 } + class NumberOfRebuy(): ListOfDouble() { + constructor(operator: Operator, numberOfRebuy: Double) : this() { + this.operator = operator + listOfValues = arrayListOf(numberOfRebuy) + } + } + + open class NetAmount: ListOfDouble() + class NetAmountWon: NetAmount() + class NetAmountLost: NetAmount() { override var sign: Int = -1 } class NumberOfPlayer: ListOfInt() @@ -346,16 +354,24 @@ sealed class QueryCondition : FilterElementRow { } } - class AnyMonthOfYear: ListOfInt() { + class AnyMonthOfYear(): ListOfInt() { override fun labelForValue(value: Int): String { return DateFormatSymbols.getInstance(Locale.getDefault()).months[value] } + + constructor(month:Int) : this() { + listOfValues = arrayListOf(month) + } } - class AnyYear: ListOfInt() { + class AnyYear(): ListOfInt() { override fun labelForValue(value: Int): String { return "$value" } + + constructor(year:Int) : this() { + listOfValues = arrayListOf(year) + } } object IsWeekDay: QueryCondition() diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt index 498cf6d2..e0e670f3 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt @@ -1,6 +1,10 @@ package net.pokeranalytics.android.model.migrations import io.realm.Realm +import net.pokeranalytics.android.model.filter.QueryCondition +import net.pokeranalytics.android.model.realm.Filter +import net.pokeranalytics.android.model.realm.Result +import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.SessionSet class Patcher { @@ -11,12 +15,19 @@ class Patcher { val realm = Realm.getDefaultInstance() val sets = realm.where(SessionSet::class.java).findAll() + val sessions = Filter.queryOn(realm, arrayListOf(QueryCondition.IsCash)) + val results = realm.where(Result::class.java).findAll() realm.executeTransaction { sets.forEach { it.computeStats() } - + sessions.forEach { + it.formatBlinds() + } + results.forEach { + it.computeNumberOfRebuy() + } } realm.close() diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index 81fb9afe..44755ecc 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -60,7 +60,9 @@ class PokerAnalyticsMigration : RealmMigration { } schema.get("Session")?.let { - it.addField("blinds", String::class.java) + it.addField("blinds", String::class.java).transform { + + } } schema.get("FilterCondition")?.let { @@ -89,6 +91,15 @@ class PokerAnalyticsMigration : RealmMigration { currentVersion++ } + // Migrate to version 3 + if (currentVersion == 3) { + Timber.d("*** Running migration ${currentVersion + 1}") + + schema.get("Result")?.let { + it.addField("numberOfRebuy", Double::class.java).setNullable("numberOfRebuy", true) + } + currentVersion++ + } } override fun equals(other: Any?): Boolean { diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt index df768729..3f0bc919 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt @@ -87,7 +87,7 @@ open class Result : RealmObject(), Filterable { var tournamentFinalPosition: Int? = null // Number of rebuys - //var numberOfRebuy: Double? = null + var numberOfRebuy: Double? = null @LinkingObjects("result") private val sessions: RealmResults? = null @@ -122,7 +122,26 @@ open class Result : RealmObject(), Filterable { } // Computes the number of rebuy - private fun computeNumberOfRebuy() { + fun computeNumberOfRebuy() { + this.session?.let { + if (it.isCashGame()) { + it.cgBigBlind?.let { bb -> + if (bb > 0.0) { + this.numberOfRebuy = (this.buyin ?: 0.0) / (bb * 100.0) + } else { + this.numberOfRebuy = null + } + } + } else { + it.tournamentEntryFee?.let { entryFee -> + if (entryFee > 0.0) { + this.numberOfRebuy = (this.buyin ?: 0.0) / entryFee + } else { + this.numberOfRebuy = null + } + } + } + } } // @todo tips? diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 839ab4e5..f08e56cb 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -77,8 +77,9 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat AnyTournamentType::class.java -> "tournamentType" AnyBlind::class.java -> "blinds" NumberOfTable::class.java -> "numberOfTable" - NetAmountWon::class.java -> "computableResults.ratedNet" - NumberOfPlayer::class.java -> "tournamentNumberOfPlayers" + NetAmount::class.java -> "computableResults.ratedNet" + NumberOfRebuy::class.java -> "result.numberOfRebuy" + NumberOfPlayer::class.java -> "result.tournamentNumberOfPlayers" TournamentFee::class.java -> "tournamentEntryFee" StartedFromDate::class.java, StartedToDate::class.java -> "startDate" EndedFromDate::class.java, EndedToDate::class.java -> "endDate" @@ -222,6 +223,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat field = value this.computeStats() formatBlinds() + this.result?.computeNumberOfRebuy() } var blinds: String? = null @@ -231,6 +233,10 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat // The entry fee of the tournament var tournamentEntryFee: Double? = null + set(value) { + field = value + this.result?.computeNumberOfRebuy() + } // The total number of players who participated in the tournament var tournamentNumberOfPlayers: Int? = null @@ -525,7 +531,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat return blinds ?: NULL_TEXT } - private fun formatBlinds() { + fun formatBlinds() { blinds = null if (cgBigBlind == null) return cgBigBlind?.let { bb -> diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterCategoryRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterCategoryRow.kt index 5bc99a77..f0202ccc 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterCategoryRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterCategoryRow.kt @@ -74,7 +74,8 @@ enum class FilterCategoryRow(override val resId: Int?, override val viewType: In MULTI_PLAYER ) RESULT -> arrayListOf( - VALUE + VALUE, + NUMBER_OF_REBUY ) TRANSACTION_TYPES -> arrayListOf() diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt index f4bd2859..a2235c00 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt @@ -33,12 +33,13 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable { PLAYERS_COUNT(R.string.players_count), TOURNAMENT_RE_BUY_COUNT(R.string.rebuy_count), ENTRY_FEE(R.string.buyin), - MULTI_TABLING(R.string.multi_tabling), + MULTI_TABLING(R.string.number_of_tables), VALUE(R.string.value), LOCATION(R.string.locations), BANKROLL(R.string.bankrolls), NUMBER_OF_PLAYERS(R.string.number_of_players), MULTI_PLAYER(R.string.multiplayer), + NUMBER_OF_REBUY(R.string.number_of_buyins) ; private enum class SelectionType { @@ -89,14 +90,12 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable { // Cash BLIND -> Criteria.Blinds.queryConditions -// CASH_RE_BUY_COUNT -> QueryCondition.moreOrLess() // Tournament TOURNAMENT_TYPE -> Criteria.TournamentTypes.queryConditions // COMPLETION_PERCENTAGE -> arrayListOf() -// PLACE -> QueryCondition.moreOrLess() + //PLACE -> QueryCondition.moreOrLess() PLAYERS_COUNT -> QueryCondition.moreOrLess() -// TOURNAMENT_RE_BUY_COUNT -> QueryCondition.moreOrLess() ENTRY_FEE -> Criteria.TournamentFees.queryConditions TOURNAMENT_NAME -> Criteria.TournamentNames.queryConditions @@ -104,7 +103,8 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable { LOCATION -> Criteria.Locations.queryConditions BANKROLL -> Criteria.Bankrolls.queryConditions MULTI_TABLING -> QueryCondition.moreOrLess() -// NUMBER_OF_PLAYERS -> QueryCondition.moreOrLess() + NUMBER_OF_PLAYERS -> QueryCondition.moreOrLess() + NUMBER_OF_REBUY -> QueryCondition.moreOrLess() // MULTI_PLAYER -> arrayListOf() VALUE -> arrayListOf().apply {