Methods and tests for reversing effectivity periods
authorGeorgios Gousios <gousiosg@gmail.com>
Mon, 28 Nov 2011 12:29:03 +0000 (14:29 +0200)
committerGeorgios Gousios <gousiosg@gmail.com>
Mon, 28 Nov 2011 12:29:03 +0000 (14:29 +0200)
logic/src/main/scala/gr/grnet/aquarium/logic/accounting/Accounting.scala
logic/src/main/scala/gr/grnet/aquarium/logic/accounting/dsl/DSLUtils.scala
logic/src/test/scala/gr/grnet/aquarium/logic/test/DSLUtilsTest.scala

index 31eebae..4a3d26a 100644 (file)
@@ -35,7 +35,7 @@
 
 package gr.grnet.aquarium.logic.accounting
 
-import dsl.{DSLPolicy, DSLAgreement, DSLPriceList, DSLAlgorithm}
+import dsl._
 import gr.grnet.aquarium.logic.events.ResourceEvent
 import com.ckkloverdos.maybe.{Failed, Just, Maybe}
 import java.util.Date
@@ -45,7 +45,7 @@ import java.util.Date
  *
  * @author Georgios Gousios <gousiosg@gmail.com>
  */
-trait Accounting {
+trait Accounting extends DSLUtils {
 
   def chargeEvent(ev: ResourceEvent) : Maybe[Float] = {
 
@@ -67,9 +67,11 @@ trait Accounting {
     }
   }
 
-  def calcChangeChunks(agr: DSLAgreement, value: Float,
+  def calcChangeChunks(agr: DSLAgreement, volume: Float,
                        from: Date, to: Date) : List[ChargeChunk] = {
 
+    val prts = allEffectiveTimeslots(agr.pricelist.effective, from, to)
+
     
 
     List()
index 19c6273..1b68198 100644 (file)
@@ -36,7 +36,7 @@
 package gr.grnet.aquarium.logic.accounting.dsl
 
 import gr.grnet.aquarium.util.DateUtils
-import java.util.{GregorianCalendar, Calendar, Date}
+import java.util.{Date, GregorianCalendar, Calendar}
 
 /**
  * Utility functions to use when working with DSL types.
@@ -46,6 +46,29 @@ import java.util.{GregorianCalendar, Calendar, Date}
 trait DSLUtils extends DateUtils {
 
   /**
+   * Get a list of timeslots within which a timeframe is not effective.
+   */
+  def ineffectiveTimeslots(spec: DSLTimeFrameRepeat, from: Date, to: Option[Date]):
+    List[(Date, Date)] = {
+
+    buildNotEffectiveList(effectiveTimeslots(spec, from, to)) sortWith sorter
+  }
+
+  private def buildNotEffectiveList(l :List[(Date, Date)]) :
+    List[(Date, Date)] = {
+
+    if (l.isEmpty) return List()
+    if (l.tail.isEmpty) return List()
+
+    assert(l.head._2.getTime < l.tail.head._1.getTime)
+
+    List[(Date, Date)]() ++
+      List((new Date(l.head._2.getTime + 1),
+        new Date(l.tail.head._1.getTime - 1))) ++
+      buildNotEffectiveList(l.tail)
+  }
+
+  /**
    * Get a list of all timeslots within which a timeframe
    * is effective.
    */
@@ -78,8 +101,10 @@ trait DSLUtils extends DateUtils {
     coExpandTimespecs(spec.start.zip(spec.end), from, endDate) sortWith sorter
   }
 
-  
-  private def sorter(x: (Date, Date), y: (Date, Date)) : Boolean =
+  /**
+   * Utility function to put timeslots in increasing start timestamp order
+   */
+  def sorter(x: (Date, Date), y: (Date, Date)) : Boolean =
     if (y._1 after x._1) true else false
 
   /**
index 4def03c..2157bec 100644 (file)
@@ -138,6 +138,42 @@ class DSLUtilsTest extends DSLUtils with TestMethods with DSL {
     testSuccessiveTimeslots(result)
   }
 
+  @Test
+  def testNonEffectiveTimeslots = {
+    val from =  new Date(1321621969000L) //Fri Nov 18 15:12:49 +0200 2011
+    val to =  new Date(1324214719000L)   //Sun Dec 18 15:25:19 +0200 2011
+
+    var repeat = DSLTimeFrameRepeat(parseCronString("00 12 * * *"),
+      parseCronString("00 14 * * *"))
+
+    var result = ineffectiveTimeslots(repeat, from, Some(to))
+    assertEquals(30, result.size)
+    testSuccessiveTimeslots(result)
+    printTimeslots(result)
+  }
+
+  @Test
+  def testTimeContinuum : Unit = {
+    val from =  new Date(1321621969000L) //Fri Nov 18 15:12:49 +0200 2011
+    val to =  new Date(1324214719000L)   //Sun Dec 18 15:25:19 +0200 2011
+
+    var repeat = DSLTimeFrameRepeat(parseCronString("00 12 * * *"),
+      parseCronString("00 14 * * *"))
+
+    val continuum = effectiveTimeslots(repeat, from, Some(to)) ++
+      ineffectiveTimeslots(repeat, from, Some(to)) sortWith sorter
+
+    testSuccessiveTimeslots(continuum)
+
+    continuum.reduce {
+      (a,b) =>
+        if(a._2.getTime - b._1.getTime > 1)
+          fail("Effectivity timeslots leave gaps: %s %s".format(a, b))
+        a
+    }
+    return
+  }
+
   @tailrec
   private def testSuccessiveTimeslots(result: List[(Date, Date)]): Unit = {
     if (result.isEmpty) return