Use Symfony formatter for currency symbol placement (#542)

This commit is contained in:
Sanjit Patel
2019-02-08 10:56:47 -05:00
committed by Kevin Papst
parent b2587c71b8
commit 616d514d5a
12 changed files with 58 additions and 33 deletions

View File

@@ -20,6 +20,7 @@ matrix:
before_install:
- phpenv config-rm xdebug.ini
- composer self-update
- php -i
install:
- composer install

View File

@@ -33,6 +33,7 @@
"symfony/flex": "^1.0",
"symfony/form": "^4.0",
"symfony/framework-bundle": "^4.0",
"symfony/intl": "^4.0",
"symfony/maker-bundle": "^1.0",
"symfony/monolog-bundle": "^3.1",
"symfony/orm-pack": "^1.0",

View File

@@ -55,11 +55,12 @@ abstract class AbstractRenderer
/**
* @param $amount
* @return mixed
* @param $currency
* @return string
*/
protected function getFormattedMoney($amount)
protected function getFormattedMoney($amount, $currency)
{
return $this->extension->money($amount);
return $this->extension->money($amount, $currency);
}
/**

View File

@@ -53,7 +53,7 @@ trait RendererTrait
* @param $amount
* @return mixed
*/
abstract protected function getFormattedMoney($amount);
abstract protected function getFormattedMoney($amount, $currency);
/**
* @param \DateTime $date
@@ -75,6 +75,7 @@ trait RendererTrait
{
$customer = $model->getCustomer();
$project = $model->getQuery()->getProject();
$currency = $model->getCalculator()->getCurrency();
$values = [
'invoice.due_date' => $this->getFormattedDateTime($model->getDueDate()),
@@ -82,10 +83,10 @@ trait RendererTrait
'invoice.number' => $model->getNumberGenerator()->getInvoiceNumber(),
'invoice.currency' => $model->getCalculator()->getCurrency(),
'invoice.vat' => $model->getCalculator()->getVat(),
'invoice.tax' => $this->getFormattedMoney($model->getCalculator()->getTax()),
'invoice.tax' => $this->getFormattedMoney($model->getCalculator()->getTax(), $currency),
'invoice.total_time' => $this->getFormattedDuration($model->getCalculator()->getTimeWorked()),
'invoice.total' => $this->getFormattedMoney($model->getCalculator()->getTotal()),
'invoice.subtotal' => $this->getFormattedMoney($model->getCalculator()->getSubtotal()),
'invoice.total' => $this->getFormattedMoney($model->getCalculator()->getTotal(), $currency),
'invoice.subtotal' => $this->getFormattedMoney($model->getCalculator()->getSubtotal(), $currency),
'template.name' => $model->getTemplate()->getName(),
'template.company' => $model->getTemplate()->getCompany(),
@@ -156,6 +157,7 @@ trait RendererTrait
$activity = $timesheet->getActivity();
$project = $timesheet->getProject();
$customer = $project->getCustomer();
$currency = $customer->getCurrency();
$begin = $timesheet->getBegin();
$end = $timesheet->getEnd();
@@ -164,8 +166,9 @@ trait RendererTrait
'entry.row' => '',
'entry.description' => $description,
'entry.amount' => $amount,
'entry.rate' => $this->getFormattedMoney($hourlyRate),
'entry.total' => $this->getFormattedMoney($rate),
'entry.rate' => $this->getFormattedMoney($hourlyRate, $currency),
'entry.total' => $this->getFormattedMoney($rate, $currency),
'entry.currency' => $currency,
'entry.duration' => $timesheet->getDuration(),
'entry.duration_minutes' => number_format($timesheet->getDuration() / 60),
'entry.begin' => $this->getFormattedDateTime($begin),

View File

@@ -254,7 +254,7 @@ class Extensions extends \Twig_Extension
if ($this->locale !== $locale) {
$this->locale = $locale;
$this->numberFormatter = new NumberFormatter($locale, NumberFormatter::DECIMAL);
$this->numberFormatter = new NumberFormatter($locale, NumberFormatter::CURRENCY);
}
$fractionDigits = Intl::getCurrencyBundle()->getFractionDigits($currency);
@@ -262,7 +262,7 @@ class Extensions extends \Twig_Extension
$result = $this->numberFormatter->format($amount);
if (null !== $currency) {
$result .= ' ' . Intl::getCurrencyBundle()->getCurrencySymbol($currency, $locale);
$result = $this->numberFormatter->formatCurrency($amount, $currency);
}
return $result;

View File

@@ -31,7 +31,7 @@ class CsvRendererTest extends AbstractRendererTest
public function getTestModel()
{
return [
['01:50 h', '2,437.12', '1,947.99', 7, 5, 1, 2, 2]
['01:50 h', '2,437.12', '1,947.99', 7, 5, 1, 2, 2]
];
}

View File

@@ -55,7 +55,7 @@ class HtmlRendererTest extends AbstractRendererTest
$this->assertContains('<td>Customer Name</td>', $content);
$this->assertContains('<td>project name</td>', $content);
$this->assertContains('<td class="duration">01:50 h</td>', $content);
$this->assertContains('<td class="cost">2,437.12</td>', $content);
$this->assertContains('<td class="cost">2,437.12</td>', $content);
$this->assertEquals(5, substr_count($content, '<td>activity description</td>'));
}

View File

@@ -60,7 +60,7 @@ abstract class AbstractRendererTest extends KernelTestCase
$languages = [
'en' => [
'date' => 'Y.m.d',
'duration' => '%%h:%%m h'
'duration' => '%h:%m h'
]
];
@@ -83,6 +83,7 @@ abstract class AbstractRendererTest extends KernelTestCase
protected function getInvoiceModel()
{
$customer = new Customer();
$customer->setCurrency('EUR');
$template = new InvoiceTemplate();
$template->setTitle('a test invoice template title');
$template->setVat(19);
@@ -194,6 +195,7 @@ abstract class AbstractRendererTest extends KernelTestCase
protected function getInvoiceModelOneEntry()
{
$customer = new Customer();
$customer->setCurrency('USD');
$template = new InvoiceTemplate();
$template->setTitle('a test invoice template title');
$template->setVat(19);

View File

@@ -36,8 +36,8 @@ class CsvRendererTest extends AbstractRendererTest
public function getTestModel()
{
yield [$this->getInvoiceModel(), '1,947.99', 6, 5, 1, 2, 2];
yield [$this->getInvoiceModelOneEntry(), '293.27', 2, 1, 0, 1, 0];
yield [$this->getInvoiceModel(), '1,947.99', 6, 5, 1, 2, 2];
yield [$this->getInvoiceModelOneEntry(), '$293.27', 2, 1, 0, 1, 0];
}
/**

View File

@@ -100,6 +100,7 @@ class DebugRendererTest extends AbstractRendererTest
'entry.amount',
'entry.rate',
'entry.total',
'entry.currency',
'entry.duration',
'entry.duration_minutes',
'entry.begin',

View File

@@ -15,6 +15,7 @@ use App\Utils\LocaleSettings;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Intl\Util\IntlTestHelper;
use Twig\TwigFilter;
/**
@@ -112,10 +113,6 @@ class ExtensionsTest extends TestCase
}
/**
* @param string $result
* @param int $amount
* @param string $currency
* @param string $locale
* @dataProvider getMoneyData
*/
public function testMoney($result, $amount, $currency, $locale)
@@ -127,19 +124,36 @@ class ExtensionsTest extends TestCase
public function getMoneyData()
{
return [
['0 €', null, 'EUR', 'de'],
['2.345 €', 2345, 'EUR', 'de'],
['2,345', 2345, 'EUR', 'en'],
['2,345.01', 2345.009, 'EUR', 'en'],
['2.345,01 €', 2345.009, 'EUR', 'de'],
['13.75 $', 13.75, 'USD', 'en'],
['13,75 $', 13.75, 'USD', 'de'],
['13,75 RUB', 13.75, 'RUB', 'de'],
['13,5 RUB', 13.50, 'RUB', 'de'],
['13,75 ₽', 13.75, 'RUB', 'ru'],
['14 ¥', 13.75, 'JPY', 'de'],
['13 933 ¥', 13933.49, 'JPY', 'ru'],
['1.234.567,89 $', 1234567.891234567890000, 'USD', 'de'],
['0,00 €', null, 'EUR', 'de'],
['2.345,00 €', 2345, 'EUR', 'de'],
['2,345.00', 2345, 'EUR', 'en'],
['2,345.01', 2345.009, 'EUR', 'en'],
['2.345,01 €', 2345.009, 'EUR', 'de'],
['$13.75', 13.75, 'USD', 'en'],
['13,75 $', 13.75, 'USD', 'de'],
['13,75 RUB', 13.75, 'RUB', 'de'],
['14 ¥', 13.75, 'JPY', 'de'],
['13 933 ¥', 13933.49, 'JPY', 'ru'],
['1.234.567,89 $', 1234567.891234567890000, 'USD', 'de'],
];
}
/**
* @dataProvider getMoneyData62_1
*/
public function testMoney62_1($result, $amount, $currency, $locale)
{
IntlTestHelper::requireFullIntl($this, '62.1');
$sut = $this->getSut($this->localeEn, $locale);
$this->assertEquals($result, $sut->money($amount, $currency));
}
public function getMoneyData62_1()
{
return [
['RUB 13.50', 13.50, 'RUB', 'en'],
['13,75 ₽', 13.75, 'RUB', 'ru'],
];
}

View File

@@ -114,6 +114,7 @@ The documents which are rendered passively (ODS, XLSX, CSV, DOCX) can use the fo
| ${invoice.total_time} | The total working time (entries with a fixed rate are always calculated with 1) |
| ${invoice.total} | The invoices total (including tax) |
| ${invoice.subtotal} | The invoices subtotal (excluding tax) |
| ${invoice.currency} | The invoices currency as string (like EUR or USD) |
| ${invoice.vat} | The VAT in percent for this invoice |
| ${invoice.tax} | The tax of the invoice amount |
| ${template.name} | The invoice name, as configured in your template |
@@ -161,6 +162,7 @@ For each timesheet entry you can use the variables from the following table.
| ${entry.amount} | The format duration/amount for this entry | 02:47 h |
| ${entry.rate} | The rate for one unit of the entry (normally one hour) | 100 |
| ${entry.total} | The total rate for this entry | 278,33 |
| ${entry.currency} | The currency for this record as string (like EUR or USD) | EUR |
| ${entry.duration} | The duration in seconds | 10020 |
| ${entry.duration_minutes} | The duration in minutes with no decimals | 167 |
| ${entry.begin} | The begin date (format depends on the users language) | 27.10.2018 |