Skip to content

Commit

Permalink
Add aggregationPeriod config param for ChartSpec
Browse files Browse the repository at this point in the history
  • Loading branch information
nymanjens committed Nov 1, 2024
1 parent 84f4eaa commit 590ba01
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ object ChartSpecTest extends TestSuite {
ChartSpec.parseStringified(chartSpec.stringify) ==> chartSpec
}
"singleEmptyLine" - {
testRoundTrip(ChartSpec.singleEmptyLine(correctForInflation = false))
testRoundTrip(ChartSpec.singleEmptyLine())
}
"single non-empty line" - {
testRoundTrip(
ChartSpec(
Seq(Line(name = "DEF@GHI", query = "ABC", inverted = true, cumulative = true)),
correctForInflation = true,
aggregationPeriod = ChartSpec.AggregationPeriod.Month,
)
)
}
Expand All @@ -37,6 +38,7 @@ object ChartSpecTest extends TestSuite {
Line(name = "", query = ""),
),
correctForInflation = false,
aggregationPeriod = ChartSpec.AggregationPeriod.Year,
)
)
}
Expand Down
12 changes: 10 additions & 2 deletions app/jvm/src/main/scala/app/models/accounting/config/Parsable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -234,13 +234,21 @@ object Parsable {
}
}
object PredefinedChart {
case class ChartSpec(lines: java.util.List[ChartSpec.Line], correctForInflation: Boolean) {
def this() = this(lines = null, correctForInflation = false)
case class ChartSpec(
lines: java.util.List[ChartSpec.Line],
correctForInflation: Boolean,
aggregationPeriod: String,
) {
def this() = this(lines = null, correctForInflation = false, aggregationPeriod = "Month")

def parse(): ParsedChartSpec = {
ParsedChartSpec(
lines = lines.asScala.toVector.map(_.parse),
correctForInflation = correctForInflation,
aggregationPeriod = aggregationPeriod match {
case "Month" => ParsedChartSpec.AggregationPeriod.Month
case "Year" => ParsedChartSpec.AggregationPeriod.Year
},
)
}
}
Expand Down
12 changes: 11 additions & 1 deletion app/shared/src/main/scala/app/api/Picklers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,21 @@ object Picklers extends StandardPicklers {
override def pickle(value: ChartSpec)(implicit state: PickleState): Unit = logExceptions {
state.pickle(value.lines)
state.pickle(value.correctForInflation)
state.pickle(value.aggregationPeriod)
}
override def unpickle(implicit state: UnpickleState): ChartSpec = logExceptions {
ChartSpec(state.unpickle[Seq[ChartSpec.Line]], state.unpickle[Boolean])
ChartSpec(
state.unpickle[Seq[ChartSpec.Line]],
state.unpickle[Boolean],
state.unpickle[ChartSpec.AggregationPeriod],
)
}
}
implicit val chartSpecAggregationPeriodPickler: Pickler[ChartSpec.AggregationPeriod] =
enumPickler(
_.getClass.getSimpleName,
Seq(ChartSpec.AggregationPeriod.Month, ChartSpec.AggregationPeriod.Year),
)

override implicit val entityPickler: Pickler[Entity] = compositePickler[Entity]
.addConcreteType[User]
Expand Down
59 changes: 46 additions & 13 deletions app/shared/src/main/scala/app/common/accounting/ChartSpec.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package app.common.accounting

import app.common.accounting.ChartSpec.AggregationPeriod
import app.common.accounting.ChartSpec.Line
import hydro.common.GuavaReplacement.Splitter
import hydro.common.ScalaUtils
Expand All @@ -9,6 +10,7 @@ import scala.collection.immutable.Seq
case class ChartSpec(
lines: Seq[Line],
correctForInflation: Boolean,
aggregationPeriod: AggregationPeriod,
) {
def withAddedEmptyLine: ChartSpec = {
copy(lines = lines :+ Line.empty)
Expand All @@ -20,34 +22,59 @@ case class ChartSpec(
copy(lines = mutableLines.toVector)
}

def modified(index: Int, modification: Line => Line) = {
def modified(index: Int, modification: Line => Line): ChartSpec = {
copy(lines = lines.updated(index, modification(lines(index))))
}

def stringify: String = {
val inflationSuffix = if (correctForInflation) "+I" else "-I"
lines.map(_.stringify).mkString(String.valueOf(ChartSpec.lineDelimiter)) + inflationSuffix
val periodSuffix = aggregationPeriod match {
case AggregationPeriod.Month => "<>M"
case AggregationPeriod.Year => "<>Y"
}
lines.map(_.stringify).mkString(String.valueOf(ChartSpec.lineDelimiter)) + inflationSuffix + periodSuffix
}
}
object ChartSpec {
def singleEmptyLine() =
ChartSpec(lines = Seq(Line.empty), correctForInflation = false)
def singleEmptyLine(): ChartSpec =
ChartSpec(
lines = Seq(Line.empty),
correctForInflation = false,
aggregationPeriod = AggregationPeriod.Month,
)

private val lineDelimiter = '~'

def parseStringified(string: String): ChartSpec = {
val correctForInflation = if (string.endsWith("+I")) {
true
} else if (string.endsWith("-I")) {
false
} else {
throw new AssertionError(string)
var stringRemainder = string
val aggregationPeriod =
if (stringRemainder.contains("<>")) {
val suffix = stringRemainder.substring(stringRemainder.length - 3)
stringRemainder = stringRemainder.substring(0, stringRemainder.length - 3)
suffix match {
case "<>M" => AggregationPeriod.Month
case "<>Y" => AggregationPeriod.Year
}
} else {
AggregationPeriod.Month
}
val correctForInflation = {
val suffix = stringRemainder.substring(stringRemainder.length - 2)
stringRemainder = stringRemainder.substring(0, stringRemainder.length - 2)
suffix match {
case "+I" => true
case "-I" => false
}
}
val stringRemainder = string.substring(0, string.length - 2)

val lines = Splitter.on(lineDelimiter).split(stringRemainder).map(Line.parseStringified)
if (lines.nonEmpty) ChartSpec(lines, correctForInflation)
else ChartSpec.singleEmptyLine().copy(correctForInflation = correctForInflation)
if (lines.nonEmpty) {
ChartSpec(lines, correctForInflation, aggregationPeriod)
} else {
ChartSpec
.singleEmptyLine()
.copy(correctForInflation = correctForInflation, aggregationPeriod = aggregationPeriod)
}
}

case class Line(
Expand Down Expand Up @@ -94,4 +121,10 @@ object ChartSpec {
)
}
}

sealed trait AggregationPeriod
object AggregationPeriod {
object Month extends AggregationPeriod
object Year extends AggregationPeriod
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ object TestObjects {
)
),
correctForInflation = false,
aggregationPeriod = ChartSpec.AggregationPeriod.Month,
),
)
),
Expand Down
2 changes: 2 additions & 0 deletions conf/demo-accounting-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ templates:
predefinedCharts:
- name: "Alice's transactions"
chartSpec:
correctForInflation: false
aggregationPeriod: Month # "Month" or "Year"
lines:
- name: "Alice's transactions"
query: "beneficiary:Alice"
Expand Down

0 comments on commit 590ba01

Please sign in to comment.