69ca62e7e94d4d75d8ce461af7bd05ae6a4419b0
[aquarium] / src / main / scala / gr / grnet / aquarium / computation / BillingMonthInfo.scala
1 /*
2  * Copyright 2011-2012 GRNET S.A. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above
9  *      copyright notice, this list of conditions and the following
10  *      disclaimer.
11  *
12  *   2. Redistributions in binary form must reproduce the above
13  *      copyright notice, this list of conditions and the following
14  *      disclaimer in the documentation and/or other materials
15  *      provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  *
30  * The views and conclusions contained in the software and
31  * documentation are those of the authors and should not be
32  * interpreted as representing official policies, either expressed
33  * or implied, of GRNET S.A.
34  */
35
36 package gr.grnet.aquarium.computation
37
38 import gr.grnet.aquarium.util.shortClassNameOf
39 import gr.grnet.aquarium.util.date.{TimeHelpers, MutableDateCalc}
40
41 /**
42  * Provides information about the billing month and related calculation utilities.
43  *
44  * @author Christos KK Loverdos <loverdos@gmail.com>
45  */
46
47 final class BillingMonthInfo(
48     /**
49      * The billing year.
50      */
51     final val year: Int,
52
53     /**
54      * The billing month, in the range from 1 to 12.
55      */
56     final val month: Int) extends Ordered[BillingMonthInfo] {
57
58   final val (monthStartMillis, monthStopMillis) = {
59     val mdc = new MutableDateCalc(year, month, 1)
60     (
61       mdc.goStartOfThisMonth.getMillis,
62       mdc.goEndOfThisMonth.getMillis // no need to `copy` here, since we are discarding `mdc`
63     )
64   }
65
66   def previousMonth: BillingMonthInfo = {
67     BillingMonthInfo.fromDateCalc(new MutableDateCalc(year, month).goPreviousMonth)
68   }
69
70   def nextMonth: BillingMonthInfo = {
71     BillingMonthInfo.fromDateCalc(new MutableDateCalc(year, month).goNextMonth)
72   }
73
74
75   def compare(that: BillingMonthInfo) = {
76     val ds = this.monthStartMillis - that.monthStartMillis
77     if(ds < 0) -1 else if(ds == 0) 0 else 1
78   }
79
80
81   override def equals(any: Any) = any match {
82     case BillingMonthInfo(thatYear, thatMonth) ⇒
83       this.year == thatYear && this.month == thatMonth // normally everything else MUST be the same by construction
84     case _ ⇒
85       false
86   }
87
88   override def hashCode() = {
89     31 * year + month
90   }
91
92   override def toString = "%s(%s-%02d-01)".format(shortClassNameOf(this), year, month)
93
94   def toShortDebugString = "%s-%02d-01".format(year, month)
95 }
96
97 object BillingMonthInfo {
98   def fromMillis(millis: Long): BillingMonthInfo = {
99     fromDateCalc(new MutableDateCalc(millis))
100   }
101
102   def fromDateCalc(mdc: MutableDateCalc): BillingMonthInfo = {
103     val year = mdc.getYear
104     val month = mdc.getMonthOfYear
105
106     new BillingMonthInfo(year, month)
107   }
108
109   def unapply(bmi: BillingMonthInfo): Option[(Int, Int)] = {
110     Some((bmi.year, bmi.month))
111   }
112 }