Add new transaction types for stacking, as well as support for it in the PBT import

csv
Laurent 6 years ago
parent cdf38e1716
commit 4fbcae37fd
  1. 16
      app/src/main/AndroidManifest.xml
  2. 13
      app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt
  3. 11
      app/src/main/java/net/pokeranalytics/android/model/realm/Transaction.kt
  4. 40
      app/src/main/java/net/pokeranalytics/android/model/realm/TransactionType.kt
  5. 31
      app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt
  6. 29
      app/src/main/java/net/pokeranalytics/android/ui/fragment/FeedFragment.kt
  7. 4
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/SettingRow.kt
  8. 3
      app/src/main/java/net/pokeranalytics/android/util/Preferences.kt
  9. 4
      app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt
  10. 2
      app/src/main/java/net/pokeranalytics/android/util/csv/ProductCSVDescriptors.kt
  11. 56
      app/src/main/java/net/pokeranalytics/android/util/csv/SessionCSVDescriptor.kt
  12. 11
      app/src/main/java/net/pokeranalytics/android/util/csv/SessionField.kt
  13. 2
      app/src/main/res/values/strings.xml
  14. 5
      app/src/test/java/net/pokeranalytics/android/SavableEnumTest.kt

@ -39,16 +39,16 @@
android:screenOrientation="portrait"
android:launchMode="singleTop">
<!--<intent-filter tools:ignore="AppLinkUrlError">-->
<!--<action android:name="android.intent.action.VIEW" />-->
<!--<category android:name="android.intent.category.DEFAULT" />-->
<intent-filter tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<!--<data android:scheme="file" />-->
<!--<data android:scheme="content" />-->
<!--<data android:mimeType="text/comma-separated-values" />-->
<!--<data android:mimeType="text/csv" />-->
<data android:scheme="file" />
<data android:scheme="content" />
<data android:mimeType="text/comma-separated-values" />
<data android:mimeType="text/csv" />
<!--</intent-filter>-->
</intent-filter>
</activity>

@ -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() {

@ -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<RowRepresentable> by lazy {
val rows = ArrayList<RowRepresentable>()
rows.addAll(TransactionRow.values())

@ -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<Value> {
override fun valuesInternal(): Array<Value> {
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

@ -12,11 +12,29 @@ import java.util.*
class Seed(var context:Context) : Realm.Transaction {
companion object {
fun createDefaultTransactionTypes(values: Array<TransactionType.Value>, 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)
}
}
}

@ -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)
}

@ -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))

@ -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 {

@ -40,6 +40,10 @@ abstract class DataCSVDescriptor<T : Identifiable>(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) {

@ -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")
)

@ -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")

@ -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<Double, Double>?)? = null) :
BlindCSVField

@ -39,6 +39,8 @@
<string name="transaction_relationship_error">The item is used in one or more transactions&#8230;Please delete the linked transactions first</string>
<string name="imported">Imported</string>
<string name="iap_session_message">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!</string>
<string name="stacking_incoming">Stacking incoming</string>
<string name="stacking_outgoing">Stacking outgoing</string>
<string name="address">Address</string>
<string name="suggestions">Naming suggestions</string>

@ -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)
}
}
Loading…
Cancel
Save