Ejemplo n.º 1
0
 public function process(Event $event, RuleConfig $config)
 {
     $entries = new ArrayCollection();
     // Days: Day difference + 1
     $days = (int) $event->start->diff($event->end)->format('%R%a') + 1;
     $amountPerDay = new Money($config->amount, $config->currency);
     // Safely calculate daily amount
     // amountPerDay * number of days
     $total = $amountPerDay->mul($days);
     $entry = new Entry();
     $entry->amount = $total->round(2);
     $entry->currency = $total->getCurrency();
     $entry->code = $config->code;
     $entry->description = sprintf('%s to %s (%s %s) @ %s per day', $event->start->format('Y-m-d'), $event->end->format('Y-m-d'), $days, $days === 1 ? 'day' : 'days', $amountPerDay->format());
     $entries->add($entry);
     return $entries;
 }
Ejemplo n.º 2
0
 public function process(Event $event, RuleConfig $config)
 {
     $entries = new ArrayCollection();
     // Nights: Day difference
     $nights = (int) $event->start->diff($event->end)->format('%R%a');
     // Nothing to do.
     if ($nights <= 0) {
         return $entries;
     }
     $amountPerNight = new Money($config->amount, $config->currency);
     // Safely calculate nightly amount
     // amountPerNight * number of nights
     $total = $amountPerNight->mul($nights);
     $entry = new Entry();
     $entry->amount = $total->round(2);
     $entry->currency = $total->getCurrency();
     $entry->code = $config->code;
     $entry->description = sprintf('%s to %s (%s %s) @ %s per night', $event->start->format('Y-m-d'), $event->end->format('Y-m-d'), $nights, $nights === 1 ? 'night' : 'nights', $amountPerNight->format());
     $entries->add($entry);
     return $entries;
 }
Ejemplo n.º 3
0
 public function process(Event $event, RuleConfig $config)
 {
     $entries = new ArrayCollection();
     $eventRange = new DateRange($event->start, $event->end);
     // Days: Day difference + 1
     $totalDays = (int) $eventRange->getStart()->diff($eventRange->getEnd())->format('%R%a') + 1;
     // The total number of full weeks
     $weeks = (int) floor($totalDays / 7);
     // The number of leftover days after full weeks are counted
     $leftoverDays = (int) $totalDays % 7;
     $amountPerWeek = new Money($config->amount, $config->currency);
     // amount per week * number of weeks
     $weekTotal = $amountPerWeek->mul($weeks);
     // (amount per week / 7) * leftover days (prorate)
     $leftoverDayTotal = $amountPerWeek->div(7)->mul($leftoverDays);
     // If we have solid weeks, make an entry for that total
     if ($weeks > 0) {
         $fullWeekEndDate = clone $eventRange->getEnd();
         $fullWeekEndDate->modify("-{$leftoverDays} day");
         $entry = new entry();
         $entry->amount = $weekTotal->round(2);
         $entry->currency = $weekTotal->getCurrency();
         $entry->code = $config->code;
         $entry->description = sprintf('%s to %s (%s %s) @ %s per week', $eventRange->getStart()->format('Y-m-d'), $fullWeekEndDate->format('Y-m-d'), $weeks, $weeks == 1 ? 'week' : 'weeks', $amountPerWeek->format());
         $entries->add($entry);
     }
     if ($leftoverDays > 0) {
         // Start 1 day after the end of the previous full week(s), if there
         // were any
         $partialWeekStartDate = clone $eventRange->getEnd();
         $partialWeekStartDate->modify("-{$leftoverDays} day")->modify('+1 day');
         $entry = new Entry();
         $entry->amount = $leftoverDayTotal->round(2);
         $entry->currency = $leftoverDayTotal->getCurrency();
         $entry->code = $config->code;
         $entry->description = sprintf('%s to %s (%s %s) @ %s per week (prorated daily)', $partialWeekStartDate->format('Y-m-d'), $eventRange->getEnd()->format('Y-m-d'), $leftoverDays, $leftoverDays == 1 ? 'day' : 'days', $amountPerWeek->format());
         $entries->add($entry);
     }
     return $entries;
 }
