package com.linxberg.ta.core.business.rules
import com.linxberg.ta.core.business.Context
import com.linxberg.ta.core.business.TimeInterval
import com.linxberg.ta.core.entities.PayPolicy
import com.linxberg.ta.core.business.TimeInterval
import com.linxberg.ta.core.business.TimeInterval._
import com.linxberg.ta.core.util.Grapher
import org.scala_tools.time.Imports._
import org.joda.time.Duration
object DailyOT extends Rule {
override val fnDesc: String = "Daily overtime"
override val activityCode: String = "OT"
override def applyRuleTo(ctx: Context) = {
val pp = ctx("PP"): PayPolicy
val days = ctx("BD"): List[TimeInterval]
def calc(list: List[TimeInterval], code:String, hoursThreshold:Int) =
if (hoursThreshold > 0)
list.zip(list.scanLeft(Duration.ZERO)(_ + _.interval.duration)).collect {
case (ti, tot) if tot > hoursThreshold.hours => ti.withCode(code)
case (ti, tot) if tot + ti.interval.duration > hoursThreshold.hours => {
val diffPtv = (tot + ti.interval.duration) - hoursThreshold.hours
TimeInterval(code, ti.end - diffPtv, ti.end)
}
}
else
Nil
def mergeVectors(v1:List[TimeInterval], v2:List[TimeInterval]) = {
val (part1, part2) = v1.partition(ot=> !v2.exists(_ ∩? ot))
val intersect = if (part2.nonEmpty && v2.nonEmpty) {
val (first,second) = (part2.head, v2.head)
if (!(first ≡ second))
Seq(TimeInterval(first.code, first.start, (first ∩ second).start))
else
Nil
}
else Nil
part1 ++ intersect ++ v2
}
val state = if (pp.otDayHours > 0)
days.foldLeft(Nil: List[TimeInterval]) { (result, e) =>
val allProds = e.children.flatMap(_.children)
result ++ Seq(calc(allProds, "OT1", pp.otDayHours),
calc(allProds, "OT2", pp.ot2DayHours),
calc(allProds, "OT3", pp.ot3DayHours)).reduceLeft(mergeVectors)
}
else
Nil
ctx + Map("OT1"->Nil, "OT2"->Nil, "OT3"->Nil) + state.groupBy(_.code)
}
}