|
|
|
|
@ -1,11 +1,14 @@ |
|
|
|
|
package net.pokeranalytics.android.util.csv |
|
|
|
|
|
|
|
|
|
import io.realm.Realm |
|
|
|
|
import io.realm.RealmModel |
|
|
|
|
import net.pokeranalytics.android.model.Limit |
|
|
|
|
import net.pokeranalytics.android.model.TableSize |
|
|
|
|
import net.pokeranalytics.android.model.TournamentType |
|
|
|
|
import net.pokeranalytics.android.model.realm.Bankroll |
|
|
|
|
import net.pokeranalytics.android.model.realm.Session |
|
|
|
|
import net.pokeranalytics.android.model.realm.Transaction |
|
|
|
|
import net.pokeranalytics.android.model.realm.TransactionType |
|
|
|
|
import net.pokeranalytics.android.model.utils.SessionUtils |
|
|
|
|
import net.pokeranalytics.android.util.extensions.getOrCreate |
|
|
|
|
import net.pokeranalytics.android.util.extensions.setHourMinutes |
|
|
|
|
@ -83,7 +86,22 @@ sealed class SessionField { |
|
|
|
|
override val numberFormat: String? = null |
|
|
|
|
) : NumberCSVField |
|
|
|
|
|
|
|
|
|
data class Blind(override var header: String, override var callback: ((String) -> Pair<Double, Double>?)? = null) : BlindCSVField |
|
|
|
|
data class Rebuy( |
|
|
|
|
override var header: String, |
|
|
|
|
override var callback: ((String) -> Double?)? = null, |
|
|
|
|
override val numberFormat: String? = null |
|
|
|
|
) : NumberCSVField |
|
|
|
|
|
|
|
|
|
data class Addon( |
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
data class Game(override var header: String) : CSVField |
|
|
|
|
data class Location(override var header: String) : CSVField |
|
|
|
|
data class LocationType(override var header: String) : CSVField |
|
|
|
|
@ -118,7 +136,8 @@ sealed class SessionField { |
|
|
|
|
/** |
|
|
|
|
* A SessionCSVDescriptor is a CSVDescriptor specialized in parsing Session objects |
|
|
|
|
*/ |
|
|
|
|
class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean, vararg elements: CSVField) : DataCSVDescriptor<Session>(source, *elements) { |
|
|
|
|
class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean, vararg elements: CSVField) : |
|
|
|
|
DataCSVDescriptor<RealmModel>(source, *elements) { |
|
|
|
|
|
|
|
|
|
companion object { |
|
|
|
|
val pokerIncomeCash: CSVDescriptor = SessionCSVDescriptor( |
|
|
|
|
@ -142,17 +161,19 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean |
|
|
|
|
val pokerBankrollTracker: CSVDescriptor = SessionCSVDescriptor( |
|
|
|
|
DataSource.POKER_BANKROLL_TRACKER, |
|
|
|
|
true, |
|
|
|
|
SessionField.Start("starttime", dateFormat = "MM/dd/yyyy HH:mm"), |
|
|
|
|
SessionField.End("endtime", dateFormat = "MM/dd/yyyy HH:mm"), |
|
|
|
|
SessionField.Start("starttime", dateFormat = "MM/dd/yy HH:mm"), |
|
|
|
|
SessionField.End("endtime", dateFormat = "MM/dd/yy HH:mm"), |
|
|
|
|
SessionField.SessionType("variant"), |
|
|
|
|
SessionField.Buyin("buyin"), |
|
|
|
|
SessionField.CashedOut("cashout"), |
|
|
|
|
SessionField.Rebuy("rebuycosts"), |
|
|
|
|
SessionField.Addon("addoncosts"), |
|
|
|
|
SessionField.Break("breakminutes"), |
|
|
|
|
SessionField.LimitType("limit"), |
|
|
|
|
SessionField.Game("game"), |
|
|
|
|
SessionField.Bankroll("currency"), // same as currency code |
|
|
|
|
SessionField.Location("location"), |
|
|
|
|
SessionField.Comment("sessionnote"), |
|
|
|
|
SessionField.Location("type"), |
|
|
|
|
// SessionField.Comment("sessionnote"), |
|
|
|
|
SessionField.Tips("expensesfromstack"), |
|
|
|
|
SessionField.SmallBlind("smallblind"), |
|
|
|
|
SessionField.BigBlind("bigblind"), |
|
|
|
|
@ -209,7 +230,8 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean |
|
|
|
|
SessionField.LocationType("Location Type"), |
|
|
|
|
SessionField.Comment("Notes"), |
|
|
|
|
SessionField.CurrencyCode("Currency"), |
|
|
|
|
SessionField.Blind("Stakes", callback = { value -> // $10/20 |
|
|
|
|
SessionField.Blind("Stakes", callback = { value -> |
|
|
|
|
// $10/20 |
|
|
|
|
value.drop(1) |
|
|
|
|
val blinds = value.split("/") |
|
|
|
|
if (blinds.size == 2) { |
|
|
|
|
@ -222,10 +244,90 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private enum class DataType { |
|
|
|
|
TRANSACTION, |
|
|
|
|
SESSION; |
|
|
|
|
|
|
|
|
|
companion object { |
|
|
|
|
|
|
|
|
|
fun valueForString(type: String): DataType? { |
|
|
|
|
return when (type) { |
|
|
|
|
"Deposit/Payout" -> TRANSACTION |
|
|
|
|
"Cash Game", "Tournament" -> SESSION |
|
|
|
|
else -> null |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Parses a [record] and return an optional Session |
|
|
|
|
*/ |
|
|
|
|
override fun parseData(realm: Realm, record: CSVRecord): Session? { |
|
|
|
|
override fun parseData(realm: Realm, record: CSVRecord): RealmModel? { |
|
|
|
|
|
|
|
|
|
var dataType: DataType? = null |
|
|
|
|
val typeField = fields.firstOrNull { it is SessionField.SessionType } |
|
|
|
|
typeField?.let { field -> |
|
|
|
|
this.fieldMapping[field]?.let { index -> |
|
|
|
|
val typeValue = record.get(index) |
|
|
|
|
dataType = DataType.valueForString(typeValue) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return when (dataType) { |
|
|
|
|
DataType.TRANSACTION -> parseTransaction(realm, record) |
|
|
|
|
else -> parseSession(realm, record) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun parseTransaction(realm: Realm, record: CSVRecord): Transaction? { |
|
|
|
|
|
|
|
|
|
var date: Date? = null |
|
|
|
|
var amount: Double? = null |
|
|
|
|
var type: TransactionType? = null |
|
|
|
|
var currencyCode: String? = null |
|
|
|
|
var currencyRate: Double? = null |
|
|
|
|
|
|
|
|
|
fields.forEach { field -> |
|
|
|
|
|
|
|
|
|
val index = this.fieldMapping[field] |
|
|
|
|
if (index != null) { |
|
|
|
|
val value = record.get(index) |
|
|
|
|
when (field) { |
|
|
|
|
is SessionField.Start -> { |
|
|
|
|
date = field.parse(value) |
|
|
|
|
} |
|
|
|
|
is SessionField.Buyin -> amount = field.parse(value) |
|
|
|
|
is SessionField.SessionType -> { |
|
|
|
|
type = realm.getOrCreate(value) |
|
|
|
|
} |
|
|
|
|
is SessionField.CurrencyCode -> currencyCode = value |
|
|
|
|
is SessionField.CurrencyRate -> currencyRate = field.parse(value) |
|
|
|
|
else -> { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (date != null && amount != null && type != null && currencyCode != null) { |
|
|
|
|
|
|
|
|
|
val transaction = realm.copyToRealm(Transaction()) |
|
|
|
|
transaction.date = date!! |
|
|
|
|
transaction.amount = amount!! |
|
|
|
|
transaction.type = type |
|
|
|
|
|
|
|
|
|
val bankroll = Bankroll.getOrCreate(realm, currencyCode!!, currencyRate = currencyRate) |
|
|
|
|
transaction.bankroll = bankroll |
|
|
|
|
|
|
|
|
|
return transaction |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return null |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun parseSession(realm: Realm, record: CSVRecord): Session? { |
|
|
|
|
|
|
|
|
|
val session = Session.newInstance(realm, this.isTournament) |
|
|
|
|
|
|
|
|
|
@ -233,6 +335,7 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean |
|
|
|
|
var bankrollName: String? = null |
|
|
|
|
var currencyCode: String? = null |
|
|
|
|
var currencyRate: Double? = null |
|
|
|
|
var additionalBuyins = 0.0 // rebuy + addon |
|
|
|
|
|
|
|
|
|
fields.forEach { field -> |
|
|
|
|
|
|
|
|
|
@ -246,18 +349,34 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean |
|
|
|
|
is SessionField.End -> { |
|
|
|
|
session.endDate = field.parse(value) |
|
|
|
|
} |
|
|
|
|
is SessionField.StartTime -> { session.startDate?.setHourMinutes(value) } |
|
|
|
|
is SessionField.EndTime -> { session.endDate?.setHourMinutes(value) } |
|
|
|
|
is SessionField.StartTime -> { |
|
|
|
|
session.startDate?.setHourMinutes(value) |
|
|
|
|
} |
|
|
|
|
is SessionField.EndTime -> { |
|
|
|
|
session.endDate?.setHourMinutes(value) |
|
|
|
|
} |
|
|
|
|
is SessionField.Buyin -> session.result?.buyin = field.parse(value) |
|
|
|
|
is SessionField.CashedOut -> session.result?.cashout = field.parse(value) |
|
|
|
|
is SessionField.Addon -> additionalBuyins += field.parse(value) ?: 0.0 |
|
|
|
|
is SessionField.Rebuy -> additionalBuyins += field.parse(value) ?: 0.0 |
|
|
|
|
is SessionField.Tips -> session.result?.tips = field.parse(value) |
|
|
|
|
is SessionField.Break -> { |
|
|
|
|
field.parse(value)?.let { |
|
|
|
|
session.breakDuration = it.toLong() * 60 * 1000 |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
is SessionField.Game -> session.game = realm.getOrCreate(value) |
|
|
|
|
is SessionField.Location -> session.location = realm.getOrCreate(value) |
|
|
|
|
is SessionField.Game -> { |
|
|
|
|
if (value.isNotEmpty()) { |
|
|
|
|
session.game = realm.getOrCreate(value) |
|
|
|
|
} else { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
is SessionField.Location -> { |
|
|
|
|
if (value.isNotEmpty()) { |
|
|
|
|
session.location = realm.getOrCreate(value) |
|
|
|
|
} else { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
is SessionField.Bankroll -> bankrollName = value |
|
|
|
|
is SessionField.LimitType -> session.limit = Limit.getInstance(value)?.ordinal |
|
|
|
|
is SessionField.Comment -> session.comment = value |
|
|
|
|
@ -274,16 +393,24 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean |
|
|
|
|
session.type = type.ordinal |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
is SessionField.TournamentPosition -> session.result?.tournamentFinalPosition = field.parse(value)?.toInt() |
|
|
|
|
is SessionField.TournamentPosition -> session.result?.tournamentFinalPosition = |
|
|
|
|
field.parse(value)?.toInt() |
|
|
|
|
is SessionField.TournamentName -> session.tournamentName = realm.getOrCreate(value) |
|
|
|
|
is SessionField.TournamentType -> session.tournamentType = TournamentType.getValueForLabel(value)?.ordinal |
|
|
|
|
is SessionField.TournamentNumberOfPlayers -> session.tournamentNumberOfPlayers = field.parse(value)?.toInt() |
|
|
|
|
is SessionField.TournamentType -> session.tournamentType = |
|
|
|
|
TournamentType.getValueForLabel(value)?.ordinal |
|
|
|
|
is SessionField.TournamentNumberOfPlayers -> session.tournamentNumberOfPlayers = |
|
|
|
|
field.parse(value)?.toInt() |
|
|
|
|
is SessionField.CurrencyCode -> currencyCode = value |
|
|
|
|
is SessionField.CurrencyRate -> currencyRate = field.parse(value) |
|
|
|
|
else -> { } |
|
|
|
|
else -> { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (bankrollName.isNullOrEmpty()) { |
|
|
|
|
bankrollName = "Import" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
session.bankroll = Bankroll.getOrCreate(realm, bankrollName ?: "Import", isLive, currencyCode, currencyRate) |
|
|
|
|
@ -291,13 +418,18 @@ class SessionCSVDescriptor(source: DataSource, private var isTournament: Boolean |
|
|
|
|
val startDate = session.startDate |
|
|
|
|
val endDate = session.endDate |
|
|
|
|
val net = session.result?.net |
|
|
|
|
session.result?.buyin?.let { |
|
|
|
|
session.result?.buyin = it + additionalBuyins |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return if (startDate != null && endDate != null && net != null) { // valid session |
|
|
|
|
val unique = SessionUtils.unicityCheck(realm, startDate, endDate, net) |
|
|
|
|
if (unique) session else null |
|
|
|
|
} else { // invalid session |
|
|
|
|
null |
|
|
|
|
if (startDate != null && endDate != null && net != null) { // valid session |
|
|
|
|
if (SessionUtils.unicityCheck(realm, startDate, endDate, net)) { |
|
|
|
|
return session |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
session.deleteFromRealm() |
|
|
|
|
return null |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|