From 4fbcae37fd0c218c26b21bf9ec7be6eca23dcc56 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 21 Jun 2019 16:59:24 +0200 Subject: [PATCH] Add new transaction types for stacking, as well as support for it in the PBT import --- app/src/main/AndroidManifest.xml | 16 +++--- .../android/model/migrations/Patcher.kt | 13 +++++ .../android/model/realm/Transaction.kt | 11 ++++ .../android/model/realm/TransactionType.kt | 42 ++++++++++++-- .../android/model/utils/Seed.kt | 31 ++++++---- .../android/ui/fragment/FeedFragment.kt | 29 +++++----- .../ui/view/rowrepresentable/SettingRow.kt | 4 +- .../android/util/Preferences.kt | 3 +- .../android/util/csv/CSVDescriptor.kt | 4 ++ .../android/util/csv/ProductCSVDescriptors.kt | 2 + .../android/util/csv/SessionCSVDescriptor.kt | 56 ++++++++++++++----- .../android/util/csv/SessionField.kt | 11 ++++ app/src/main/res/values/strings.xml | 2 + .../pokeranalytics/android/SavableEnumTest.kt | 5 ++ 14 files changed, 172 insertions(+), 57 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 969194d3..b7e5f47c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -39,16 +39,16 @@ android:screenOrientation="portrait" android:launchMode="singleTop"> - - - + + + - - - - + + + + - + 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 2f325f92..d0097048 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 @@ -5,6 +5,7 @@ import io.realm.Realm import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.realm.* +import net.pokeranalytics.android.model.utils.Seed import net.pokeranalytics.android.util.Preferences class Patcher { @@ -23,6 +24,18 @@ class Patcher { patchBlindFormat(context) } + val realm = Realm.getDefaultInstance() + + val lockedTypes = realm.where(TransactionType::class.java).equalTo("lock", true).findAll() + if (lockedTypes.size == 3) { + Preferences.executeOnce(Preferences.Keys.ADD_NEW_TRANSACTION_TYPES, context) { + val newTypes = arrayOf(TransactionType.Value.STACKING_INCOMING, TransactionType.Value.STACKING_OUTGOING) + Seed.createDefaultTransactionTypes(newTypes, context, realm) + patchBlindFormat(context) + } + } + + realm.close() } private fun patchBreaks() { diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt index bbf95d07..5efc1bbf 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt @@ -30,6 +30,17 @@ open class Transaction : RealmObject(), Manageable, StaticRowRepresentableDataSo companion object { + fun newInstance(realm: Realm, bankroll: Bankroll, date: Date? = null, type: TransactionType, amount: Double): Transaction { + + val transaction = realm.copyToRealm(Transaction()) + transaction.date = date ?: Date() + transaction.amount = amount + transaction.type = type + transaction.bankroll = bankroll + + return transaction + } + val rowRepresentation: List by lazy { val rows = ArrayList() rows.addAll(TransactionRow.values()) diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt index cc00a931..6886b576 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt @@ -17,16 +17,28 @@ import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow import net.pokeranalytics.android.ui.view.rowrepresentable.TransactionTypeRow +import net.pokeranalytics.android.util.enumerations.IntIdentifiable +import net.pokeranalytics.android.util.enumerations.IntSearchable import java.util.* import kotlin.collections.ArrayList open class TransactionType : RealmObject(), NameManageable, StaticRowRepresentableDataSource, RowRepresentable { - enum class Value(val additive: Boolean) : Localizable { - WITHDRAWAL(false), - DEPOSIT(true), - BONUS(true); + enum class Value(override var uniqueIdentifier: Int, val additive: Boolean) : IntIdentifiable, Localizable { + + WITHDRAWAL(0, false), + DEPOSIT(1, true), + BONUS(2, true), + STACKING_INCOMING(3, true), + STACKING_OUTGOING(4, false); + + companion object : IntSearchable { + + override fun valuesInternal(): Array { + return values() + } + } override val resId: Int? get() { @@ -34,8 +46,11 @@ open class TransactionType : RealmObject(), NameManageable, StaticRowRepresentab WITHDRAWAL -> R.string.withdrawal DEPOSIT -> R.string.deposit BONUS -> R.string.bonus + STACKING_INCOMING -> R.string.stacking_incoming + STACKING_OUTGOING -> R.string.stacking_outgoing } } + } companion object { @@ -47,13 +62,28 @@ open class TransactionType : RealmObject(), NameManageable, StaticRowRepresentab } fun getByValue(value: Value, realm: Realm): TransactionType { - val type = realm.where(TransactionType::class.java).equalTo("kind", value.ordinal).findFirst() + val type = realm.where(TransactionType::class.java).equalTo("kind", value.uniqueIdentifier).findFirst() type?.let { return it } throw PAIllegalStateException("Transaction type ${value.name} should exist in database!") } + fun getOrCreateByValue(realm: Realm, context: Context, value: Value): TransactionType { + val type = realm.where(TransactionType::class.java).equalTo("kind", value.uniqueIdentifier).findFirst() + type?.let { + return it + } + + val tt = TransactionType() + tt.name = value.localizedTitle(context) + tt.additive = value.additive + tt.kind = value.uniqueIdentifier + tt.lock = true + + return tt + } + } @Ignore @@ -64,7 +94,7 @@ open class TransactionType : RealmObject(), NameManageable, StaticRowRepresentab /** * The name of the transaction type - */ + */ override var name: String = "" /** diff --git a/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt b/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt index bb2875a8..72afe28a 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt @@ -12,11 +12,29 @@ import java.util.* class Seed(var context:Context) : Realm.Transaction { + companion object { + + fun createDefaultTransactionTypes(values: Array, context: Context, realm: Realm) { + values.forEach { value -> + + val existing = realm.where(TransactionType::class.java).equalTo("kind", value.uniqueIdentifier).findAll() + if (existing.isEmpty()) { + val type = TransactionType() + type.name = value.localizedTitle(context) + type.additive = value.additive + type.kind = value.uniqueIdentifier + type.lock = true + realm.insertOrUpdate(type) + } + } + } + } + override fun execute(realm: Realm) { this.createDefaultGames(realm) this.createDefaultTournamentFeatures(realm) this.createDefaultCurrencyAndBankroll(realm) - this.createDefaultTransactionTypes(realm) + createDefaultTransactionTypes(TransactionType.Value.values(), context, realm) } private fun createDefaultTournamentFeatures(realm: Realm) { @@ -56,15 +74,4 @@ class Seed(var context:Context) : Realm.Transaction { } } - private fun createDefaultTransactionTypes(realm: Realm) { - TransactionType.Value.values().forEachIndexed { index, value -> - val type = TransactionType() - type.name = value.localizedTitle(context) - type.additive = value.additive - type.kind = index - type.lock = true - realm.insertOrUpdate(type) - } - } - } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt index 3e4e68b4..d4a09661 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt @@ -33,6 +33,8 @@ import net.pokeranalytics.android.ui.view.ContextMenuRecyclerView import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager import net.pokeranalytics.android.util.Preferences +import net.pokeranalytics.android.util.billing.AppGuard +import net.pokeranalytics.android.util.extensions.count import java.text.SimpleDateFormat import java.util.* @@ -277,18 +279,19 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { */ private fun createNewSession(isTournament: Boolean, sessionId: String? = null, duplicate: Boolean = false) { -// val sessionCount = this.feedSessionAdapter.realmResults.size -// if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG -//// Toast.makeText(context, "Please subscribe!", Toast.LENGTH_LONG).show() -// BillingActivity.newInstanceForResult(this, true) -// return +// if (!BuildConfig.DEBUG) { + val sessionCount = getRealm().count(Session::class.java) + if (!AppGuard.isProUser && sessionCount >= AppGuard.MAX_SESSIONS_BEFORE_REQUESTING_SUBSCRIPTION) { // && !BuildConfig.DEBUG + BillingActivity.newInstanceForResult(this, true) + return + } // } // Keep commented code for special versions - if (Date().after(betaLimitDate)) { - this.showEndOfBetaMessage() - return - } +// if (Date().after(betaLimitDate)) { +// this.showEndOfBetaMessage() +// return +// } SessionActivity.newInstanceforResult( this, @@ -305,10 +308,10 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate { */ private fun createNewTransaction() { - if (Date().after(betaLimitDate)) { - this.showEndOfBetaMessage() - return - } +// if (Date().after(betaLimitDate)) { +// this.showEndOfBetaMessage() +// return +// } EditableDataActivity.newInstanceForResult(this, LiveData.TRANSACTION, null, RequestCode.NEW_TRANSACTION.value) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt index 2456d822..b5514060 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt @@ -52,8 +52,8 @@ enum class SettingRow : RowRepresentable { rows.addAll(arrayListOf(BANKROLL_REPORT)) rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.information)) - rows.addAll(arrayListOf(VERSION, RATE_APP, CONTACT_US, BUG_REPORT)) -// rows.addAll(arrayListOf(SUBSCRIPTION, VERSION, RATE_APP, CONTACT_US, BUG_REPORT)) +// rows.addAll(arrayListOf(VERSION, RATE_APP, CONTACT_US, BUG_REPORT)) + rows.addAll(arrayListOf(SUBSCRIPTION, VERSION, RATE_APP, CONTACT_US, BUG_REPORT)) rows.add(CustomizableRowRepresentable(customViewType = RowViewType.HEADER_TITLE, resId = R.string.follow_us)) rows.addAll(arrayListOf(FOLLOW_US)) diff --git a/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt index c9eca7ce..b4c73024 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt @@ -33,7 +33,8 @@ class Preferences { LATEST_PURCHASE("latestPurchase"), PATCH_BREAK("patchBreaks"), PATCH_TRANSACTION_TYPES_NAMES("patchTransactionTypesNames"), - PATCH_BLINDS_FORMAT("patchBlindFormat") + PATCH_BLINDS_FORMAT("patchBlindFormat"), + ADD_NEW_TRANSACTION_TYPES("addNewTransactionTypes") } enum class FeedMessage { diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt index 5813452f..2020fdd6 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt @@ -40,6 +40,10 @@ abstract class DataCSVDescriptor(source: DataSource, vararg el return if (data != null) 1 else 0 } + protected fun addAdditionallyCreatedIdentifiable(identifiable: Identifiable) { + this.realmModelIds.add(identifiable.objectIdentifier) + } + override fun cancel(realm: Realm) { if (realm.isInTransaction) { diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/ProductCSVDescriptors.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/ProductCSVDescriptors.kt index a475972b..2d84ff19 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/ProductCSVDescriptors.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/ProductCSVDescriptors.kt @@ -45,6 +45,8 @@ class ProductCSVDescriptors { SessionField.TournamentPosition("place"), SessionField.TournamentName("mttname"), SessionField.CurrencyCode("currency"), + SessionField.StackingIn("sharesincomings"), + SessionField.StackingOut("sharesoutgoings"), SessionField.CurrencyRate("exchangerate"), SessionField.TableSize("tablesize") ) diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt index 5888d53a..5b76f362 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt @@ -104,14 +104,13 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean if (DataUtils.transactionUnicityCheck(realm, date!!, amount, type)) { - val transaction = realm.copyToRealm(Transaction()) - transaction.date = date!! - transaction.amount = amount - transaction.type = type - - val bankroll = Bankroll.getOrCreate(realm, currencyCode!!, currencyCode = currencyCode!!, currencyRate = currencyRate) - transaction.bankroll = bankroll - return transaction + val bankroll = Bankroll.getOrCreate( + realm, + currencyCode!!, + currencyCode = currencyCode!!, + currencyRate = currencyRate + ) + return Transaction.newInstance(realm, bankroll, date!!, type, amount) } else { Timber.d("Transaction already exists") } @@ -130,11 +129,14 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean var endDate: Date? = null var isLive = true - var bankrollName: String? = null + var bankrollName = "" var currencyCode: String? = null var currencyRate: Double? = null var additionalBuyins = 0.0 // rebuy + addon + var stackingIn: Double? = null + var stackingOut: Double? = null + fields.forEach { field -> this.fieldMapping[field]?.let { index -> @@ -158,7 +160,8 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean session.result?.buyin = buyin if (session.type == Session.Type.TOURNAMENT.ordinal) { session.tournamentEntryFee = buyin - } else {} + } else { + } } is SessionField.CashedOut -> session.result?.cashout = field.parse(value) is SessionField.SessionType -> { @@ -177,12 +180,14 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean is SessionField.Game -> { if (value.isNotEmpty()) { session.game = realm.getOrCreate(value) - } else { } + } else { + } } is SessionField.Location -> { if (value.isNotEmpty()) { session.location = realm.getOrCreate(value) - } else { } + } else { + } } is SessionField.Bankroll -> bankrollName = value is SessionField.LimitType -> session.limit = Limit.getInstance(value)?.ordinal @@ -200,7 +205,8 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean is SessionField.TournamentName -> { if (value.isNotEmpty()) { session.tournamentName = realm.getOrCreate(value) - } else { } + } else { + } } is SessionField.TournamentType -> session.tournamentType = TournamentType.getValueForLabel(value)?.ordinal @@ -208,6 +214,12 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean field.parse(value)?.toInt() is SessionField.CurrencyCode -> currencyCode = value is SessionField.CurrencyRate -> currencyRate = field.parse(value) + is SessionField.StackingIn -> { + stackingIn = field.parse(value) + } + is SessionField.StackingOut -> { + stackingOut = field.parse(value) + } else -> { } } @@ -215,11 +227,12 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean } - if (bankrollName.isNullOrEmpty()) { + if (bankrollName.isEmpty()) { bankrollName = "Import" } - session.bankroll = Bankroll.getOrCreate(realm, bankrollName ?: "Import", isLive, currencyCode, currencyRate) + val bankroll = Bankroll.getOrCreate(realm, bankrollName, isLive, currencyCode, currencyRate) + session.bankroll = bankroll session.result?.buyin?.let { session.result?.buyin = it + additionalBuyins @@ -233,6 +246,19 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean val managedSession = realm.copyToRealm(session) managedSession.startDate = startDate managedSession.endDate = endDate + + if (stackingIn != null && stackingIn != 0.0) { + val type = TransactionType.getByValue(TransactionType.Value.STACKING_INCOMING, realm) + val transaction = Transaction.newInstance(realm, bankroll, startDate, type, stackingIn!!) + this.addAdditionallyCreatedIdentifiable(transaction) + } + + if (stackingOut != null && stackingOut != 0.0) { + val type = TransactionType.getByValue(TransactionType.Value.STACKING_OUTGOING, realm) + val transaction = Transaction.newInstance(realm, bankroll, startDate, type, stackingOut!!) + this.addAdditionallyCreatedIdentifiable(transaction) + } + return managedSession } else { Timber.d("Session already exists(count=$count): sd=$startDate, ed=$endDate, net=$net") diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt index 1550d399..4e1e2922 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt @@ -94,6 +94,17 @@ sealed class SessionField { override val numberFormat: String? = null ) : NumberCSVField + data class StackingIn( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField + + data class StackingOut( + override var header: String, + override var callback: ((String) -> Double?)? = null, + override val numberFormat: String? = null + ) : NumberCSVField data class Blind(override var header: String, override var callback: ((String) -> Pair?)? = null) : BlindCSVField diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e10b1f06..538c113d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -39,6 +39,8 @@ The item is used in one or more transactions…Please delete the linked transactions first Imported You\'ve reached the maximum number of free sessions. Please subscribe for unlimited use and don\'t hesitate to tell us how you feel about your current experience! + Stacking incoming + Stacking outgoing Address Naming suggestions diff --git a/app/src/test/java/net/pokeranalytics/android/SavableEnumTest.kt b/app/src/test/java/net/pokeranalytics/android/SavableEnumTest.kt index 13f1e6e7..4b58795e 100644 --- a/app/src/test/java/net/pokeranalytics/android/SavableEnumTest.kt +++ b/app/src/test/java/net/pokeranalytics/android/SavableEnumTest.kt @@ -1,7 +1,9 @@ package net.pokeranalytics.android +import com.google.android.libraries.places.internal.it import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.model.Criteria +import net.pokeranalytics.android.model.realm.TransactionType import org.junit.Assert import org.junit.Test @@ -16,6 +18,9 @@ class SavableEnumTest { val criteriaIds = Criteria.valuesInternal().map { it.uniqueIdentifier } Assert.assertEquals(criteriaIds.toSet().size, criteriaIds.size) + val transactionTypeValueIds = TransactionType.Value.valuesInternal().map { it.uniqueIdentifier } + Assert.assertEquals(transactionTypeValueIds.toSet().size, transactionTypeValueIds.size) + } } \ No newline at end of file