Ustawienia powiadomień faktur cyklicznych

This commit is contained in:
2026-07-30 00:23:02 +02:00
parent e6ba6152a6
commit 8b92aac1db
3 changed files with 342 additions and 1 deletions
@@ -0,0 +1,324 @@
<?php
$enablePrototypeComments = true;
include '../../header-invoice.php';
?>
<div class="container-fluid flex-grow-1 container-p-y">
<h4 class="py-3 mb-4">
<span class="text-muted fw-light">Sprzedaż / Ustawienia /</span> Powiadomienia e-mail (Faktury cykliczne)
</h4>
<div class="row">
<!-- Lewa Kolumna: Konfigurator -->
<div class="col-lg-5 mb-4 mb-lg-0">
<!-- Wybór Profilu -->
<div class="card mb-4">
<div class="card-header border-bottom d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">Wybierz Profil Powiadomień</h5>
<div class="d-flex gap-2">
<button class="btn btn-sm btn-label-danger"><i class="bx bx-trash me-1"></i> Usuń profil</button>
<button class="btn btn-sm btn-primary"><i class="bx bx-plus me-1"></i> Nowy profil</button>
</div>
</div>
<div class="card-body pt-4">
<div class="mb-3">
<label class="form-label">Aktualny profil</label>
<select class="form-select select2" id="profile-select">
<option value="1">Standardowy (Termin 30 dni)</option>
<option value="2">Szybki (Termin 3 dni)</option>
<option value="3">Tylko przypomnienia po terminie</option>
</select>
<div class="form-text">Zmiany wprowadzane poniżej zapiszą się dla wybranego profilu.</div>
</div>
</div>
</div>
<!-- Harmonogram wysyłki -->
<div class="card mb-4">
<div class="card-header border-bottom d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">Harmonogram wysyłki</h5>
<button class="btn btn-sm btn-label-primary" data-bs-toggle="modal" data-bs-target="#modalRule"><i class="bx bx-plus me-1"></i> Dodaj regułę</button>
</div>
<div class="card-body pt-4">
<ul class="list-group list-group-flush mb-0">
<li class="list-group-item d-flex justify-content-between align-items-center px-0 pt-0 pb-3" style="cursor: pointer;">
<div class="d-flex align-items-center gap-2">
<span class="badge bg-label-success p-2"><i class="bx bx-check"></i></span>
<div>
<h6 class="mb-0">Wystawienie faktury</h6>
<small class="text-muted">Natychmiast (W dniu dokumentu)</small>
</div>
</div>
<button class="btn btn-icon btn-sm text-secondary" data-bs-toggle="modal" data-bs-target="#modalRule"><i class="bx bx-edit"></i></button>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center px-3 py-3 rounded border border-primary bg-label-primary mb-2 mt-2" style="cursor: pointer;">
<div class="d-flex align-items-center gap-2">
<span class="badge bg-primary p-2 text-white"><i class="bx bx-time"></i></span>
<div>
<h6 class="mb-0 text-primary fw-bold">Przypomnienie przed terminem</h6>
<small class="text-primary">14 dni przed upływem terminu</small>
</div>
</div>
<button class="btn btn-icon btn-sm text-primary" data-bs-toggle="modal" data-bs-target="#modalRule"><i class="bx bx-edit"></i></button>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center px-0 py-3" style="cursor: pointer;">
<div class="d-flex align-items-center gap-2">
<span class="badge bg-label-warning p-2"><i class="bx bx-error"></i></span>
<div>
<h6 class="mb-0">Przypomnienie przed terminem</h6>
<small class="text-muted">3 dni przed upływem terminu</small>
</div>
</div>
<button class="btn btn-icon btn-sm text-secondary" data-bs-toggle="modal" data-bs-target="#modalRule"><i class="bx bx-edit"></i></button>
</li>
</ul>
</div>
</div>
<!-- Treść wiadomości -->
<div class="card border border-primary">
<div class="card-header border-bottom bg-label-primary">
<h5 class="card-title mb-0 text-primary">Treść wiadomości <span class="fw-normal fs-6 d-block mt-1">Edytujesz: <strong>Przypomnienie przed terminem (14 dni)</strong></span></h5>
</div>
<div class="card-body pt-4">
<div class="mb-3">
<label class="form-label">Temat e-maila</label>
<input type="text" id="email-subject" class="form-control" value="Przypomnienie: Zbliża się termin płatności faktury {NUMER_FAKTURY}">
<div class="form-text">Zmienne: {NUMER_FAKTURY}, {NAZWA_KLIENTA}</div>
</div>
<div class="mb-3">
<label class="form-label">Nagłówek powitania</label>
<input type="text" id="email-heading" class="form-control" value="Cześć {IMIE_NABYWCY},">
</div>
<div class="mb-3">
<label class="form-label">Główna treść wiadomości</label>
<textarea id="email-body" class="form-control" rows="4">Przypominamy, że za 14 dni upływa termin płatności za Twoją ostatnią fakturę. W załączniku przesyłamy plik PDF z dokumentem. Będziemy wdzięczni za terminową wpłatę.</textarea>
</div>
<div class="mb-0">
<label class="form-label">Podpis / Stopka</label>
<input type="text" id="email-footer" class="form-control" value="Pozdrawiamy serdecznie,\nZespół TwojaFirma">
</div>
<!-- Zmienne do kliknięcia -->
<div class="mt-4 pt-3 border-top">
<small class="text-muted text-uppercase fw-bold d-block mb-2">Dostępne zmienne (kliknij, aby wstawić)</small>
<div class="d-flex flex-wrap gap-2" id="variable-badges">
<span class="badge bg-label-primary" style="cursor: pointer;" data-var="{NUMER_FAKTURY}">+ {NUMER_FAKTURY}</span>
<span class="badge bg-label-primary" style="cursor: pointer;" data-var="{NAZWA_KLIENTA}">+ {NAZWA_KLIENTA}</span>
<span class="badge bg-label-primary" style="cursor: pointer;" data-var="{IMIE_NABYWCY}">+ {IMIE_NABYWCY}</span>
<span class="badge bg-label-primary" style="cursor: pointer;" data-var="{KWOTA_BRUTTO}">+ {KWOTA_BRUTTO}</span>
<span class="badge bg-label-primary" style="cursor: pointer;" data-var="{TERMIN_PLATNOSCI}">+ {TERMIN_PLATNOSCI}</span>
<span class="badge bg-label-primary" style="cursor: pointer;" data-var="{POZOSTALO_DNI_DO_TERMINU}">+ {POZOSTALO_DNI_DO_TERMINU}</span>
<span class="badge bg-label-primary" style="cursor: pointer;" data-var="{LINK_DO_OPLATY}">+ {LINK_DO_OPLATY}</span>
</div>
<div class="form-text mt-2">Tag zostanie wstawiony w polu, w którym ostatnio pisałeś.</div>
</div>
</div>
</div>
</div>
<!-- Prawa Kolumna: Podgląd Live -->
<div class="col-lg-7">
<div class="card h-100" style="background-color: #f8f9fa;">
<div class="card-header border-bottom bg-white d-flex justify-content-between align-items-center">
<div>
<small class="text-muted d-block mb-1">Podgląd na żywo</small>
<h6 class="mb-0">Temat: <span id="preview-subject" class="fw-normal">Przypomnienie: Zbliża się termin płatności faktury FV/2026/08/12</span></h6>
</div>
<span class="badge bg-label-secondary">Wersja Desktop</span>
</div>
<!-- Email Canvas -->
<div class="card-body d-flex justify-content-center align-items-start pt-5 pb-5 overflow-auto" style="min-height: 600px;">
<div class="email-container bg-white rounded shadow-sm" style="width: 100%; max-width: 600px; overflow: hidden; font-family: Arial, sans-serif;">
<!-- Email Header Logo -->
<div class="bg-primary text-center py-4 text-white">
<h3 class="mb-0 fw-bold text-white"><i class="bx bxl-sketch fs-2 align-middle mb-1 me-1"></i> TwojaFirma</h3>
</div>
<!-- Email Content Container -->
<div class="p-4 p-md-5">
<h4 id="preview-heading" class="fw-bold mb-3" style="color: #333;">Cześć Jan,</h4>
<p id="preview-body" style="color: #555; line-height: 1.6; margin-bottom: 30px;">
Przypominamy, że za 14 dni upływa termin płatności za Twoją ostatnią fakturę. W załączniku przesyłamy plik PDF z dokumentem. Będziemy wdzięczni za terminową wpłatę.
</p>
<!-- ZABLOKOWANY MODUŁ Z FAKTURĄ (LOCKED SUMMARY TABLE) -->
<div class="invoice-summary border rounded bg-lighter p-4 mb-4 text-center">
<small class="text-muted fw-bold d-block mb-2 text-uppercase">Szczegóły Faktury</small>
<h3 class="mb-2 text-primary">1 845,00 PLN</h3>
<p class="mb-0 text-muted">Termin: <strong>15.08.2026</strong></p>
<hr class="my-3">
<div class="d-flex justify-content-between align-items-center mb-2 text-start">
<span class="text-muted">Numer:</span>
<span class="fw-medium">FV/2026/08/12</span>
</div>
<div class="d-flex justify-content-between align-items-center mb-3 text-start">
<span class="text-muted">Do zapłaty:</span>
<span class="fw-medium text-danger">1 845,00 PLN</span>
</div>
<a href="#" class="btn btn-primary w-100 mt-2" style="padding: 10px 20px; text-decoration: none; display: inline-block;">
Zobacz dokument i opłać online
</a>
</div>
<!-- END LOCKED MODULE -->
<p id="preview-footer" style="color: #777; margin-top: 30px; font-size: 0.95em;">
Pozdrawiamy serdecznie,<br>Zespół TwojaFirma
</p>
</div>
<!-- Email Footer App Info -->
<div class="bg-lighter text-center py-3">
<small class="text-muted">Wiadomość wygenerowana automatycznie przez system Magico ERP.</small>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal: Dodaj Regułę -->
<div class="modal fade" id="modalRule" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalRuleTitle">Konfiguracja reguły wysyłki</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row">
<div class="col mb-3">
<label class="form-label">Wydarzenie początkowe (Wyzwalacz)</label>
<select class="form-select">
<option value="issue">Wystawienie nowej faktury</option>
<option value="due">Termin płatności faktury</option>
</select>
</div>
</div>
<div class="row g-2">
<div class="col mb-0">
<label class="form-label">Kiedy wysłać e-mail?</label>
<select class="form-select">
<option value="0">Dokładnie w tym dniu</option>
<option value="before">Przed wydarzeniem</option>
<option value="after">Po wydarzeniu</option>
</select>
</div>
<div class="col mb-0">
<label class="form-label">Ile dni?</label>
<input type="number" class="form-control" value="0">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-label-secondary" data-bs-dismiss="modal">Anuluj</button>
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">Zapisz regułę</button>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Inputs
const inputSubject = document.getElementById('email-subject');
const inputHeading = document.getElementById('email-heading');
const inputBody = document.getElementById('email-body');
const inputFooter = document.getElementById('email-footer');
// Previews
const previewSubject = document.getElementById('preview-subject');
const previewHeading = document.getElementById('preview-heading');
const previewBody = document.getElementById('preview-body');
const previewFooter = document.getElementById('preview-footer');
// Mocks for variables
const mockVars = {
'{NUMER_FAKTURY}': 'FV/2026/08/12',
'{NAZWA_KLIENTA}': 'ABC Logistics',
'{IMIE_NABYWCY}': 'Jan',
'{KWOTA_BRUTTO}': '1 845,00 PLN',
'{TERMIN_PLATNOSCI}': '15.08.2026',
'{POZOSTALO_DNI_DO_TERMINU}': '14',
'{LINK_DO_OPLATY}': 'https://magico.pl/pay/123'
};
function replaceVariables(text) {
let result = text;
for (const [key, value] of Object.entries(mockVars)) {
result = result.replace(new RegExp(key, 'g'), value);
}
return result;
}
function updatePreview() {
previewSubject.innerText = replaceVariables(inputSubject.value);
previewHeading.innerText = replaceVariables(inputHeading.value);
// Preserve line breaks in body
const bodyText = replaceVariables(inputBody.value);
previewBody.innerHTML = bodyText.replace(/\n/g, '<br>');
// Preserve line breaks in footer
const footerText = replaceVariables(inputFooter.value);
previewFooter.innerHTML = footerText.replace(/\n/g, '<br>');
}
// Event Listeners
inputSubject.addEventListener('input', updatePreview);
inputHeading.addEventListener('input', updatePreview);
inputBody.addEventListener('input', updatePreview);
inputFooter.addEventListener('input', updatePreview);
// Initial render
updatePreview();
// Variable insertion logic
let lastFocusedInput = inputBody; // default
const allInputs = [inputSubject, inputHeading, inputBody, inputFooter];
allInputs.forEach(input => {
input.addEventListener('focus', function() {
lastFocusedInput = this;
});
});
document.querySelectorAll('#variable-badges .badge').forEach(badge => {
badge.addEventListener('click', function() {
const varText = this.getAttribute('data-var');
if (lastFocusedInput) {
const start = lastFocusedInput.selectionStart;
const end = lastFocusedInput.selectionEnd;
const text = lastFocusedInput.value;
lastFocusedInput.value = text.substring(0, start) + varText + text.substring(end);
lastFocusedInput.selectionStart = lastFocusedInput.selectionEnd = start + varText.length;
lastFocusedInput.focus();
updatePreview();
}
});
});
});
</script>
<?php include '../../footer.php'; ?>