Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- [#96](https://github.com/itk-dev/devops_itksites/pull/96)
Show the Service Agreements monthly price as Danish kroner,
`12.500,50 kr.`, on index and detail
- [#95](https://github.com/itk-dev/devops_itksites/pull/95)
Update `vincentlanglet/twig-cs-fixer` to 4.0. Every other dependency is
already at its latest minor; the remaining majors are held back by their
Expand Down
30 changes: 29 additions & 1 deletion src/Controller/Admin/SecurityContractCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@ public function configureFields(string $pageName): iterable
yield TextField::new('clientContactEmail')->hideOnIndex();

yield FormField::addFieldset('Budget');
yield NumberField::new('monthlyPrice')->setTextAlign('right')->setColumns(6);
// The amount is Danish kroner, which the admin never said anywhere.
// 5.5's prepend()/append() addons would be the way to show a unit inside
// an input, but they render on form pages only and this CRUD disables
// NEW and EDIT (see configureActions), so index and detail are the only
// pages it has. Hence formatting instead of an addon.
yield NumberField::new('monthlyPrice')->setTextAlign('right')->setColumns(6)->formatValue(self::formatKroner(...));

yield FormField::addFieldset('Infrastructure');
yield BooleanField::new('dedicatedServer')->renderAsSwitch(false)->hideOnIndex();
Expand All @@ -83,6 +88,29 @@ public function configureFields(string $pageName): iterable
yield DateField::new('validTo')->setColumns(6);
}

/**
* An amount as Danish kroner: 12.500,50 kr.
*
* Through Intl rather than by pasting a suffix on, so the grouping and the
* decimal separator are Danish too. The application locale is `en`, which
* would otherwise render 12,500.5 with no currency at all.
*/
public static function formatKroner(?float $value): ?string
{
if (null === $value) {
return null;
}

return (new \NumberFormatter('da_DK', \NumberFormatter::CURRENCY))->formatCurrency($value, 'DKK') ?: null;
}

/**
* The attribute is what makes this method reachable as a CRUD action.
*
* Without it EasyAdmin throws while rendering the "Sync all" button, which
* took the whole index page with it — see the "Custom CRUD Actions" section
* of the bundle's UPGRADE.md.
*/
#[AdminRoute]
public function syncAll(): RedirectResponse
{
Expand Down
65 changes: 65 additions & 0 deletions tests/Controller/Admin/SecurityContractCurrencyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

namespace App\Tests\Controller\Admin;

use App\Controller\Admin\SecurityContractCrudController;
use App\Entity\Project;
use App\Entity\SecurityContract;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use Hautelook\AliceBundle\PhpUnit\RefreshDatabaseTrait;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

/**
* Service agreement amounts are Danish kroner, and the admin has to say so.
*
* The values come from Economics with no unit attached, and the CRUD has no
* form pages — NEW and EDIT are disabled — so index and detail are the only
* places a reader ever sees them.
*/
class SecurityContractCurrencyTest extends WebTestCase
{
use RefreshDatabaseTrait;

public function testAmountsRenderAsDanishKroner(): void
{
$client = static::createClient();

$entityManager = static::getContainer()->get(EntityManagerInterface::class);
$client->loginUser($entityManager->getRepository(User::class)->findOneBy([]));

$project = new Project();
$project->setEconomicsId(4711);
$project->setName('Kroner probe');

$contract = new SecurityContract();
$contract->setEconomicsId(4711);
$contract->setProject($project);
$contract->setMonthlyPrice(12500.5);

$entityManager->persist($project);
$entityManager->persist($contract);
$entityManager->flush();

$url = static::getContainer()->get(AdminUrlGenerator::class)
->setController(SecurityContractCrudController::class)
->setAction(Crud::PAGE_INDEX)
->generateUrl();

$client->request('GET', $url);

$this->assertResponseIsSuccessful();

$content = (string) $client->getResponse()->getContent();

// Danish grouping and separator, not the application locale's 12,500.5.
// Amount and unit are asserted apart because Intl joins them with a
// non-breaking space.
$this->assertStringContainsString('12.500,50', $content);
$this->assertStringContainsString('kr.', $content);
}
}
Loading