invoices: unified money, number and date formats and fully respect configured language (#1814)
This commit is contained in:
74
src/Invoice/Renderer/AbstractTwigRenderer.php
Normal file
74
src/Invoice/Renderer/AbstractTwigRenderer.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Invoice\Renderer;
|
||||
|
||||
use App\Entity\InvoiceDocument;
|
||||
use App\Invoice\InvoiceModel;
|
||||
use App\Invoice\RendererInterface;
|
||||
use App\Twig\DateExtensions;
|
||||
use App\Twig\LocaleExtensions;
|
||||
use Symfony\Bridge\Twig\Extension\TranslationExtension;
|
||||
use Symfony\Contracts\Translation\LocaleAwareInterface;
|
||||
use Twig\Environment;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
abstract class AbstractTwigRenderer implements RendererInterface
|
||||
{
|
||||
/**
|
||||
* @var Environment
|
||||
*/
|
||||
private $twig;
|
||||
|
||||
public function __construct(Environment $twig)
|
||||
{
|
||||
$this->twig = $twig;
|
||||
}
|
||||
|
||||
protected function renderTwigTemplate(InvoiceDocument $document, InvoiceModel $model): string
|
||||
{
|
||||
$previousLocale = $this->changeTwigLocale($this->twig, $model->getTemplate()->getLanguage());
|
||||
|
||||
$content = $this->twig->render('@invoice/' . basename($document->getFilename()), [
|
||||
'model' => $model
|
||||
]);
|
||||
|
||||
$this->changeTwigLocale($this->twig, $previousLocale);
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
private function changeTwigLocale(Environment $twig, ?string $locale = null): ?string
|
||||
{
|
||||
// for invoices that don't have a language configured (using request locale)
|
||||
if (null === $locale) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var TranslationExtension $extension */
|
||||
$extension = $twig->getExtension(TranslationExtension::class);
|
||||
/** @var LocaleAwareInterface $translator */
|
||||
$translator = $extension->getTranslator();
|
||||
$previousLocale = $translator->getLocale();
|
||||
|
||||
$translator->setLocale($locale);
|
||||
|
||||
/** @var LocaleExtensions $extension */
|
||||
$extension = $twig->getExtension(LocaleExtensions::class);
|
||||
$extension->setLocale($locale);
|
||||
|
||||
/** @var DateExtensions $extension */
|
||||
$extension = $twig->getExtension(DateExtensions::class);
|
||||
$extension->setLocale($locale);
|
||||
|
||||
return $previousLocale;
|
||||
}
|
||||
}
|
||||
@@ -12,23 +12,11 @@ namespace App\Invoice\Renderer;
|
||||
use App\Entity\InvoiceDocument;
|
||||
use App\Invoice\InvoiceFilename;
|
||||
use App\Invoice\InvoiceModel;
|
||||
use App\Invoice\RendererInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
|
||||
use Twig\Environment;
|
||||
|
||||
final class JsonRenderer implements RendererInterface
|
||||
final class JsonRenderer extends AbstractTwigRenderer
|
||||
{
|
||||
/**
|
||||
* @var Environment
|
||||
*/
|
||||
private $twig;
|
||||
|
||||
public function __construct(Environment $twig)
|
||||
{
|
||||
$this->twig = $twig;
|
||||
}
|
||||
|
||||
public function supports(InvoiceDocument $document): bool
|
||||
{
|
||||
return stripos($document->getFilename(), '.json.twig') !== false;
|
||||
@@ -36,9 +24,7 @@ final class JsonRenderer implements RendererInterface
|
||||
|
||||
public function render(InvoiceDocument $document, InvoiceModel $model): Response
|
||||
{
|
||||
$content = $this->twig->render('@invoice/' . basename($document->getFilename()), [
|
||||
'model' => $model
|
||||
]);
|
||||
$content = $this->renderTwigTemplate($document, $model);
|
||||
$filename = (string) new InvoiceFilename($model);
|
||||
|
||||
$response = new Response($content);
|
||||
|
||||
@@ -12,18 +12,13 @@ namespace App\Invoice\Renderer;
|
||||
use App\Entity\InvoiceDocument;
|
||||
use App\Invoice\InvoiceFilename;
|
||||
use App\Invoice\InvoiceModel;
|
||||
use App\Invoice\RendererInterface;
|
||||
use App\Utils\HtmlToPdfConverter;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
|
||||
use Twig\Environment;
|
||||
|
||||
final class PdfRenderer implements RendererInterface
|
||||
final class PdfRenderer extends AbstractTwigRenderer
|
||||
{
|
||||
/**
|
||||
* @var Environment
|
||||
*/
|
||||
private $twig;
|
||||
/**
|
||||
* @var HtmlToPdfConverter
|
||||
*/
|
||||
@@ -31,7 +26,7 @@ final class PdfRenderer implements RendererInterface
|
||||
|
||||
public function __construct(Environment $twig, HtmlToPdfConverter $converter)
|
||||
{
|
||||
$this->twig = $twig;
|
||||
parent::__construct($twig);
|
||||
$this->converter = $converter;
|
||||
}
|
||||
|
||||
@@ -42,9 +37,7 @@ final class PdfRenderer implements RendererInterface
|
||||
|
||||
public function render(InvoiceDocument $document, InvoiceModel $model): Response
|
||||
{
|
||||
$content = $this->twig->render('@invoice/' . basename($document->getFilename()), [
|
||||
'model' => $model
|
||||
]);
|
||||
$content = $this->renderTwigTemplate($document, $model);
|
||||
|
||||
$content = $this->converter->convertToPdf($content, [
|
||||
'setAutoTopMargin' => 'pad',
|
||||
|
||||
@@ -12,23 +12,11 @@ namespace App\Invoice\Renderer;
|
||||
use App\Entity\InvoiceDocument;
|
||||
use App\Invoice\InvoiceFilename;
|
||||
use App\Invoice\InvoiceModel;
|
||||
use App\Invoice\RendererInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
|
||||
use Twig\Environment;
|
||||
|
||||
final class TextRenderer implements RendererInterface
|
||||
final class TextRenderer extends AbstractTwigRenderer
|
||||
{
|
||||
/**
|
||||
* @var Environment
|
||||
*/
|
||||
private $twig;
|
||||
|
||||
public function __construct(Environment $twig)
|
||||
{
|
||||
$this->twig = $twig;
|
||||
}
|
||||
|
||||
public function supports(InvoiceDocument $document): bool
|
||||
{
|
||||
return stripos($document->getFilename(), '.txt.twig') !== false;
|
||||
@@ -36,9 +24,7 @@ final class TextRenderer implements RendererInterface
|
||||
|
||||
public function render(InvoiceDocument $document, InvoiceModel $model): Response
|
||||
{
|
||||
$content = $this->twig->render('@invoice/' . basename($document->getFilename()), [
|
||||
'model' => $model
|
||||
]);
|
||||
$content = $this->renderTwigTemplate($document, $model);
|
||||
$filename = (string) new InvoiceFilename($model);
|
||||
|
||||
$response = new Response($content);
|
||||
|
||||
@@ -11,22 +11,10 @@ namespace App\Invoice\Renderer;
|
||||
|
||||
use App\Entity\InvoiceDocument;
|
||||
use App\Invoice\InvoiceModel;
|
||||
use App\Invoice\RendererInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Twig\Environment;
|
||||
|
||||
final class TwigRenderer implements RendererInterface
|
||||
final class TwigRenderer extends AbstractTwigRenderer
|
||||
{
|
||||
/**
|
||||
* @var Environment
|
||||
*/
|
||||
private $twig;
|
||||
|
||||
public function __construct(Environment $twig)
|
||||
{
|
||||
$this->twig = $twig;
|
||||
}
|
||||
|
||||
public function supports(InvoiceDocument $document): bool
|
||||
{
|
||||
return stripos($document->getFilename(), '.html.twig') !== false;
|
||||
@@ -34,9 +22,7 @@ final class TwigRenderer implements RendererInterface
|
||||
|
||||
public function render(InvoiceDocument $document, InvoiceModel $model): Response
|
||||
{
|
||||
$content = $this->twig->render('@invoice/' . basename($document->getFilename()), [
|
||||
'model' => $model
|
||||
]);
|
||||
$content = $this->renderTwigTemplate($document, $model);
|
||||
|
||||
$response = new Response();
|
||||
$response->setContent($content);
|
||||
|
||||
@@ -12,23 +12,11 @@ namespace App\Invoice\Renderer;
|
||||
use App\Entity\InvoiceDocument;
|
||||
use App\Invoice\InvoiceFilename;
|
||||
use App\Invoice\InvoiceModel;
|
||||
use App\Invoice\RendererInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
|
||||
use Twig\Environment;
|
||||
|
||||
final class XmlRenderer implements RendererInterface
|
||||
final class XmlRenderer extends AbstractTwigRenderer
|
||||
{
|
||||
/**
|
||||
* @var Environment
|
||||
*/
|
||||
private $twig;
|
||||
|
||||
public function __construct(Environment $twig)
|
||||
{
|
||||
$this->twig = $twig;
|
||||
}
|
||||
|
||||
public function supports(InvoiceDocument $document): bool
|
||||
{
|
||||
return stripos($document->getFilename(), '.xml.twig') !== false;
|
||||
@@ -36,9 +24,7 @@ final class XmlRenderer implements RendererInterface
|
||||
|
||||
public function render(InvoiceDocument $document, InvoiceModel $model): Response
|
||||
{
|
||||
$content = $this->twig->render('@invoice/' . basename($document->getFilename()), [
|
||||
'model' => $model
|
||||
]);
|
||||
$content = $this->renderTwigTemplate($document, $model);
|
||||
$filename = (string) new InvoiceFilename($model);
|
||||
|
||||
$response = new Response($content);
|
||||
|
||||
Reference in New Issue
Block a user