161 lines
6.0 KiB
PHP
161 lines
6.0 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
require_once dirname(__DIR__) . '/bootstrap.php';
|
|
|
|
$assets = app()->assets();
|
|
if ($assets) {
|
|
$assets->addStyle('/module/fx-rates/asset?file=fx-rates.css');
|
|
$assets->addScript('/module/fx-rates/asset?file=fx-rates.js', 'footer', true);
|
|
}
|
|
|
|
$settings = module_fn('fx-rates', 'settings');
|
|
$service = module_fn('fx-rates', 'service');
|
|
$preferredCurrencies = is_array($settings['preferred_currencies'] ?? null) ? $settings['preferred_currencies'] : [];
|
|
$notice = trim((string) ($_GET['notice'] ?? ''));
|
|
$error = trim((string) ($_GET['error'] ?? ''));
|
|
|
|
if ((string) ($_GET['refresh'] ?? '') === '1') {
|
|
try {
|
|
$result = $service->refreshLatestRates(null, (string) ($settings['default_base_currency'] ?? ''));
|
|
$params = [
|
|
'notice' => sprintf(
|
|
'Aktuelle Kurse gespeichert. %d Werte aktualisiert.',
|
|
(int) ($result['updated_count'] ?? 0)
|
|
),
|
|
];
|
|
} catch (\Throwable $exception) {
|
|
$params = ['error' => $exception->getMessage() !== '' ? $exception->getMessage() : 'Kurse konnten nicht aktualisiert werden.'];
|
|
}
|
|
|
|
redirect('/module/fx-rates?' . http_build_query($params));
|
|
}
|
|
|
|
$latest = $service->latestStatus();
|
|
$recentFetches = $service->recentFetches(12);
|
|
$pageData = json_encode([
|
|
'settings' => $settings,
|
|
'latest' => $latest,
|
|
'preferred_currencies' => $preferredCurrencies,
|
|
'recent_fetches' => $recentFetches,
|
|
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
?>
|
|
<?= module_shell_header('fx-rates', [
|
|
'title' => 'Waehrungskurse',
|
|
'actions' => [
|
|
['label' => 'Setup', 'href' => '/modules/setup/fx-rates', 'variant' => 'secondary', 'size' => 'sm'],
|
|
['label' => 'Aktuelle Kurse abrufen', 'href' => '/module/fx-rates?refresh=1', 'variant' => 'secondary', 'size' => 'sm'],
|
|
],
|
|
]) ?>
|
|
<div id="fx-rates-app" data-page='<?= e(is_string($pageData) ? $pageData : '{}') ?>'>
|
|
<div class="fx-stack">
|
|
<div class="fx-card">
|
|
<?php if ($notice !== ''): ?>
|
|
<div class="fx-message is-success"><?= e($notice) ?></div>
|
|
<?php elseif ($error !== ''): ?>
|
|
<div class="fx-message is-error"><?= e($error) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<h2>Umrechnung</h2>
|
|
<p>Umrechnung auf Basis des letzten verfuegbaren Kurses zwischen den bevorzugten Waehrungen.</p>
|
|
<div class="fx-form-grid">
|
|
<label>
|
|
<span>Quellwaehrung</span>
|
|
<select name="convert_from">
|
|
<?php foreach ($preferredCurrencies as $currency): ?>
|
|
<option value="<?= e((string) $currency) ?>"><?= e((string) $currency) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</label>
|
|
<label>
|
|
<span>Zielwaehrung</span>
|
|
<select name="convert_to">
|
|
<?php foreach ($preferredCurrencies as $currency): ?>
|
|
<option value="<?= e((string) $currency) ?>" <?= (string) $currency === (string) ($preferredCurrencies[1] ?? $preferredCurrencies[0] ?? '') ? 'selected' : '' ?>><?= e((string) $currency) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</label>
|
|
<label>
|
|
<span>Betrag</span>
|
|
<input type="number" name="convert_amount" min="0" step="0.00000001" value="1">
|
|
</label>
|
|
</div>
|
|
<div class="fx-convert-result" data-bind="convert-result">Noch keine Umrechnung berechnet.</div>
|
|
</div>
|
|
|
|
<div class="fx-card">
|
|
<div class="fx-card-head">
|
|
<div>
|
|
<h2>Letzte Kurse</h2>
|
|
<p>Letzter gespeicherter Snapshot, umgerechnet auf <?= e((string) ($settings['display_base_currency'] ?? $settings['default_base_currency'] ?? 'EUR')) ?>.</p>
|
|
</div>
|
|
<div class="fx-card-meta">
|
|
<div><strong>Letzter Abruf:</strong> <?= e((string) ($latest['fetched_at_display'] ?? $latest['fetched_at'] ?? 'noch keiner')) ?></div>
|
|
<div><strong>Anzeige-Basis:</strong> <?= e((string) ($settings['display_base_currency'] ?? $settings['default_base_currency'] ?? '')) ?></div>
|
|
<div><strong>Snapshot-Basis:</strong> <?= e((string) ($latest['base_currency'] ?? '')) ?></div>
|
|
</div>
|
|
</div>
|
|
<div class="fx-table-wrap">
|
|
<table class="fx-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Waehrung</th>
|
|
<th>Kurs</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody data-bind="rates-body">
|
|
<tr><td colspan="2">Noch keine Daten geladen.</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="fx-card">
|
|
<h2>Kursverlauf</h2>
|
|
<p>Chronologischer Verlauf der bevorzugten Waehrungen relativ zur Anzeige-Basiswaehrung.</p>
|
|
<div class="fx-table-wrap">
|
|
<table class="fx-table">
|
|
<thead data-bind="history-head">
|
|
<tr>
|
|
<th>Datum</th>
|
|
<th>Kurse</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody data-bind="history-body">
|
|
<tr><td colspan="2">Noch keine Verlaufsdaten geladen.</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="fx-card">
|
|
<h2>Letzte Abrufe</h2>
|
|
<div class="fx-table-wrap">
|
|
<table class="fx-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Datum</th>
|
|
<th>Basis</th>
|
|
<th>Provider</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody data-bind="fetches-body">
|
|
<?php if ($recentFetches === []): ?>
|
|
<tr><td colspan="3">Noch keine Abrufe vorhanden.</td></tr>
|
|
<?php else: ?>
|
|
<?php foreach ($recentFetches as $fetch): ?>
|
|
<tr>
|
|
<td><?= e((string) ($fetch['fetched_at_display'] ?? $fetch['fetched_at'] ?? '')) ?></td>
|
|
<td><?= e((string) ($fetch['base_currency'] ?? '')) ?></td>
|
|
<td><?= e((string) ($fetch['provider'] ?? '')) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?= module_shell_footer() ?>
|