diff --git a/src/Invoice/Renderer/AbstractRenderer.php b/src/Invoice/Renderer/AbstractRenderer.php index a41e5753..412d1867 100644 --- a/src/Invoice/Renderer/AbstractRenderer.php +++ b/src/Invoice/Renderer/AbstractRenderer.php @@ -89,4 +89,13 @@ abstract class AbstractRenderer { return $this->extension->duration($seconds); } + + /** + * @param int $seconds + * @return mixed + */ + protected function getFormattedDecimalDuration($seconds) + { + return $this->extension->durationDecimal($seconds); + } } diff --git a/src/Invoice/Renderer/RendererTrait.php b/src/Invoice/Renderer/RendererTrait.php index 443439b2..f4872c8c 100644 --- a/src/Invoice/Renderer/RendererTrait.php +++ b/src/Invoice/Renderer/RendererTrait.php @@ -74,6 +74,12 @@ trait RendererTrait */ abstract protected function getFormattedDuration($seconds); + /** + * @param int $seconds + * @return mixed + */ + abstract protected function getFormattedDecimalDuration($seconds); + /** * @param InvoiceModel $model * @return array @@ -93,6 +99,7 @@ trait RendererTrait 'invoice.vat' => $model->getCalculator()->getVat(), 'invoice.tax' => $this->getFormattedMoney($model->getCalculator()->getTax(), $currency), 'invoice.total_time' => $this->getFormattedDuration($model->getCalculator()->getTimeWorked()), + 'invoice.duration_decimal' => $this->getFormattedDecimalDuration($model->getCalculator()->getTimeWorked()), 'invoice.total' => $this->getFormattedMoney($model->getCalculator()->getTotal(), $currency), 'invoice.subtotal' => $this->getFormattedMoney($model->getCalculator()->getSubtotal(), $currency), @@ -177,7 +184,7 @@ trait RendererTrait if (null !== $timesheet->getFixedRate()) { $rate = $timesheet->getFixedRate(); $hourlyRate = $timesheet->getFixedRate(); - $amount = 1; + $amount = 1; // FIXME fixed rates } if (empty($description)) { @@ -206,6 +213,7 @@ trait RendererTrait 'entry.total' => $this->getFormattedMoney($rate, $currency), 'entry.currency' => $currency, 'entry.duration' => $timesheet->getDuration(), + 'entry.duration_decimal' => $this->getFormattedDecimalDuration($timesheet->getDuration()), 'entry.duration_minutes' => number_format($timesheet->getDuration() / 60), 'entry.begin' => $this->getFormattedDateTime($begin), 'entry.begin_time' => $this->getFormattedTime($begin), diff --git a/src/Twig/Extensions.php b/src/Twig/Extensions.php index e33f7d92..b69ac408 100644 --- a/src/Twig/Extensions.php +++ b/src/Twig/Extensions.php @@ -63,6 +63,7 @@ class Extensions extends AbstractExtension { return [ new TwigFilter('duration', [$this, 'duration']), + new TwigFilter('duration_decimal', [$this, 'durationDecimal']), new TwigFilter('money', [$this, 'money']), new TwigFilter('currency', [$this, 'currency']), new TwigFilter('country', [$this, 'country']), @@ -102,6 +103,30 @@ class Extensions extends AbstractExtension * @return string */ public function duration($duration, $format = null) + { + $duration = $this->getSecondsForDuration($duration); + + if (null === $format) { + $format = $this->localeSettings->getDurationFormat(); + } + + return $this->formatDuration($duration, $format); + } + + /** + * Transforms seconds into a decimal formatted duration string. + * + * @param int|Timesheet $duration + * @return string + */ + public function durationDecimal($duration) + { + $duration = $this->getSecondsForDuration($duration); + + return $this->getNumberFormatter()->format(number_format($duration / 3600, 2)); + } + + private function getSecondsForDuration($duration): int { if (null === $duration) { $duration = 0; @@ -116,19 +141,15 @@ class Extensions extends AbstractExtension $duration = $seconds; } - return $this->formatDuration((int) $duration, $format); + return (int) $duration; } - protected function formatDuration(int $seconds, $format = null): string + protected function formatDuration(int $seconds, string $format): string { if ($seconds < 0) { return '?'; } - if (null === $format) { - $format = $this->localeSettings->getDurationFormat(); - } - return $this->durationFormatter->format($seconds, $format); } @@ -159,6 +180,33 @@ class Extensions extends AbstractExtension return Constants::HOMEPAGE . '/documentation/' . $url; } + private function initLocale() + { + $locale = $this->localeSettings->getLocale(); + + if ($this->locale === $locale) { + return; + } + + $this->locale = $locale; + $this->numberFormatter = new NumberFormatter($locale, NumberFormatter::DECIMAL); + $this->moneyFormatter = new NumberFormatter($locale, NumberFormatter::CURRENCY); + } + + private function getNumberFormatter(): NumberFormatter + { + $this->initLocale(); + + return $this->numberFormatter; + } + + private function getMoneyFormatter(): NumberFormatter + { + $this->initLocale(); + + return $this->moneyFormatter; + } + /** * @param float $amount * @param string $currency @@ -166,19 +214,11 @@ class Extensions extends AbstractExtension */ public function money($amount, $currency = null) { - $locale = $this->localeSettings->getLocale(); - - if ($this->locale !== $locale) { - $this->locale = $locale; - $this->numberFormatter = new NumberFormatter($locale, NumberFormatter::DECIMAL); - $this->moneyFormatter = new NumberFormatter($locale, NumberFormatter::CURRENCY); - } - if (null !== $currency) { - return $this->moneyFormatter->formatCurrency($amount, $currency); + return $this->getMoneyFormatter()->formatCurrency($amount, $currency); } - return $this->numberFormatter->format($amount); + return $this->getNumberFormatter()->format($amount); } /** diff --git a/templates/invoice/index.html.twig b/templates/invoice/index.html.twig index b431e2d1..42ea7a79 100644 --- a/templates/invoice/index.html.twig +++ b/templates/invoice/index.html.twig @@ -45,7 +45,7 @@ {% set duration = entry.duration|duration %} {% if entry.fixedRate is not null %} {% set rate = entry.fixedRate %} - {% set duration = 1 %} + {% set duration = 1 %}{# FIXME fixed rates #} {% elseif entry.hourlyRate is not null %} {% set rate = entry.hourlyRate %} {% else %} diff --git a/templates/invoice/renderer/default.html.twig b/templates/invoice/renderer/default.html.twig index 4f9fcb07..a8382bd7 100644 --- a/templates/invoice/renderer/default.html.twig +++ b/templates/invoice/renderer/default.html.twig @@ -67,7 +67,7 @@ {% set duration = entry.duration|duration %} {% if entry.fixedRate is not null %} {% set rate = entry.fixedRate %} - {% set duration = 1 %} + {% set duration = 1 %}{# FIXME fixed rates #} {% elseif entry.hourlyRate is not null %} {% set rate = entry.hourlyRate %} {% else %} diff --git a/templates/invoice/renderer/freelancer.html.twig b/templates/invoice/renderer/freelancer.html.twig index 096c3344..f4f08293 100644 --- a/templates/invoice/renderer/freelancer.html.twig +++ b/templates/invoice/renderer/freelancer.html.twig @@ -80,7 +80,7 @@ {% set duration = entry.duration|duration %} {% if entry.fixedRate is not null %} {% set rate = entry.fixedRate %} - {% set duration = 1 %} + {% set duration = 1 %}{# FIXME fixed rates #} {% elseif entry.hourlyRate is not null %} {% set rate = entry.hourlyRate %} {% else %} diff --git a/templates/invoice/renderer/timesheet.html.twig b/templates/invoice/renderer/timesheet.html.twig index b7497edc..f2364dc9 100644 --- a/templates/invoice/renderer/timesheet.html.twig +++ b/templates/invoice/renderer/timesheet.html.twig @@ -86,6 +86,9 @@