merge default currency settings (#5739)

This commit is contained in:
Kevin Papst
2025-12-22 17:55:48 +01:00
committed by GitHub
parent f0e2337d67
commit 3fcaf55d02
15 changed files with 41 additions and 71 deletions

View File

@@ -30,6 +30,8 @@ final class Version20251214160001 extends AbstractMigration
// used to count the tags for the dropdown (filter and timesheet edit) // used to count the tags for the dropdown (filter and timesheet edit)
$table->addIndex(['visible'], 'IDX_27CAF54C7AB0E859'); $table->addIndex(['visible'], 'IDX_27CAF54C7AB0E859');
} }
// deleted in this release
$this->addSql("DELETE from kimai2_configuration where name = 'defaults.user.language'");
} }
public function down(Schema $schema): void public function down(Schema $schema): void

View File

@@ -584,11 +584,6 @@ parameters:
count: 1 count: 1
path: src/Configuration/SystemConfiguration.php path: src/Configuration/SystemConfiguration.php
-
message: "#^Method App\\\\Configuration\\\\SystemConfiguration\\:\\:getCustomerDefaultCurrency\\(\\) should return string but returns bool\\|float\\|int\\|string\\|null\\.$#"
count: 1
path: src/Configuration/SystemConfiguration.php
- -
message: "#^Method App\\\\Configuration\\\\SystemConfiguration\\:\\:getCustomerDefaultTimezone\\(\\) should return string\\|null but returns bool\\|float\\|int\\|string\\|null\\.$#" message: "#^Method App\\\\Configuration\\\\SystemConfiguration\\:\\:getCustomerDefaultTimezone\\(\\) should return string\\|null but returns bool\\|float\\|int\\|string\\|null\\.$#"
count: 1 count: 1
@@ -599,21 +594,6 @@ parameters:
count: 1 count: 1
path: src/Configuration/SystemConfiguration.php path: src/Configuration/SystemConfiguration.php
-
message: "#^Method App\\\\Configuration\\\\SystemConfiguration\\:\\:getUserDefaultCurrency\\(\\) should return string but returns bool\\|float\\|int\\|string\\|null\\.$#"
count: 1
path: src/Configuration/SystemConfiguration.php
-
message: "#^Method App\\\\Configuration\\\\SystemConfiguration\\:\\:getUserDefaultLanguage\\(\\) should return string but returns bool\\|float\\|int\\|string\\|null\\.$#"
count: 1
path: src/Configuration/SystemConfiguration.php
-
message: "#^Method App\\\\Configuration\\\\SystemConfiguration\\:\\:getUserDefaultTheme\\(\\) should return string\\|null but returns bool\\|float\\|int\\|string\\|null\\.$#"
count: 1
path: src/Configuration/SystemConfiguration.php
- -
message: "#^Method App\\\\Configuration\\\\SystemConfiguration\\:\\:getUserDefaultTimezone\\(\\) should return string\\|null but returns bool\\|float\\|int\\|string\\|null\\.$#" message: "#^Method App\\\\Configuration\\\\SystemConfiguration\\:\\:getUserDefaultTimezone\\(\\) should return string\\|null but returns bool\\|float\\|int\\|string\\|null\\.$#"
count: 1 count: 1

View File

@@ -323,11 +323,6 @@ final class SystemConfiguration
return $this->find('defaults.customer.timezone'); return $this->find('defaults.customer.timezone');
} }
public function getCustomerDefaultCurrency(): string
{
return $this->find('defaults.customer.currency');
}
public function getCustomerDefaultCountry(): string public function getCustomerDefaultCountry(): string
{ {
return $this->find('defaults.customer.country'); return $this->find('defaults.customer.country');
@@ -340,20 +335,35 @@ final class SystemConfiguration
return $this->find('defaults.user.timezone'); return $this->find('defaults.user.timezone');
} }
public function getUserDefaultTheme(): ?string public function getUserDefaultTheme(): string
{ {
return $this->find('defaults.user.theme'); return $this->getString('defaults.user.theme', 'auto');
} }
public function getUserDefaultLanguage(): string public function getUserDefaultLanguage(): string
{ {
return $this->find('defaults.user.language'); return $this->getString('defaults.user.language', 'en');
} }
// TODO this is only used to display the hourly rate in the user profile public function getDefaultCurrency(): string
{
return $this->getString('defaults.customer.currency', 'EUR');
}
/**
* @deprecated use getDefaultCurrency() instead
*/
public function getCustomerDefaultCurrency(): string
{
return $this->getDefaultCurrency();
}
/**
* @deprecated use getDefaultCurrency() instead
*/
public function getUserDefaultCurrency(): string public function getUserDefaultCurrency(): string
{ {
return $this->find('defaults.user.currency'); return $this->getDefaultCurrency();
} }
// ========== Timesheet configurations ========== // ========== Timesheet configurations ==========

