- * Compute the charge slots generated by a particular resource event.
- *
- */
- def computeFullChargeslots(
- previousResourceEventOpt: Option[ResourceEventModel],
- currentResourceEvent: ResourceEventModel,
- oldCredits: Double,
- oldTotalAmount: Double,
- newTotalAmount: Double,
- resourceType: ResourceType,
- agreementByTimeslot: SortedMap[Timeslot, UserAgreementModel],
- policyStore: PolicyStore,
- clogOpt: Option[ContextualLogger] = None
- ): (Timeslot, List[Chargeslot]) = {
-
- val clog = ContextualLogger.fromOther(clogOpt, logger, "computeFullChargeslots()")
- // clog.begin()
-
- val occurredDate = currentResourceEvent.occurredDate
- val occurredMillis = currentResourceEvent.occurredMillis
- val chargingBehavior = resourceType.chargingBehavior
-
- val (referenceTimeslot, policyByTimeslot, previousValue) = chargingBehavior.needsPreviousEventForCreditAndAmountCalculation match {
- // We need a previous event
- case true ⇒
- previousResourceEventOpt match {
- // We have a previous event
- case Some(previousResourceEvent) ⇒
- val referenceTimeslot = Timeslot(previousResourceEvent.occurredDate, occurredDate)
- // all policies within the interval from previous to current resource event
- // clog.debug("Calling policyStore.loadAndSortPoliciesWithin(%s)", referenceTimeslot)
- // TODO: store policies in mem?
- val policyByTimeslot = policyStore.loadAndSortPoliciesWithin(referenceTimeslot.from.getTime, referenceTimeslot.to.getTime)
-
- (referenceTimeslot, policyByTimeslot, previousResourceEvent.value)
-
- // We do not have a previous event
- case None ⇒
- throw new AquariumInternalError(
- "Unable to charge. No previous event given for %s".format(currentResourceEvent.toDebugString))
- }
-
- // We do not need a previous event
- case false ⇒
- // ... so we cannot compute timedelta from a previous event, there is just one chargeslot
- // referring to (almost) an instant in time
- val previousValue = chargingBehavior.getResourceInstanceUndefinedAmount
-
- // TODO: Check semantics of this
- val referenceTimeslot = Timeslot(new MutableDateCalc(occurredDate).goPreviousMilli.toDate, occurredDate)
-
- // TODO: store policies in mem?
- val relevantPolicyOpt: Option[PolicyModel] = policyStore.loadValidPolicyAt(occurredMillis)
-
- val policyByTimeslot = relevantPolicyOpt match {
- case Some(relevantPolicy) ⇒
- SortedMap(referenceTimeslot -> relevantPolicy)
-
- case None ⇒
- throw new AquariumInternalError("No relevant policy found for %s".format(referenceTimeslot))
- }
-
- (referenceTimeslot, policyByTimeslot, previousValue)
- }
-
- val initialChargeslots = computeInitialChargeslots(
- referenceTimeslot,
- resourceType,
- policyByTimeslot,
- agreementByTimeslot,
- Some(clog)
- )
-
- val fullChargeslots = initialChargeslots.map {
- case chargeslot@Chargeslot(startMillis, stopMillis, unitPrice, _) ⇒
- val valueMap = chargingBehavior.makeValueMap(
- oldCredits,
- oldTotalAmount,
- newTotalAmount,
- stopMillis - startMillis,
- previousValue,
- currentResourceEvent.value,
- unitPrice
- )
-
- // clog.debug("execAlgorithm = %s", execAlgorithm)
- clog.debugMap("valueMap", valueMap, 1)
-
- // This is it
- val credits = SimpleExecutableChargingBehaviorAlgorithm.apply(valueMap)
- chargeslot.copyWithCredits(credits)
- }
-
- val result = referenceTimeslot -> fullChargeslots
-
- result
- }
-
- /**