Ejemplo n.º 4
0
 public function process(Event $event, RuleConfig $config)
 {
     $entries = new ArrayCollection();
     // Create a pointer because we’re about to get procedural
     $pointer = clone $event->start;
     // If we don't start on the first of the month, we will need to
     // calculate "leading" days before the first full month (if there is
     // one).
     $leadingDays = 0;
     $leadingDaysInMonth = 0;
     if ($pointer->format('j') != 1) {
         $leadingStartAudit = $pointer->format('Y-m-d');
         $leadingEnd = min($event->end, new DateTime($pointer->format('Y-m-t')));
         $leadingEndAudit = $leadingEnd->format('Y-m-d');
         $leadingDaysInMonth = (int) $pointer->format('t');
         $leadingDays = (int) $pointer->diff($leadingEnd)->format('%R%a') + 1;
         $pointer->modify("+{$leadingDays} days");
     }
     // Initial number of full months
     $months = 0;
     // Get the date of the last day in the month our pointer is in
     $endOfMonth = new DateTime($pointer->format('Y-m-t'));
     $fullMonthStartAudit = $pointer->format('F Y');
     // If the pointer points at the first, and the end date is at or at or
     // beyond the end of the current month, we can count a full month.
     while ($pointer->format('j') == 1 && $event->end >= $endOfMonth) {
         $fullMonthEndAudit = $endOfMonth->format('F Y');
         $months += 1;
         // Now that we counted a full month, advance pointer 1 day past the
         // end of the month, which should be the first day of the next month
         $pointer = clone $endOfMonth;
         $pointer->modify('+1 day');
         // Update the new end of the month based on the new pointer value
         $endOfMonth = new DateTime($pointer->format('Y-m-t'));
     }
     $trailingDays = 0;
     $trailingDaysInMonth = 0;
     if ($pointer <= $event->end) {
         $trailingStartAudit = $pointer->format('Y-m-d');
         $trailingEndAudit = $event->end->format('Y-m-d');
         $trailingDaysInMonth = (int) $pointer->format('t');
         // Our pointer should be exactly where it needs to be to calculate any
         // "trailing" days
         $trailingDays = (int) $pointer->diff($event->end)->format('%R%a') + 1;
     }
     $amountPerMonth = new Money($config->amount, $config->currency);
     // amount per month * number of months
     $monthTotal = $amountPerMonth->mul($months);
     if ($leadingDays > 0) {
         // (amount per month / number of days in month) * leftover days (prorate)
         $leadingDayTotal = $amountPerMonth->div($leadingDaysInMonth)->mul($leadingDays);
         $entry = new Entry();
         $entry->amount = $leadingDayTotal->round(2);
         $entry->currency = $leadingDayTotal->getCurrency();
         $entry->code = $config->code;
         $entry->description = sprintf('%s to %s (%s %s) @ %s per month (prorated daily)', $leadingStartAudit, $leadingEndAudit, $leadingDays, $leadingDays == 1 ? 'day' : 'days', $amountPerMonth->format());
         $entries->add($entry);
     }
     // If we have solid months, make an entry for that total
     if ($months > 0) {
         $entry = new Entry();
         $entry->amount = $monthTotal->round(2);
         $entry->currency = $monthTotal->getCurrency();
         $entry->code = $config->code;
         $entry->description = sprintf('%s (%s %s) @ %s per month', $months == 1 ? $fullMonthStartAudit : "{$fullMonthStartAudit} to {$fullMonthEndAudit}", $months, $months == 1 ? 'month' : 'months', $amountPerMonth->format());
         $entries->add($entry);
     }
     if ($trailingDays > 0) {
         // (amount per month / number of days in month) * leftover days (prorate)
         $trailingDayTotal = $amountPerMonth->div($trailingDaysInMonth)->mul($trailingDays);
         $entry = new Entry();
         $entry->amount = $trailingDayTotal->round(2);
         $entry->currency = $trailingDayTotal->getCurrency();
         $entry->code = $config->code;
         $entry->description = sprintf('%s to %s (%s %s) @ %s per month (prorated daily)', $trailingStartAudit, $trailingEndAudit, $trailingDays, $trailingDays == 1 ? 'day' : 'days', $amountPerMonth->format());
         $entries->add($entry);
     }
     return $entries;
 }
Ejemplo n.º 5
0
 /**
  * @expectedException InvalidArgumentException
  */
 public function testMulCurrencyMismatch()
 {
     $m1 = new Money(45, 'EUR');
     $m2 = new Money(50, 'USD');
     $m2->mul($m1);
 }