View File

@@ -111,7 +111,7 @@ final class ActivityController extends AbstractController
'page_setup' => $page, 'page_setup' => $page,
'dataTable' => $table, 'dataTable' => $table,
'metaColumns' => $metaColumns, 'metaColumns' => $metaColumns,
'defaultCurrency' => $configuration->getCustomerDefaultCurrency(), 'defaultCurrency' => $configuration->getDefaultCurrency(),
'now' => $this->getDateTimeFactory()->createDateTime(), 'now' => $this->getDateTimeFactory()->createDateTime(),
]); ]);
} }
@@ -452,7 +452,7 @@ final class ActivityController extends AbstractController
*/ */
private function createEditForm(Activity $activity, SystemConfiguration $configuration): FormInterface private function createEditForm(Activity $activity, SystemConfiguration $configuration): FormInterface
{ {
$currency = $configuration->getCustomerDefaultCurrency(); $currency = $configuration->getDefaultCurrency();
$url = $this->generateUrl('admin_activity_create'); $url = $this->generateUrl('admin_activity_create');
if ($activity->getProject()?->getId() !== null) { if ($activity->getProject()?->getId() !== null) {
$url = $this->generateUrl('admin_activity_create_with_project', ['project' => $activity->getProject()->getId()]); $url = $this->generateUrl('admin_activity_create_with_project', ['project' => $activity->getProject()->getId()]);

View File

@@ -177,7 +177,7 @@ final class ProjectController extends AbstractController
{ {
$project = $projectService->createNewProject($customer); $project = $projectService->createNewProject($customer);
$editForm = $this->createEditForm($project, $configuration->getCustomerDefaultCurrency()); $editForm = $this->createEditForm($project, $configuration->getDefaultCurrency());
$editForm->handleRequest($request); $editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) { if ($editForm->isSubmitted() && $editForm->isValid()) {
@@ -440,7 +440,7 @@ final class ProjectController extends AbstractController
{ {
$projectService->loadMetaFields($project); $projectService->loadMetaFields($project);
$editForm = $this->createEditForm($project, $configuration->getCustomerDefaultCurrency()); $editForm = $this->createEditForm($project, $configuration->getDefaultCurrency());
$editForm->handleRequest($request); $editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) { if ($editForm->isSubmitted() && $editForm->isValid()) {

View File

@@ -467,10 +467,6 @@ final class SystemConfigurationController extends AbstractController
->setLabel('country') ->setLabel('country')
->setType(CountryType::class) ->setType(CountryType::class)
->setOptions(['help' => 'default_value_new']), ->setOptions(['help' => 'default_value_new']),
(new Configuration('defaults.customer.currency'))
->setLabel('currency')
->setType(CurrencyType::class)
->setOptions(['help' => 'default_value_new']),
(new Configuration('customer.choice_pattern')) (new Configuration('customer.choice_pattern'))
->setLabel('choice_pattern') ->setLabel('choice_pattern')
->setType(CustomerTypePatternType::class), ->setType(CustomerTypePatternType::class),
@@ -542,9 +538,6 @@ final class SystemConfigurationController extends AbstractController
->setLabel('skin') ->setLabel('skin')
->setType(SkinType::class) ->setType(SkinType::class)
->setOptions(['help' => 'default_value_new']), ->setOptions(['help' => 'default_value_new']),
(new Configuration('defaults.user.currency'))
->setLabel('currency')
->setType(CurrencyType::class),
(new Configuration('theme.avatar_url')) (new Configuration('theme.avatar_url'))
->setRequired(false) ->setRequired(false)
->setLabel('theme.avatar_url') ->setLabel('theme.avatar_url')
@@ -617,6 +610,10 @@ final class SystemConfigurationController extends AbstractController
->setTranslationDomain('system-configuration') ->setTranslationDomain('system-configuration')
->setRequired(false) ->setRequired(false)
->setType(TextType::class), ->setType(TextType::class),
(new Configuration('defaults.customer.currency'))
->setLabel('currency')
->setType(CurrencyType::class)
->setOptions(['help' => 'Can be overwritten per customer']),
(new Configuration('company.financial_year')) (new Configuration('company.financial_year'))
->setTranslationDomain('system-configuration') ->setTranslationDomain('system-configuration')
->setRequired(false) ->setRequired(false)

View File

@@ -55,7 +55,7 @@ final class CustomerService
$customer = new Customer($name); $customer = new Customer($name);
$customer->setTimezone($this->getDefaultTimezone()); $customer->setTimezone($this->getDefaultTimezone());
$customer->setCountry($this->configuration->getCustomerDefaultCountry()); $customer->setCountry($this->configuration->getCustomerDefaultCountry());
$customer->setCurrency($this->configuration->getCustomerDefaultCurrency()); $customer->setCurrency($this->configuration->getDefaultCurrency());
$customer->setNumber($this->calculateNextCustomerNumber()); $customer->setNumber($this->calculateNextCustomerNumber());
$this->loadMetaFields($customer); $this->loadMetaFields($customer);

View File

@@ -625,8 +625,7 @@ final class Configuration implements ConfigurationInterface
->children() ->children()
->scalarNode('timezone')->defaultNull()->end() ->scalarNode('timezone')->defaultNull()->end()
->scalarNode('language')->defaultValue(User::DEFAULT_LANGUAGE)->end() ->scalarNode('language')->defaultValue(User::DEFAULT_LANGUAGE)->end()
->scalarNode('theme')->defaultValue('default')->end() ->scalarNode('theme')->defaultValue('auto')->end()
->scalarNode('currency')->defaultValue(Customer::DEFAULT_CURRENCY)->end()
->end() ->end()
->end() ->end()
->end() ->end()

View File

@@ -60,7 +60,7 @@ final class UserPreferenceSubscriber implements EventSubscriberInterface
if ($this->voter->isGranted('hourly-rate', $user)) { if ($this->voter->isGranted('hourly-rate', $user)) {
$enableHourlyRate = true; $enableHourlyRate = true;
$hourlyRateOptions = ['currency' => $this->systemConfiguration->getUserDefaultCurrency()]; $hourlyRateOptions = ['currency' => $this->systemConfiguration->getDefaultCurrency()];
} }
return [ return [

View File

@@ -19,8 +19,8 @@ use PHPUnit\Framework\TestCase;
class SystemConfigurationTest extends TestCase class SystemConfigurationTest extends TestCase
{ {
/** /**
* @param array $settings * @param array<string, array<mixed>> $settings
* @param array $loaderSettings * @param array<Configuration> $loaderSettings
* @return SystemConfiguration * @return SystemConfiguration
*/ */
protected function getSut(array $settings, array $loaderSettings = []): SystemConfiguration protected function getSut(array $settings, array $loaderSettings = []): SystemConfiguration
@@ -207,12 +207,11 @@ class SystemConfigurationTest extends TestCase
{ {
$sut = $this->getSut($this->getDefaultSettings(), []); $sut = $this->getSut($this->getDefaultSettings(), []);
self::assertEquals('Europe/London', $sut->getCustomerDefaultTimezone()); self::assertEquals('Europe/London', $sut->getCustomerDefaultTimezone());
self::assertEquals('GBP', $sut->getCustomerDefaultCurrency()); self::assertEquals('GBP', $sut->getDefaultCurrency());
self::assertEquals('FR', $sut->getCustomerDefaultCountry()); self::assertEquals('FR', $sut->getCustomerDefaultCountry());
self::assertEquals('foo/bar', $sut->getUserDefaultTimezone()); self::assertEquals('foo/bar', $sut->getUserDefaultTimezone());
self::assertEquals('blue', $sut->getUserDefaultTheme()); self::assertEquals('blue', $sut->getUserDefaultTheme());
self::assertEquals('IT', $sut->getUserDefaultLanguage()); self::assertEquals('IT', $sut->getUserDefaultLanguage());
self::assertEquals('USD', $sut->getUserDefaultCurrency());
self::assertNull($sut->getFinancialYearStart()); self::assertNull($sut->getFinancialYearStart());
} }
@@ -220,12 +219,11 @@ class SystemConfigurationTest extends TestCase
{ {
$sut = $this->getSut($this->getDefaultSettings(), $this->getDefaultLoaderSettings()); $sut = $this->getSut($this->getDefaultSettings(), $this->getDefaultLoaderSettings());
self::assertEquals('Russia/Moscov', $sut->getCustomerDefaultTimezone()); self::assertEquals('Russia/Moscov', $sut->getCustomerDefaultTimezone());
self::assertEquals('RUB', $sut->getCustomerDefaultCurrency()); self::assertEquals('RUB', $sut->getDefaultCurrency());
self::assertEquals('FR', $sut->getCustomerDefaultCountry()); self::assertEquals('FR', $sut->getCustomerDefaultCountry());
self::assertEquals('foo/bar', $sut->getUserDefaultTimezone()); self::assertEquals('foo/bar', $sut->getUserDefaultTimezone());
self::assertEquals('blue', $sut->getUserDefaultTheme()); self::assertEquals('blue', $sut->getUserDefaultTheme());
self::assertEquals('IT', $sut->getUserDefaultLanguage()); self::assertEquals('IT', $sut->getUserDefaultLanguage());
self::assertEquals('USD', $sut->getUserDefaultCurrency());
} }
public function testTimesheetWithoutLoader(): void public function testTimesheetWithoutLoader(): void

View File

@@ -449,7 +449,7 @@ class ProfileControllerTest extends AbstractControllerBaseTestCase
self::assertEquals($hourlyRateOriginal, $user->getPreferenceValue(UserPreference::HOURLY_RATE)); self::assertEquals($hourlyRateOriginal, $user->getPreferenceValue(UserPreference::HOURLY_RATE));
self::assertNull($user->getPreferenceValue(UserPreference::INTERNAL_RATE)); self::assertNull($user->getPreferenceValue(UserPreference::INTERNAL_RATE));
self::assertEquals('default', $user->getPreferenceValue(UserPreference::SKIN)); self::assertEquals('auto', $user->getPreferenceValue(UserPreference::SKIN));
$data = [ $data = [
UserPreference::TIMEZONE => ['value' => 'America/Creston'], UserPreference::TIMEZONE => ['value' => 'America/Creston'],

View File

@@ -208,7 +208,6 @@ class SystemConfigurationControllerTest extends AbstractControllerBaseTestCase
'configuration' => [ 'configuration' => [
['name' => 'defaults.customer.timezone', 'value' => 'Atlantic/Canary'], ['name' => 'defaults.customer.timezone', 'value' => 'Atlantic/Canary'],
['name' => 'defaults.customer.country', 'value' => 'BB'], ['name' => 'defaults.customer.country', 'value' => 'BB'],
['name' => 'defaults.customer.currency', 'value' => 'GBP'],
] ]
] ]
]); ]);
@@ -221,7 +220,6 @@ class SystemConfigurationControllerTest extends AbstractControllerBaseTestCase
$configService = $this->getSystemConfiguration(); $configService = $this->getSystemConfiguration();
self::assertEquals('Atlantic/Canary', $configService->find('defaults.customer.timezone')); self::assertEquals('Atlantic/Canary', $configService->find('defaults.customer.timezone'));
self::assertEquals('BB', $configService->find('defaults.customer.country')); self::assertEquals('BB', $configService->find('defaults.customer.country'));
self::assertEquals('GBP', $configService->find('defaults.customer.currency'));
} }
public function testUpdateCustomerConfigWithSingleParam(): void public function testUpdateCustomerConfigWithSingleParam(): void
@@ -236,7 +234,6 @@ class SystemConfigurationControllerTest extends AbstractControllerBaseTestCase
'configuration' => [ 'configuration' => [
['name' => 'defaults.customer.timezone', 'value' => 'Atlantic/Canary'], ['name' => 'defaults.customer.timezone', 'value' => 'Atlantic/Canary'],
['name' => 'defaults.customer.country', 'value' => 'BB'], ['name' => 'defaults.customer.country', 'value' => 'BB'],
['name' => 'defaults.customer.currency', 'value' => 'GBP'],
] ]
] ]
]); ]);
@@ -254,7 +251,7 @@ class SystemConfigurationControllerTest extends AbstractControllerBaseTestCase
$configService = $this->getSystemConfiguration(); $configService = $this->getSystemConfiguration();
self::assertNull($configService->find('defaults.user.timezone')); self::assertNull($configService->find('defaults.user.timezone'));
self::assertEquals('default', $configService->find('defaults.user.theme')); self::assertEquals('auto', $configService->find('defaults.user.theme'));
self::assertEquals('en', $configService->find('defaults.user.language')); self::assertEquals('en', $configService->find('defaults.user.language'));
$form = $client->getCrawler()->filter('form[name=system_configuration_form_user]')->form(); $form = $client->getCrawler()->filter('form[name=system_configuration_form_user]')->form();
@@ -290,14 +287,12 @@ class SystemConfigurationControllerTest extends AbstractControllerBaseTestCase
'configuration' => [ 'configuration' => [
['name' => 'defaults.customer.timezone', 'value' => 'XX'], ['name' => 'defaults.customer.timezone', 'value' => 'XX'],
['name' => 'defaults.customer.country', 'value' => 1], ['name' => 'defaults.customer.country', 'value' => 1],
['name' => 'defaults.customer.currency', 'value' => 'XXX'],
] ]
] ]
], ],
[ [
'#system_configuration_form_customer_configuration_0_value', '#system_configuration_form_customer_configuration_0_value',
'#system_configuration_form_customer_configuration_1_value', '#system_configuration_form_customer_configuration_1_value',
'#system_configuration_form_customer_configuration_2_value',
] ]
); );
} }

