Files
kaffeekasse-saas/mandant-einstellungen.php

410 lines
27 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
require_once __DIR__ . '/functions.php';
require_once __DIR__ . '/app/audit.php';
require_once __DIR__ . '/app/billing.php';
require_once __DIR__ . '/app/tenant-logo.php';
require_once __DIR__ . '/app/features.php';
$pdo = app_db_pdo();
$user = saas_require_login();
$canManageSettings = saas_can_manage_tenant_settings($user);
$brandingEnabled = app_feature_enabled($pdo, (int)$user['tenant_id'], 'branding');
$errors = [];
$saved = false;
$settings = null;
if ($canManageSettings) {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
app_require_csrf();
$eingaben = $_POST;
// Ohne freigeschaltetes Design fehlt das Farbfeld im Formular. Der
// gespeicherte Wert wird dann durchgereicht statt geleert, damit eine
// spaetere Freischaltung die alte Farbe wiederfindet.
if (!$brandingEnabled) {
$bestehend = saas_fetch_tenant_settings($pdo, (int)$user['tenant_id']);
$eingaben['brand_color'] = (string)($bestehend['brand_color'] ?? '');
}
$result = saas_update_tenant_settings($pdo, (int)$user['tenant_id'], $eingaben);
if ($result['ok']) {
$saved = true;
$settings = $result['settings'];
app_audit_log($pdo, (int)$user['tenant_id'], (int)$user['user_id'], 'tenant_settings.updated', 'tenant', (int)$user['tenant_id']);
$tenantIdLogo = (int)$user['tenant_id'];
// Marken-Logo der App-Oberflaeche: nur wenn der Betreiber das
// eigene Design fuer diesen Mandanten freigeschaltet hat.
if ($brandingEnabled) {
if (!empty($_POST['brand_logo_remove'])) {
tenant_logo_delete((string)($settings['brand_logo'] ?? ''));
$pdo->prepare("UPDATE tenant_settings SET brand_logo = '' WHERE tenant_id = ?")->execute([$tenantIdLogo]);
$settings['brand_logo'] = '';
} elseif (isset($_FILES['brand_logo_file']) && ($_FILES['brand_logo_file']['error'] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_OK) {
$brandResult = tenant_logo_store($tenantIdLogo, $_FILES['brand_logo_file'], 'brand');
if ($brandResult['ok']) {
$pdo->prepare('UPDATE tenant_settings SET brand_logo = ? WHERE tenant_id = ?')->execute([$brandResult['filename'], $tenantIdLogo]);
$settings['brand_logo'] = $brandResult['filename'];
} else {
$errors[] = $brandResult['error'];
}
}
}
if (!empty($_POST['pdf_watermark_logo_remove'])) {
tenant_logo_delete((string)($settings['pdf_watermark_logo'] ?? ''));
$pdo->prepare("UPDATE tenant_settings SET pdf_watermark_logo = '' WHERE tenant_id = ?")->execute([$tenantIdLogo]);
$settings['pdf_watermark_logo'] = '';
} elseif (isset($_FILES['pdf_watermark_logo_file']) && ($_FILES['pdf_watermark_logo_file']['error'] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_OK) {
$logoResult = tenant_logo_store($tenantIdLogo, $_FILES['pdf_watermark_logo_file']);
if ($logoResult['ok']) {
$pdo->prepare('UPDATE tenant_settings SET pdf_watermark_logo = ? WHERE tenant_id = ?')->execute([$logoResult['filename'], $tenantIdLogo]);
$settings['pdf_watermark_logo'] = $logoResult['filename'];
} else {
$errors[] = $logoResult['error'];
}
}
} else {
$errors = $result['errors'];
$settings = [
'name' => $_POST['tenant_name'] ?? '',
'customer_type' => $_POST['customer_type'] ?? 'unknown',
'timezone' => $_POST['timezone'] ?? 'Europe/Berlin',
'locale' => $_POST['locale'] ?? 'de-DE',
'currency_code' => $_POST['currency_code'] ?? 'EUR',
'mark_price_cents' => saas_parse_money_cents($_POST['mark_price'] ?? '') ?? 0,
'self_entry_enabled' => !empty($_POST['self_entry_enabled']) ? 1 : 0,
'paypal_enabled' => !empty($_POST['paypal_enabled']) ? 1 : 0,
'paypal_url_template' => $_POST['paypal_url_template'] ?? '',
'cash_enabled' => !empty($_POST['cash_enabled']) ? 1 : 0,
'cash_contact' => $_POST['cash_contact'] ?? '',
'bank_transfer_enabled' => !empty($_POST['bank_transfer_enabled']) ? 1 : 0,
'bank_account_holder' => $_POST['bank_account_holder'] ?? '',
'bank_iban' => $_POST['bank_iban'] ?? '',
'sheet_window_days' => $_POST['sheet_window_days'] ?? 100,
'negative_warning_cents' => -abs(saas_parse_money_cents($_POST['negative_warning'] ?? '') ?? 0),
'pdf_show_empty_rows' => !empty($_POST['pdf_show_empty_rows']) ? 1 : 0,
'pdf_split_mode' => $_POST['pdf_split_mode'] ?? 'drinking_behavior',
'pdf_row_height_px' => $_POST['pdf_row_height_px'] ?? 16,
'pdf_watermark_text' => $_POST['pdf_watermark_text'] ?? '',
'pdf_footer_text' => $_POST['pdf_footer_text'] ?? '',
'payment_reminder_enabled' => !empty($_POST['payment_reminder_enabled']) ? 1 : 0,
'payment_reminder_interval_days' => $_POST['payment_reminder_interval_days'] ?? 7,
'brand_color' => $_POST['brand_color'] ?? '',
'brand_logo' => (string)(saas_fetch_tenant_settings($pdo, (int)$user['tenant_id'])['brand_logo'] ?? ''),
'watermark_enabled' => !empty($_POST['watermark_enabled']) ? 1 : 0,
];
}
} else {
$settings = saas_fetch_tenant_settings($pdo, (int)$user['tenant_id']);
}
$auditLog = app_fetch_audit_log($pdo, (int)$user['tenant_id'], 50);
$billingCheck = billing_check_tenant($pdo, (int)$user['tenant_id']);
$billingPlans = billing_plans();
$billing = billing_fetch_or_init($pdo, (int)$user['tenant_id']);
}
include 'header.php';
include 'headerline.php';
include 'nav.php';
?>
<section id="banner">
<div class="content">
<h2>Mandant-Einstellungen</h2>
<?php if (!$canManageSettings): ?>
<?php http_response_code(403); ?>
<div class="hint-box error"><p>Du hast keine Berechtigung für diese Einstellungen.</p></div>
<?php elseif ($settings === null): ?>
<div class="hint-box error"><p>Die Einstellungen konnten nicht geladen werden.</p></div>
<?php else: ?>
<?php if ($saved): ?>
<div class="hint-box success"><p>Die Einstellungen wurden gespeichert.</p></div>
<?php endif; ?>
<?php if ($errors !== []): ?>
<div class="hint-box error">
<?php foreach ($errors as $error): ?>
<p><?php echo saas_html($error); ?></p>
<?php endforeach; ?>
</div>
<?php endif; ?>
<form method="post" action="mandant-einstellungen.php" enctype="multipart/form-data">
<?php echo app_csrf_field(); ?>
<div class="row">
<div class="col-6 col-12-small">
<label for="tenant_name">Kundenname</label>
<input type="text" name="tenant_name" id="tenant_name" value="<?php echo saas_html($settings['name']); ?>" required>
</div>
<div class="col-6 col-12-small">
<label for="customer_type">Vertragstyp</label>
<select name="customer_type" id="customer_type" required>
<option value=""<?php echo $settings['customer_type'] === 'unknown' ? ' selected' : ''; ?>>Bitte auswählen</option>
<option value="business"<?php echo $settings['customer_type'] === 'business' ? ' selected' : ''; ?>>Unternehmen / selbstständige Tätigkeit</option>
<option value="consumer"<?php echo $settings['customer_type'] === 'consumer' ? ' selected' : ''; ?>>Verbraucher / private Nutzung</option>
</select>
</div>
<div class="col-6 col-12-small">
<label for="timezone">Zeitzone</label>
<input type="text" name="timezone" id="timezone" value="<?php echo saas_html($settings['timezone']); ?>" required>
</div>
<div class="col-6 col-12-small">
<label for="locale">Locale</label>
<input type="text" name="locale" id="locale" value="<?php echo saas_html($settings['locale']); ?>" required>
</div>
<div class="col-6 col-12-small">
<label for="currency_code">Währung</label>
<input type="text" name="currency_code" id="currency_code" value="<?php echo saas_html($settings['currency_code']); ?>" maxlength="3" required>
</div>
<div class="col-6 col-12-small">
<label for="mark_price">Preis pro Strich</label>
<input type="text" name="mark_price" id="mark_price" value="<?php echo saas_html(saas_format_money_cents($settings['mark_price_cents'])); ?>" required>
</div>
<div class="col-6 col-12-small">
<label for="sheet_window_days">Listenfenster in Tagen</label>
<input type="number" name="sheet_window_days" id="sheet_window_days" min="1" max="365" value="<?php echo saas_html($settings['sheet_window_days']); ?>" required>
</div>
<div class="col-6 col-12-small">
<label for="negative_warning">Schulden-Warnschwelle</label>
<input type="text" name="negative_warning" id="negative_warning" value="<?php echo saas_html(saas_format_money_cents(abs((int)$settings['negative_warning_cents']))); ?>" required>
</div>
<div class="col-12">
<h3>Bezahloptionen</h3>
<p>Aktiviere die Zahlungswege, die deine Mitglieder nutzen können. Nur aktivierte Optionen werden im Mitglieder-Dashboard angezeigt.</p>
</div>
<div class="col-6 col-12-small">
<input type="checkbox" id="cash_enabled" name="cash_enabled" value="1" <?php echo (int)$settings['cash_enabled'] === 1 ? 'checked' : ''; ?>>
<label for="cash_enabled">Barzahlung anbieten</label>
</div>
<div class="col-6 col-12-small">
<label for="cash_contact">Ansprechpartner für Barzahlung</label>
<input type="text" name="cash_contact" id="cash_contact" maxlength="255" value="<?php echo saas_html($settings['cash_contact']); ?>">
</div>
<div class="col-6 col-12-small">
<input type="checkbox" id="paypal_enabled" name="paypal_enabled" value="1" <?php echo (int)$settings['paypal_enabled'] === 1 ? 'checked' : ''; ?>>
<label for="paypal_enabled">PayPal anbieten</label>
</div>
<div class="col-6 col-12-small">
<label for="paypal_url_template">PayPal-Link</label>
<input type="text" name="paypal_url_template" id="paypal_url_template" value="<?php echo saas_html($settings['paypal_url_template']); ?>">
</div>
<div class="col-6 col-12-small">
<input type="checkbox" id="bank_transfer_enabled" name="bank_transfer_enabled" value="1" <?php echo (int)$settings['bank_transfer_enabled'] === 1 ? 'checked' : ''; ?>>
<label for="bank_transfer_enabled">Überweisung anbieten</label>
</div>
<div class="col-6 col-12-small">
<label for="bank_account_holder">Kontoinhaber (Überweisung)</label>
<input type="text" name="bank_account_holder" id="bank_account_holder" maxlength="255" value="<?php echo saas_html($settings['bank_account_holder']); ?>">
</div>
<div class="col-12">
<label for="bank_iban">IBAN (Überweisung)</label>
<input type="text" name="bank_iban" id="bank_iban" maxlength="40" value="<?php echo saas_html($settings['bank_iban']); ?>">
</div>
<div class="col-6 col-12-small">
<input type="checkbox" id="self_entry_enabled" name="self_entry_enabled" value="1" <?php echo (int)$settings['self_entry_enabled'] === 1 ? 'checked' : ''; ?>>
<label for="self_entry_enabled">Web-Striche erlauben</label>
</div>
<div class="col-6 col-12-small">
<input type="checkbox" id="pdf_show_empty_rows" name="pdf_show_empty_rows" value="1" <?php echo (int)$settings['pdf_show_empty_rows'] === 1 ? 'checked' : ''; ?>>
<label for="pdf_show_empty_rows">Freie Zeilen für neue Mitglieder im Ausdruck</label>
</div>
<div class="col-6 col-12-small">
<label for="pdf_split_mode">Sortierung im Ausdruck (bei mehreren Seiten)</label>
<select name="pdf_split_mode" id="pdf_split_mode">
<option value="drinking_behavior" <?php echo $settings['pdf_split_mode'] === 'drinking_behavior' ? 'selected' : ''; ?>>Nach Trinkverhalten (Vieltrinker vorne)</option>
<option value="alphabetical" <?php echo $settings['pdf_split_mode'] === 'alphabetical' ? 'selected' : ''; ?>>Alphabetisch</option>
</select>
</div>
<div class="col-6 col-12-small">
<label for="pdf_row_height_px">Zeilenhöhe im Ausdruck (1060px)</label>
<input type="number" name="pdf_row_height_px" id="pdf_row_height_px" min="10" max="60" value="<?php echo saas_html($settings['pdf_row_height_px']); ?>" required>
</div>
<div class="col-12">
<label for="pdf_watermark_text">Wasserzeichen-Text im Ausdruck (leer = kein Wasserzeichen)</label>
<input type="text" name="pdf_watermark_text" id="pdf_watermark_text" maxlength="500" value="<?php echo saas_html($settings['pdf_watermark_text']); ?>">
</div>
<div class="col-12">
<label for="pdf_watermark_logo_file">Logo als Wasserzeichen (PNG/JPEG, ersetzt den Text im Ausdruck)</label>
<input type="file" name="pdf_watermark_logo_file" id="pdf_watermark_logo_file" accept="image/png,image/jpeg">
<?php if (trim((string)($settings['pdf_watermark_logo'] ?? '')) !== ''): ?>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="pdf_watermark_logo_remove" id="pdf_watermark_logo_remove" value="1">
<label class="form-check-label" for="pdf_watermark_logo_remove">Hinterlegtes Logo entfernen (wieder Text-Wasserzeichen verwenden)</label>
</div>
<?php else: ?>
<small>Aktuell kein Logo hinterlegt.</small>
<?php endif; ?>
</div>
<div class="col-12">
<label for="pdf_footer_text">Hinweis in der Fußzeile des Ausdrucks (leer = keine Fußzeile)</label>
<input type="text" name="pdf_footer_text" id="pdf_footer_text" maxlength="500" value="<?php echo saas_html($settings['pdf_footer_text']); ?>">
</div>
<?php if ($brandingEnabled): ?>
<div class="col-12">
<h3>Eigenes Design</h3>
<p>Logo und Akzentfarbe für die Oberfläche eurer Kaffeeliste. Leere Felder =
Standarddesign. Das Logo hier erscheint sichtbar in der Kopfzeile jeder Seite
das Wasserzeichen weiter oben betrifft nur den Ausdruck.</p>
</div>
<div class="col-6 col-12-small">
<label for="brand_color">Akzentfarbe</label>
<input type="color" name="brand_color" id="brand_color"
value="<?php echo saas_html($settings['brand_color'] !== '' ? $settings['brand_color'] : '#38761d'); ?>">
</div>
<div class="col-6 col-12-small">
<label for="brand_logo_file">Logo für die Kopfzeile (PNG/JPEG)</label>
<input type="file" name="brand_logo_file" id="brand_logo_file" accept="image/png,image/jpeg">
<?php if (trim((string)($settings['brand_logo'] ?? '')) !== ''): ?>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="brand_logo_remove" id="brand_logo_remove" value="1">
<label class="form-check-label" for="brand_logo_remove">Hinterlegtes Logo entfernen</label>
</div>
<?php else: ?>
<small>Aktuell kein Logo hinterlegt.</small>
<?php endif; ?>
</div>
<?php endif; ?>
<?php
// Der Hinweis auf die Kaffeeliste (Logo unten rechts) ist im kostenlosen
// Tarif Teil des Angebots und deshalb dort festgestellt. Das Kaestchen bleibt
// sichtbar, damit erkennbar ist, was passiert - nur eben unveraenderlich.
$watermarkErzwungen = (string)($billing['plan_code'] ?? 'free') === 'free';
$watermarkAn = $watermarkErzwungen || (int)($settings['watermark_enabled'] ?? 1) === 1;
?>
<div class="col-12">
<h3>Hinweis auf die Kaffeeliste</h3>
<p>Unten rechts steht eine kleine Marke mit dem Logo der Kaffeeliste und
einem Link auf unsere Seite.</p>
</div>
<div class="col-12">
<input type="checkbox" id="watermark_enabled" name="watermark_enabled" value="1"
<?php echo $watermarkAn ? 'checked' : ''; ?>
<?php echo $watermarkErzwungen ? 'disabled' : ''; ?>>
<label for="watermark_enabled">Logo der Kaffeeliste unten rechts anzeigen</label>
<?php if ($watermarkErzwungen): ?>
<div class="hint-box"><p>Im kostenlosen Tarif bleibt dieser Hinweis eingeblendet
er ist der Gegenwert für die kostenlose Nutzung. Ab dem Tarif „Basic" könnt ihr
ihn hier ausschalten.</p></div>
<?php endif; ?>
</div>
<div class="col-6 col-12-small">
<input type="checkbox" id="payment_reminder_enabled" name="payment_reminder_enabled" value="1" <?php echo (int)$settings['payment_reminder_enabled'] === 1 ? 'checked' : ''; ?>>
<label for="payment_reminder_enabled">Automatische Zahlungserinnerung ab Warnschwelle</label>
</div>
<div class="col-6 col-12-small">
<label for="payment_reminder_interval_days">Erinnerungs-Intervall in Tagen</label>
<input type="number" name="payment_reminder_interval_days" id="payment_reminder_interval_days" min="1" max="90" value="<?php echo saas_html($settings['payment_reminder_interval_days']); ?>">
</div>
</div>
<ul class="actions">
<li><button type="submit">Speichern</button></li>
<li><a href="konto.php" class="button alt">Zurück</a></li>
</ul>
</form>
<h3>Abo &amp; Tarif</h3>
<p>
Aktueller Tarif: <b><?php echo saas_html($billingPlans[$billingCheck['current_plan']]['label'] ?? $billingCheck['current_plan']); ?></b><br>
Aktive Teilnehmer: <?php echo (int)$billingCheck['active_participants']; ?>
<?php if (!empty($user['contract_ends_at'])): ?>
<br><b>Vertrag gekündigt:</b> Der Zugang endet am <?php echo saas_html(date('d.m.Y, H:i', strtotime((string)$user['contract_ends_at']))); ?> Uhr. Bitte lade vorher den <a href="datenexport.php">Datenexport</a> herunter.
<?php elseif (($billing['subscription_status'] ?? '') === 'canceling'): ?>
<br><b>Gekündigt:</b> Der kostenpflichtige Tarif endet <?php echo !empty($billing['current_period_end']) ? 'am ' . saas_html(date('d.m.Y, H:i', strtotime((string)$billing['current_period_end']))) . ' Uhr' : 'zum Ende der laufenden Abrechnungsperiode'; ?>. Danach gilt der kostenlose Tarif.
<?php endif; ?>
</p>
<?php if (isset($_GET['upgrade']) && $_GET['upgrade'] === 'success'): ?>
<div class="hint-box success"><p>Danke! Die Änderung wird verarbeitet, der Tarif ist gleich aktuell.</p></div>
<?php elseif (isset($_GET['upgrade']) && $_GET['upgrade'] === 'cancelled'): ?>
<div class="hint-box error"><p>Der Bezahlvorgang wurde abgebrochen, es wurde nichts geändert.</p></div>
<?php endif; ?>
<?php if (isset($_GET['contract_mail_failed'])): ?>
<div class="hint-box error"><p>Die Tarifänderung wurde ausgeführt, aber die Vertragsbestätigung konnte nicht per E-Mail versendet werden. Bitte speichere <a href="legal/agb-<?php echo saas_html(APP_TERMS_VERSION); ?>.txt" download>die AGB</a> und bei privater Nutzung <a href="legal/widerruf-<?php echo saas_html(APP_WITHDRAWAL_VERSION); ?>.txt" download>die Widerrufsbelehrung</a> und melde dich über das <a href="<?php echo saas_html(app_legal_ticket_url()); ?>">Ticketsystem</a>.</p></div>
<?php endif; ?>
<?php if ($billingCheck['needs_upgrade']): ?>
<div class="hint-box error">
<p>Mit <?php echo (int)$billingCheck['active_participants']; ?> aktiven Teilnehmern benötigt ihr mindestens den
Tarif „<?php echo saas_html($billingPlans[$billingCheck['required_plan']]['label'] ?? $billingCheck['required_plan']); ?>".</p>
</div>
<?php else: ?>
<div class="hint-box success"><p>Euer aktueller Tarif deckt eure Teilnehmerzahl ab.</p></div>
<?php endif; ?>
<table>
<tr>
<th>Tarif</th>
<th>Max. aktive Teilnehmer</th>
<th>Preis/Monat</th>
<th>Status</th>
<th></th>
</tr>
<?php foreach ($billingPlans as $planCode => $plan): ?>
<?php
$isCurrent = $planCode === $billingCheck['current_plan'];
$selectable = billing_plan_selectable_for($pdo, (int)$user['tenant_id'], $planCode);
$isSelfService = $plan['stripe_lookup_key'] !== null || $planCode === 'free';
?>
<tr<?php echo $isCurrent ? ' class="tarif-aktuell"' : ''; ?>>
<td><?php echo saas_html($plan['label']); ?></td>
<td><?php echo $plan['max_participants'] !== null ? (int)$plan['max_participants'] : 'unbegrenzt'; ?></td>
<td><?php echo $plan['price_cents'] > 0 ? saas_html(saas_format_money_cents($plan['price_cents'])) . ' €' : 'kostenlos'; ?></td>
<td>
<?php if ($isCurrent): ?>
aktuell gebucht
<?php elseif (!$selectable): ?>
deckt eure <?php echo (int)$billingCheck['active_participants']; ?> Teilnehmer nicht ab
<?php endif; ?>
</td>
<td>
<?php if ($isCurrent): ?>
<?php elseif (!$isSelfService): ?>
<a href="<?php echo saas_html(app_legal_ticket_url()); ?>" class="button small">Anfragen</a>
<?php elseif (!$selectable): ?>
<button type="button" class="button small" disabled>Nicht wählbar</button>
<?php else: ?>
<form method="post" action="<?php echo $planCode === 'free' ? 'abo-upgrade.php' : 'abo-bestellen.php'; ?>">
<?php echo app_csrf_field(); ?>
<input type="hidden" name="plan_code" value="<?php echo saas_html($planCode); ?>">
<button type="submit" class="button small primary">
<?php echo $planCode === 'free' ? 'Kostenpflichtiges Abo kündigen' : 'Bestellung prüfen'; ?>
</button>
</form>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</table>
<p><small>Bei einem Wechsel zwischen bezahlten Tarifen gilt die neue Teilnehmergrenze sofort; der neue Monatspreis wird ab der nächsten Verlängerung berechnet. Die Kündigung zum kostenlosen Tarif wirkt zum Ende der laufenden Abrechnungsperiode. Details stehen unter <a href="preise.php">Preise</a>.</small></p>
<?php if (($billing['stripe_customer_id'] ?? null) !== null): ?>
<form method="post" action="abo-portal.php">
<?php echo app_csrf_field(); ?>
<button type="submit">Zahlungsmethode verwalten</button>
</form>
<?php endif; ?>
<h3>Protokoll</h3>
<p>Die letzten Admin-Aktionen für diesen Mandanten.</p>
<table>
<tr><th>Datum</th><th>Wer</th><th>Aktion</th><th>Betrifft</th></tr>
<?php if ($auditLog === []): ?>
<tr><td colspan="4">Noch keine protokollierten Aktionen.</td></tr>
<?php endif; ?>
<?php foreach ($auditLog as $eintrag): ?>
<tr>
<td><?php echo saas_html($eintrag['created_at']); ?></td>
<td><?php echo saas_html($eintrag['actor_name'] ?? '—'); ?></td>
<td><?php echo saas_html($eintrag['action']); ?></td>
<td><?php echo saas_html($eintrag['subject_type']); ?><?php echo $eintrag['subject_id'] !== null ? ' #' . (int)$eintrag['subject_id'] : ''; ?></td>
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>
</div>
</section>
<?php include 'footer.php'; ?>