Globinours/app/Views/settings_pricing.php

195 lines
13 KiB
PHP

<?php require __DIR__ . '/settings_nav.php'; ?>
<div class="mb-3">
<h2 class="mb-1"><?= h(t('pricing.heading')) ?></h2>
<div class="text-muted"><?= h(t('pricing.intro')) ?></div>
</div>
<?php if ($saved): ?><div class="alert alert-success">✅ <?= h(t('pricing.saved')) ?></div>
<?php endif; ?><?php if ($error !== ''): ?><div class="alert alert-danger"><?= h($error) ?></div><?php endif; ?>
<div class="row row-cards mb-4">
<div class="col-lg-7">
<form class="card h-100" method="post" action="/settings/pricing/adoption">
<div class="card-status-top bg-green"></div>
<div class="card-header">
<div>
<h3 class="card-title"><?= h(t('pricing.adoption_fees')) ?></h3>
<div class="text-muted small"><?= h(t('pricing.adoption_fees_help')) ?></div>
</div>
</div>
<div class="table-responsive">
<table class="table table-vcenter mb-0"><thead><tr><th><?= h(t('animal.species')) ?></th><th><?= h(t('pricing.before_sterilization')) ?></th><th><?= h(t('pricing.after_sterilization')) ?></th><th><?= h(t('pricing.free_fee')) ?></th></tr></thead><tbody>
<?php foreach ($adoptionFees as $species => $fee): ?><tr><td class="fw-semibold"><?= h(($fee['icon'] ?? '') . ' ' . $fee['name']) ?></td>
<td><div class="input-group"><input class="form-control" type="number" min="0" max="2000" name="fees[<?= h($species) ?>][before]" value="<?= (int)$fee['fee_before_sterilization'] ?>"><span class="input-group-text">€</span></div></td>
<td><div class="input-group"><input class="form-control" type="number" min="0" max="2000" name="fees[<?= h($species) ?>][after]" value="<?= (int)$fee['fee_after_sterilization'] ?>"><span class="input-group-text">€</span></div></td>
<td><label class="form-check form-switch"><input class="form-check-input adoption-fee-free" type="checkbox" name="fees[<?= h($species) ?>][free]" <?= (int)$fee['is_free'] === 1 ? 'checked' : '' ?>><span class="form-check-label"><?= h(t('pricing.free')) ?></span></label></td>
</tr><?php endforeach; ?>
</tbody></table>
</div>
<div class="card-footer text-end"><button class="btn btn-primary"><?= h(t('common.save')) ?></button></div>
</form>
</div>
<div class="col-lg-5">
<div class="card h-100">
<div class="card-status-top bg-orange"></div>
<div class="card-header">
<div>
<h3 class="card-title"><?= h(t('pricing.discounts')) ?></h3>
<div class="text-muted small"><?= h(t('pricing.discounts_help')) ?></div>
</div>
</div>
<div class="list-group list-group-flush">
<?php foreach ($clinics as $c):$clinicRules = $discounts[(int)$c['id']] ?? []; ?><div
class="list-group-item py-3">
<div class="d-flex align-items-center gap-3">
<div class="me-auto text-truncate">
<div class="fw-bold text-truncate"><?= h($c['name']) ?></div>
<div class="d-flex flex-wrap gap-1 mt-1"><?php foreach ($groups as $code => $label):if ($code === 'none') {
continue;
}$value = (float)($clinicRules[$code]['percent'] ?? 0);
if ($value <= 0) {
continue;
}?><span class="badge bg-orange-lt"><?= h(PricingService::groupLabel($code)) ?> ·
<?= number_format($value, 0, ',', ' ') ?>
%</span><?php endforeach; ?><?php if (!array_filter($clinicRules, static fn ($r) => (float)$r['percent'] > 0)): ?><span
class="text-muted small"><?= h(t('pricing.no_discount')) ?></span><?php endif; ?>
</div>
</div><button class="btn btn-outline-secondary btn-sm" type="button" data-bs-toggle="modal"
data-bs-target="#discountModal<?= (int)$c['id'] ?>"><?= h(t('pricing.configure')) ?></button>
</div>
</div><?php endforeach; ?><?php if (!$clinics): ?><div class="card-body text-muted">
<?= h(t('pricing.no_structure')) ?></div><?php endif; ?></div>
</div>
</div>
</div>
<?php foreach ($clinics as $c):$clinicRules = $discounts[(int)$c['id']] ?? []; ?><div class="modal modal-blur fade"
id="discountModal<?= (int)$c['id'] ?>" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<form class="modal-content" method="post" action="/settings/pricing/discount"><input type="hidden"
name="clinic_contact_id" value="<?= (int)$c['id'] ?>">
<div class="modal-header">
<div>
<h5 class="modal-title"><?= h(t('pricing.discount_for', ['name' => $c['name']])) ?></h5>
<div class="text-muted small"><?= h(t('pricing.future_help')) ?></div>
</div><button class="btn-close" type="button" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="vstack gap-3"><?php foreach ($groups as $code => $label):if ($code === 'none') {
continue;
}$value = $clinicRules[$code]['percent'] ?? 0; ?><div class="row align-items-center"><label
class="col form-label mb-0"><?= h(PricingService::groupLabel($code)) ?></label>
<div class="col-5">
<div class="input-group"><input class="form-control" name="discounts[<?= h($code) ?>]"
type="number" min="0" max="100" step="0.01" value="<?= h((string)$value) ?>"><span
class="input-group-text">%</span></div>
</div>
</div><?php endforeach; ?></div>
<div class="alert alert-info py-2 mt-3 mb-0 small"><?= h(t('pricing.antibiotic_help')) ?></div>
</div>
<div class="modal-footer"><button class="btn me-auto" type="button"
data-bs-dismiss="modal"><?= h(t('common.cancel')) ?></button><button
class="btn btn-primary"><?= h(t('pricing.save_discounts')) ?></button></div>
</form>
</div>
</div><?php endforeach; ?>
<div class="card mb-4">
<div class="card-status-top bg-blue"></div>
<div class="card-header">
<div>
<h3 class="card-title"><?= h(t('pricing.add_label')) ?></h3>
<div class="text-muted small"><?= h(t('pricing.add_label_help')) ?></div>
</div>
</div>
<form method="post" action="/settings/pricing/tariff" id="tariffForm">
<input type="hidden" name="id" id="tariffId" value="0">
<div class="card-body row g-3">
<div class="col-md-4"><label class="form-label required"><?= h(t('pricing.structure')) ?></label><select
class="form-select" name="clinic_contact_id" id="tariffClinic" required>
<option value="">—</option><?php foreach ($clinics as $c): ?><option value="<?= (int)$c['id'] ?>">
<?= h($c['name']) ?></option><?php endforeach; ?>
</select></div>
<div class="col-md-5"><label class="form-label required"><?= h(t('pricing.label')) ?></label><input
class="form-control" name="label" id="tariffLabel" required placeholder="<?= h(t('pricing.label_example')) ?>"></div>
<div class="col-md-3"><label class="form-label"><?= h(t('pricing.catalog_price')) ?></label>
<div class="input-group"><input class="form-control" name="amount" id="tariffAmount" inputmode="decimal" required><span
class="input-group-text">€</span></div>
</div>
<div class="col-md-3"><label class="form-label"><?= h(t('settings.category')) ?></label><select
class="form-select" name="category" id="tariffCategory"><?php foreach ($categories as $k => $v): ?><option
value="<?= h($k) ?>"><?= h(PricingService::categoryLabel($k)) ?></option>
<?php endforeach; ?></select></div>
<div class="col-md-3"><label class="form-label"><?= h(t('pricing.discount_group')) ?></label><select
class="form-select" name="discount_group" id="tariffGroup"><?php foreach ($groups as $k => $v): ?><option
value="<?= h($k) ?>"><?= h(PricingService::groupLabel($k)) ?></option>
<?php endforeach; ?></select></div>
<div class="col-md-2"><label class="form-label"><?= h(t('pricing.unit')) ?></label><input
class="form-control" name="unit_label" id="tariffUnit" value="acte"></div>
<div class="col-md-4"><label class="form-label"><?= h(t('pricing.linked_medication')) ?> <span
class="text-muted">(<?= h(t('common.optional')) ?>)</span></label><select class="form-select"
name="medication_id" id="tariffMedication">
<option value="">—</option><?php foreach ($medications as $m): ?><option
value="<?= (int)$m['id'] ?>"><?= h($m['name']) ?></option><?php endforeach; ?>
</select></div>
<div class="col-12"><label class="form-check"><input class="form-check-input" type="checkbox" name="active" id="tariffActive"
checked><span class="form-check-label"><?= h(t('pricing.active_tariff')) ?></span></label></div>
</div>
<div class="card-footer text-end"><button class="btn btn-primary"><?= h(t('pricing.add_tariff')) ?></button>
</div>
</form>
</div>
<div class="card">
<div class="card-header">
<h3 class="card-title"><?= h(t('pricing.grid')) ?></h3>
</div>
<div class="table-responsive">
<table class="table table-vcenter table-hover mb-0">
<thead>
<tr>
<th><?= h(t('pricing.structure')) ?></th>
<th><?= h(t('pricing.label')) ?></th>
<th><?= h(t('settings.category')) ?></th>
<th><?= h(t('pricing.discount')) ?></th>
<th class="text-end"><?= h(t('pricing.catalog')) ?></th>
<th class="text-end"><?= h(t('pricing.estimated_cost')) ?></th>
<th><?= h(t('pricing.state')) ?></th>
</tr>
</thead>
<tbody><?php foreach ($tariffs as $t): ?><tr class="tariff-edit cursor-pointer" tabindex="0"
aria-label="<?= h(t('pricing.edit_tariff') . ' : ' . $t['label']) ?>"
data-id="<?= (int)$t['id'] ?>" data-clinic="<?= (int)$t['clinic_contact_id'] ?>"
data-label="<?= h($t['label']) ?>" data-amount="<?= h(number_format($t['amount_cents'] / 100, 2, '.', '')) ?>"
data-category="<?= h($t['category']) ?>" data-group="<?= h($t['discount_group']) ?>"
data-unit="<?= h($t['unit_label']) ?>" data-medication="<?= (int)($t['medication_id'] ?? 0) ?>"
data-active="<?= (int)$t['active'] ?>">
<td><?= h($t['clinic_name']) ?></td>
<td class="fw-semibold"><?= h($t['label']) ?><div class="text-muted small">
<?= h(t('pricing.per_unit', ['unit' => $t['unit_label']])) ?></div>
</td>
<td><?= h(PricingService::categoryLabel($t['category'])) ?></td>
<td><?= h(PricingService::groupLabel($t['discount_group'])) ?> ·
<?= number_format((float)$t['discount_percent'], 2, ',', ' ') ?> %</td>
<td class="text-end"><?= number_format($t['amount_cents'] / 100, 2, ',', ' ') ?> €</td>
<td class="text-end fw-bold"><?= number_format($t['effective_cents'] / 100, 2, ',', ' ') ?> €</td>
<td><span
class="badge <?= $t['active'] ? 'bg-green-lt' : 'bg-secondary-lt' ?>"><?= $t['active'] ? t('pricing.active') : t('pricing.inactive') ?></span>
</td>
</tr><?php endforeach; ?></tbody>
</table>
</div>
</div>
<script>
const editTariff = (row) => {
const fields = {tariffId:'id',tariffClinic:'clinic',tariffLabel:'label',tariffAmount:'amount',tariffCategory:'category',tariffGroup:'group',tariffUnit:'unit',tariffMedication:'medication'};
Object.entries(fields).forEach(([id, key]) => { document.getElementById(id).value = row.dataset[key] || ''; });
document.getElementById('tariffActive').checked = row.dataset.active === '1';
document.getElementById('tariffForm').scrollIntoView({behavior:'smooth', block:'start'});
document.getElementById('tariffLabel').focus({preventScroll:true});
};
document.querySelectorAll('.tariff-edit').forEach((row) => {
row.addEventListener('click', () => editTariff(row));
row.addEventListener('keydown', (event) => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
editTariff(row);
}
});
});
</script>