View File

@@ -364,8 +364,7 @@ class ConfigurationTest extends TestCase
'user' => [ 'user' => [
'timezone' => null, 'timezone' => null,
'language' => 'en', 'language' => 'en',
'theme' => 'default', 'theme' => 'auto',
'currency' => 'EUR',
], ],
], ],
'permissions' => [ 'permissions' => [

View File

@@ -426,16 +426,6 @@ parameters:
count: 1 count: 1
path: Configuration/SamlConfigurationTest.php path: Configuration/SamlConfigurationTest.php
-
message: "#^Method App\\\\Tests\\\\Configuration\\\\SystemConfigurationTest\\:\\:getSut\\(\\) has parameter \\$loaderSettings with no value type specified in iterable type array\\.$#"
count: 1
path: Configuration/SystemConfigurationTest.php
-
message: "#^Method App\\\\Tests\\\\Configuration\\\\SystemConfigurationTest\\:\\:getSut\\(\\) has parameter \\$settings with no value type specified in iterable type array\\.$#"
count: 1
path: Configuration/SystemConfigurationTest.php
- -
message: "#^Cannot call method getId\\(\\) on App\\\\Entity\\\\Activity\\|null\\.$#" message: "#^Cannot call method getId\\(\\) on App\\\\Entity\\\\Activity\\|null\\.$#"
count: 4 count: 4

View File

@@ -5,7 +5,7 @@
<!-- Reports --> <!-- Reports -->
<!-- Actions --> <!-- Actions -->
<!-- Application --> <!-- Application -->
<trans-unit id="tLV1hoP" resname="report_tasks_assigned" xml:space="preserve" approved="no"> <trans-unit id="tLV1hoP" resname="report_tasks_assigned" xml:space="preserve" approved="no">
<source>report_tasks_assigned</source> <source>report_tasks_assigned</source>
<target state="translated">Tasques per usuari</target> <target state="translated">Tasques per usuari</target>
</trans-unit> </trans-unit>