|
|
|
@ -27,11 +27,11 @@ import kotlin.math.min |
|
|
|
class Calculator { |
|
|
|
class Calculator { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* The options used for calculations or display |
|
|
|
* The options used for calculations and display |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
class Options( |
|
|
|
class Options( |
|
|
|
var display: Display = Display.TABLE, |
|
|
|
var display: Display = Display.TABLE, |
|
|
|
evolutionValues: EvolutionValues = EvolutionValues.NONE, |
|
|
|
progressValues: ProgressValues = ProgressValues.NONE, |
|
|
|
var stats: List<Stat> = listOf(), |
|
|
|
var stats: List<Stat> = listOf(), |
|
|
|
var criterias: List<Criteria> = listOf(), |
|
|
|
var criterias: List<Criteria> = listOf(), |
|
|
|
query: Query = Query(), |
|
|
|
query: Query = Query(), |
|
|
|
@ -41,14 +41,20 @@ class Calculator { |
|
|
|
var reportSetupId: String? = null |
|
|
|
var reportSetupId: String? = null |
|
|
|
) { |
|
|
|
) { |
|
|
|
|
|
|
|
|
|
|
|
var evolutionValues: EvolutionValues = evolutionValues |
|
|
|
/** |
|
|
|
|
|
|
|
* Specifies whether progress values should be added and their kind |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
var progressValues: ProgressValues = progressValues |
|
|
|
get() { |
|
|
|
get() { |
|
|
|
if (field == EvolutionValues.NONE && this.display == Display.PROGRESS) { |
|
|
|
if (field == ProgressValues.NONE && this.display == Display.PROGRESS) { |
|
|
|
return EvolutionValues.STANDARD |
|
|
|
return ProgressValues.STANDARD |
|
|
|
} |
|
|
|
} |
|
|
|
return field |
|
|
|
return field |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* The query used to filter data |
|
|
|
|
|
|
|
*/ |
|
|
|
private var _query: Query = query |
|
|
|
private var _query: Query = query |
|
|
|
|
|
|
|
|
|
|
|
init { |
|
|
|
init { |
|
|
|
@ -56,14 +62,14 @@ class Calculator { |
|
|
|
throw IllegalStateException("Can't specify a query with conditions AND a filter") |
|
|
|
throw IllegalStateException("Can't specify a query with conditions AND a filter") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
when (this.aggregationType) { |
|
|
|
this.aggregationType?.let { |
|
|
|
AggregationType.MONTH -> this.criterias = listOf(Criteria.AllMonthsUpToNow) |
|
|
|
this.criterias = it.criterias |
|
|
|
AggregationType.YEAR -> this.criterias = listOf(Criteria.Years) |
|
|
|
|
|
|
|
else -> {} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* The query used, either filter query or the provided query |
|
|
|
|
|
|
|
*/ |
|
|
|
val query: Query |
|
|
|
val query: Query |
|
|
|
get() { |
|
|
|
get() { |
|
|
|
this.filter?.let { |
|
|
|
this.filter?.let { |
|
|
|
@ -73,7 +79,7 @@ class Calculator { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* The way the statIds are going to be displayed |
|
|
|
* The way the computed stats are going to be displayed |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
enum class Display : RowRepresentable { |
|
|
|
enum class Display : RowRepresentable { |
|
|
|
TABLE, |
|
|
|
TABLE, |
|
|
|
@ -105,13 +111,12 @@ class Calculator { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* The type of evolution numericValues |
|
|
|
* The type of evolution numericValues |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
enum class EvolutionValues { |
|
|
|
enum class ProgressValues { |
|
|
|
NONE, |
|
|
|
NONE, |
|
|
|
STANDARD, |
|
|
|
STANDARD, |
|
|
|
TIMED |
|
|
|
TIMED |
|
|
|
@ -130,23 +135,37 @@ class Calculator { |
|
|
|
return false |
|
|
|
return false |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Whether the longest streaks should be computed |
|
|
|
|
|
|
|
*/ |
|
|
|
val computeLongestStreak: Boolean |
|
|
|
val computeLongestStreak: Boolean |
|
|
|
get() { |
|
|
|
get() { |
|
|
|
return this.stats.contains(LONGEST_STREAKS) |
|
|
|
return this.stats.contains(LONGEST_STREAKS) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Whether the values should be sorted |
|
|
|
|
|
|
|
*/ |
|
|
|
val shouldSortValues: Boolean |
|
|
|
val shouldSortValues: Boolean |
|
|
|
get() { |
|
|
|
get() { |
|
|
|
return this.evolutionValues != EvolutionValues.NONE || this.computeLongestStreak |
|
|
|
return this.progressValues != ProgressValues.NONE || this.computeLongestStreak |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Whether the number of locations played should be computed |
|
|
|
|
|
|
|
*/ |
|
|
|
val computeLocationsPlayed: Boolean |
|
|
|
val computeLocationsPlayed: Boolean |
|
|
|
get() { |
|
|
|
get() { |
|
|
|
return this.stats.contains(LOCATIONS_PLAYED) |
|
|
|
return this.stats.contains(LOCATIONS_PLAYED) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Whether the number of days played should be computed |
|
|
|
|
|
|
|
*/ |
|
|
|
val computeDaysPlayed: Boolean |
|
|
|
val computeDaysPlayed: Boolean |
|
|
|
get() { |
|
|
|
get() { |
|
|
|
return this.stats.contains(DAYS_PLAYED) |
|
|
|
return this.stats.contains(DAYS_PLAYED) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Whether progress values should be managed at the group level |
|
|
|
|
|
|
|
*/ |
|
|
|
val shouldManageMultiGroupProgressValues: Boolean |
|
|
|
val shouldManageMultiGroupProgressValues: Boolean |
|
|
|
get() { |
|
|
|
get() { |
|
|
|
return if (this.aggregationType != null) { |
|
|
|
return if (this.aggregationType != null) { |
|
|
|
@ -178,13 +197,15 @@ class Calculator { |
|
|
|
stats: List<Stat>? = null |
|
|
|
stats: List<Stat>? = null |
|
|
|
): Report { |
|
|
|
): Report { |
|
|
|
|
|
|
|
|
|
|
|
val options = Options(display = Options.Display.PROGRESS, |
|
|
|
val options = Options( |
|
|
|
evolutionValues = Options.EvolutionValues.STANDARD, |
|
|
|
display = Options.Display.PROGRESS, |
|
|
|
|
|
|
|
progressValues = Options.ProgressValues.STANDARD, |
|
|
|
stats = listOf(stat), |
|
|
|
stats = listOf(stat), |
|
|
|
aggregationType = aggregationType) |
|
|
|
aggregationType = aggregationType |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
if (aggregationType == AggregationType.DURATION) { |
|
|
|
if (aggregationType == AggregationType.DURATION) { |
|
|
|
options.evolutionValues = Options.EvolutionValues.TIMED |
|
|
|
options.progressValues = Options.ProgressValues.TIMED |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
stats?.let { |
|
|
|
stats?.let { |
|
|
|
@ -227,7 +248,7 @@ class Calculator { |
|
|
|
|
|
|
|
|
|
|
|
val report = Report(options) |
|
|
|
val report = Report(options) |
|
|
|
groups.forEach { group -> |
|
|
|
groups.forEach { group -> |
|
|
|
// val s = Date() |
|
|
|
// val s = Date() |
|
|
|
|
|
|
|
|
|
|
|
// Clean existing computables / sessionSets if group is reused |
|
|
|
// Clean existing computables / sessionSets if group is reused |
|
|
|
group.cleanup() |
|
|
|
group.cleanup() |
|
|
|
@ -325,7 +346,7 @@ class Calculator { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
val shouldIterateOverComputables = |
|
|
|
val shouldIterateOverComputables = |
|
|
|
(options.evolutionValues == Options.EvolutionValues.STANDARD || options.computeLongestStreak) |
|
|
|
(options.progressValues == Options.ProgressValues.STANDARD || options.computeLongestStreak) |
|
|
|
|
|
|
|
|
|
|
|
// Computable Result |
|
|
|
// Computable Result |
|
|
|
if (shouldIterateOverComputables) { |
|
|
|
if (shouldIterateOverComputables) { |
|
|
|
@ -419,7 +440,7 @@ class Calculator { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
val shouldIterateOverSets = computableGroup.conditions.isNotEmpty() || |
|
|
|
val shouldIterateOverSets = computableGroup.conditions.isNotEmpty() || |
|
|
|
options.evolutionValues != Options.EvolutionValues.NONE || |
|
|
|
options.progressValues != Options.ProgressValues.NONE || |
|
|
|
options.computeDaysPlayed |
|
|
|
options.computeDaysPlayed |
|
|
|
|
|
|
|
|
|
|
|
// Session Set |
|
|
|
// Session Set |
|
|
|
@ -450,8 +471,8 @@ class Calculator { |
|
|
|
tHourlyRateBB = tBBSum / tHourlyDuration |
|
|
|
tHourlyRateBB = tBBSum / tHourlyDuration |
|
|
|
daysSet.add(sessionSet.startDate.startOfDay()) |
|
|
|
daysSet.add(sessionSet.startDate.startOfDay()) |
|
|
|
|
|
|
|
|
|
|
|
when (options.evolutionValues) { |
|
|
|
when (options.progressValues) { |
|
|
|
Options.EvolutionValues.STANDARD -> { |
|
|
|
Options.ProgressValues.STANDARD -> { |
|
|
|
results.addEvolutionValue(tHourlyRate, stat = HOURLY_RATE, data = sessionSet) |
|
|
|
results.addEvolutionValue(tHourlyRate, stat = HOURLY_RATE, data = sessionSet) |
|
|
|
results.addEvolutionValue(tIndex.toDouble(), stat = NUMBER_OF_SETS, data = sessionSet) |
|
|
|
results.addEvolutionValue(tIndex.toDouble(), stat = NUMBER_OF_SETS, data = sessionSet) |
|
|
|
results.addEvolutionValue( |
|
|
|
results.addEvolutionValue( |
|
|
|
@ -472,7 +493,7 @@ class Calculator { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
Options.EvolutionValues.TIMED -> { |
|
|
|
Options.ProgressValues.TIMED -> { |
|
|
|
results.addEvolutionValue(tRatedNetSum, tHourlyDuration, NET_RESULT, sessionSet) |
|
|
|
results.addEvolutionValue(tRatedNetSum, tHourlyDuration, NET_RESULT, sessionSet) |
|
|
|
results.addEvolutionValue(tHourlyRate, tHourlyDuration, HOURLY_RATE, sessionSet) |
|
|
|
results.addEvolutionValue(tHourlyRate, tHourlyDuration, HOURLY_RATE, sessionSet) |
|
|
|
results.addEvolutionValue( |
|
|
|
results.addEvolutionValue( |
|
|
|
|