Skip to content

Commit f93ae6a

Browse files
committed
Configuration: Fix currency fallback
Previously, it would always use fallback currency for child fees. Also add a test that demonstrates the issue – the `overridden` category would use `GBP` instead of `USD`.
1 parent e406373 commit f93ae6a

File tree

6 files changed

+62
-6
lines changed

6 files changed

+62
-6
lines changed

app/Model/Configuration/Category.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public static function from(
4040
Fees $parentFees,
4141
DateTimeInterface $eventDate,
4242
): self {
43-
$fees = Fees::from($category['fees'] ?? [], $parentFees);
43+
$fees = Fees::from("categories.$key", $category['fees'] ?? [], $parentFees);
4444
if ($fees->person === null) {
4545
throw new InvalidConfigurationException("No person fee set for category “{$key}");
4646
}

app/Model/Configuration/CategoryGroup.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public static function from(
2727
Fees $parentFees,
2828
DateTimeInterface $eventDate,
2929
): self {
30-
$fees = Fees::from($group['fees'] ?? [], $parentFees);
30+
$fees = Fees::from("categories.$key", $group['fees'] ?? [], $parentFees);
3131

3232
if (!isset($group['categories']) || !\is_array($group['categories']) || \count($group['categories']) === 0) {
3333
throw new InvalidConfigurationException("Category group #{$key} lacks categories");

app/Model/Configuration/Entries.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public static function from(
4545
array $entries,
4646
): self {
4747
$allLocales = $entries['supportedLocales'] ?? ['en', 'cs'];
48-
$fees = Fees::from($entries['fees'] ?? []);
48+
$fees = Fees::fromRoot($entries['fees'] ?? []);
4949
$eventDate = $entries['eventDate'];
5050
$minMembers = $entries['minMembers'] ?? 0;
5151
$personFieldsRaw = Helpers::ensureFields('person', $entries['fields']['person'] ?? []);

app/Model/Configuration/Fees.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,28 @@ public function __construct(
1414
) {
1515
}
1616

17-
public static function from(array $fees, ?self $parentFees = null): self {
18-
$currency = $parentFees?->currency ?? new Currency($fees['currency'] ?? 'CZK');
17+
/**
18+
* @param array<mixed> $fees
19+
*/
20+
public static function fromRoot(array $fees): self {
21+
$currencyCode = Helpers::ensureNonEmptyString('fees.currency', $fees['currency'] ?? 'CZK');
22+
$currency = new Currency($currencyCode);
1923

2024
return new self(
2125
currency: $currency,
22-
person: isset($fees['person']) ? new Money($fees['person'] * 100, $currency) : $parentFees?->person,
26+
person: isset($fees['person']) ? new Money($fees['person'] * 100, $currency) : null,
27+
);
28+
}
29+
30+
/**
31+
* @param array<mixed> $fees
32+
*/
33+
public static function from(string $context, array $fees, self $parentFees): self {
34+
$currency = isset($fees['currency']) ? new Currency(Helpers::ensureNonEmptyString("$context.fees.currency", $fees['currency'])) : $parentFees->currency;
35+
36+
return new self(
37+
currency: $currency,
38+
person: isset($fees['person']) ? new Money($fees['person'] * 100, $currency) : $parentFees->person,
2339
);
2440
}
2541
}

app/Model/Configuration/Helpers.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,21 @@ public static function ensureIntMaybe(string $context, mixed $value): ?int {
141141
return $value;
142142
}
143143

144+
/**
145+
* @return non-empty-string
146+
*/
147+
public static function ensureNonEmptyString(string $context, mixed $value): string {
148+
if (!\is_string($value)) {
149+
throw new InvalidConfigurationException("Expected string for {$context}.");
150+
}
151+
152+
if ($value === '') {
153+
throw new InvalidConfigurationException("Expected non-empty string for {$context}.");
154+
}
155+
156+
return $value;
157+
}
158+
144159
public static function ensureStringMaybe(string $context, mixed $value): ?string {
145160
if ($value === null) {
146161
return $value;

tests/Model/Configuration/BasicReadTest.phpt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,31 @@ class BasicReadTest extends TestCase {
115115
Assert::equal(new Money(20_00, new Currency('CZK')), $entries->categories->allCategories['inherited']->fees->person);
116116
}
117117

118+
public function testFlatCategoriesFeesWithCurrency(): void {
119+
$entries = Entries::from([
120+
'eventDate' => new DateTimeImmutable('2050-12-07'),
121+
'fees' => [
122+
'person' => 20,
123+
'currency' => 'GBP',
124+
],
125+
'categories' => [
126+
'overridden' => [
127+
'fees' => [
128+
'currency' => 'USD',
129+
'person' => 10,
130+
],
131+
],
132+
'inherited' => [
133+
'fees' => [
134+
'person' => 30,
135+
],
136+
],
137+
],
138+
]);
139+
Assert::equal(new Money(10_00, new Currency('USD')), $entries->categories->allCategories['overridden']->fees->person);
140+
Assert::equal(new Money(30_00, new Currency('GBP')), $entries->categories->allCategories['inherited']->fees->person);
141+
}
142+
118143
public function testNestedCategoriesFees(): void {
119144
$entries = Entries::from([
120145
'eventDate' => new DateTimeImmutable('2050-12-07'),

0 commit comments

Comments
 (0)