/**
  * @param  Event   $event
  * @return Entry[]
  *
  * @throws Exception\RuntimeException
  * @throws Zend\Di\Exception\ClassNotFoundException
  */
 public function process(Event $event)
 {
     $entries = new ArrayCollection();
     $eventRange = new DateRange($event->start, $event->end);
     if ($eventRange->isEmpty()) {
         return $entries;
     }
     $rule = $event->rule;
     if ($rule === null) {
         throw new Exception\RuntimeException(sprintf('The event %s has no associated rule.', $event->id));
     }
     $config = $this->getMatchingConfiguration($rule, $eventRange->getStart());
     if ($config->end < $eventRange->getEnd()) {
         throw new Exception\RuntimeException(sprintf('The rule configuration %s from %s to %s does not' . ' cover the desired range %s to %s.', $config->id, $config->start->format('Y-m-d'), $config->end->format('Y-m-d'), $eventRange->getStart()->format('Y-m-d'), $eventRange->getEnd()->format('Y-m-d')));
     }
     $strategy = $this->di->get($config->strategy);
     if (!$strategy instanceof StrategyInterface) {
         throw new Exception\RuntimeException(sprintf('The class %s does not implement %s.', get_class($strategy), 'Tillikum\\Billing\\Event\\Strategy\\StrategyInterface'));
     }
     $strategyEntries = $strategy->process($event, $config);
     foreach ($strategyEntries as $entry) {
         if ($event->is_credit) {
             $entry->amount *= -1;
         }
         $entries->add($entry);
     }
     return $entries;
 }
Пример #2
0
 public function process(Event $event, RuleConfig $config)
 {
     $entries = new ArrayCollection();
     $configRange = new DateRange($config->start, $config->end);
     $eventRange = new DateRange($event->start, $event->end);
     if ($configRange->isEmpty()) {
         return $entries;
     }
     $amountPerRange = new Money($config->amount, $config->currency);
     $configDays = (int) $configRange->getStart()->diff($configRange->getEnd())->format('%R%a') + 1;
     $totalDays = (int) $eventRange->getStart()->diff($eventRange->getEnd())->format('%R%a') + 1;
     // If we match up nicely, just bill at the fixed value and we're done
     if ($eventRange->equals($configRange)) {
         $rangeTotal = $amountPerRange;
         $entry = new Entry();
         $entry->amount = $rangeTotal->round(2);
         $entry->currency = $rangeTotal->getCurrency();
         $entry->code = $config->code;
         $entry->description = sprintf('%s to %s (%s %s) @ %s for the entire range', $event->start->format('Y-m-d'), $event->end->format('Y-m-d'), $totalDays, $totalDays == 1 ? 'day' : 'days', $amountPerRange->format());
         $entries->add($entry);
     } else {
         // (amount per fixed range / days in fixed range) * days billed
         $proratedTotal = $amountPerRange->div($configDays)->mul($totalDays);
         $entry = new Entry();
         $entry->amount = $proratedTotal->round(2);
         $entry->currency = $proratedTotal->getCurrency();
         $entry->code = $config->code;
         $entry->description = sprintf('%s to %s (%s %s) @ %s for part of %s to %s (%s %s) (prorated daily)', $event->start->format('Y-m-d'), $event->end->format('Y-m-d'), $totalDays, $totalDays == 1 ? 'day' : 'days', $amountPerRange->format(), $configRange->getStart()->format('Y-m-d'), $configRange->getEnd()->format('Y-m-d'), $configDays, $configDays == 1 ? 'day' : 'days');
         $entries->add($entry);
     }
     return $entries;
 }