zmiana waluty w .env
This commit is contained in:
@@ -195,4 +195,10 @@ UPLOADS_CACHE_CONTROL="max-age=3600, immutable"
|
||||
# UWAGA: wielkość liter w nazwach jest zachowywana, ale porównywanie odbywa się
|
||||
# bez rozróżniania wielkości liter (case-insensitive).
|
||||
# Domyślnie: poniższa lista
|
||||
DEFAULT_CATEGORIES="Spożywcze,Budowlane,Zabawki,Chemia,Inne,Elektronika,Odzież i obuwie,Artykuły biurowe,Kosmetyki i higiena,Motoryzacja,Ogród i rośliny,Zwierzęta,Sprzęt sportowy,Książki i prasa,Narzędzia i majsterkowanie,RTV / AGD,Apteka i suplementy,Artykuły dekoracyjne,Gry i hobby,Usługi,Pieczywo"
|
||||
DEFAULT_CATEGORIES="Spożywcze,Budowlane,Zabawki,Chemia,Inne,Elektronika,Odzież i obuwie,Artykuły biurowe,Kosmetyki i higiena,Motoryzacja,Ogród i rośliny,Zwierzęta,Sprzęt sportowy,Książki i prasa,Narzędzia i majsterkowanie,RTV / AGD,Apteka i suplementy,Artykuły dekoracyjne,Gry i hobby,Usługi,Pieczywo"
|
||||
|
||||
# Waluta używana w całej aplikacji (kwoty, paragony, analizy)
|
||||
# Użyj kodu ISO 4217 (np. PLN, EUR, USD, GBP)
|
||||
# Domyślnie: PLN (jeśli zmienna nie jest ustawiona)
|
||||
|
||||
CURRENCY_CODE=PLN
|
||||
@@ -91,6 +91,8 @@ class Config:
|
||||
DEBUG_MODE = env_bool("DEBUG_MODE", True)
|
||||
DISABLE_ROBOTS = env_bool("DISABLE_ROBOTS", False)
|
||||
|
||||
CURRENCY_CODE = env_str("CURRENCY_CODE", "PLN").strip().upper() or "PLN"
|
||||
|
||||
JS_CACHE_CONTROL = env_str("JS_CACHE_CONTROL", "no-cache")
|
||||
CSS_CACHE_CONTROL = env_str("CSS_CACHE_CONTROL", "no-cache")
|
||||
LIB_JS_CACHE_CONTROL = env_str("LIB_JS_CACHE_CONTROL", "max-age=604800")
|
||||
|
||||
@@ -2,6 +2,25 @@ from .deps import *
|
||||
from .app_setup import *
|
||||
from .models import *
|
||||
|
||||
|
||||
def get_currency_code() -> str:
|
||||
code = str(app.config.get("CURRENCY_CODE", "PLN") or "PLN").strip().upper()
|
||||
return code or "PLN"
|
||||
|
||||
|
||||
def format_currency(amount, include_code: bool = True) -> str:
|
||||
try:
|
||||
normalized = float(amount or 0)
|
||||
except (TypeError, ValueError):
|
||||
normalized = 0.0
|
||||
formatted = f"{normalized:.2f}"
|
||||
return f"{formatted} {get_currency_code()}" if include_code else formatted
|
||||
|
||||
|
||||
def currency_placeholder(prefix: str = "Kwota") -> str:
|
||||
return f"{prefix} ({get_currency_code()})"
|
||||
|
||||
|
||||
def get_setting(key: str, default: str | None = None) -> str | None:
|
||||
s = db.session.get(AppSetting, key)
|
||||
return s.value if s else default
|
||||
|
||||
@@ -453,7 +453,7 @@ def handle_add_expense(data):
|
||||
)
|
||||
|
||||
db.session.add(new_expense)
|
||||
log_list_activity(list_id, 'expense_added', item_name=None, actor=current_user if current_user.is_authenticated else None, actor_name=current_user.username if current_user.is_authenticated else 'Gość', details=f'kwota: {float(amount):.2f} PLN')
|
||||
log_list_activity(list_id, 'expense_added', item_name=None, actor=current_user if current_user.is_authenticated else None, actor_name=current_user.username if current_user.is_authenticated else 'Gość', details=f'kwota: {format_currency(amount)}')
|
||||
db.session.commit()
|
||||
|
||||
total = (
|
||||
|
||||
@@ -123,7 +123,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
data: {
|
||||
labels: data.labels || [],
|
||||
datasets: [{
|
||||
label: "Suma wydatków [PLN]",
|
||||
label: `Suma wydatków [${getCurrencyCode()}]`,
|
||||
data: data.expenses || [],
|
||||
}],
|
||||
},
|
||||
|
||||
@@ -28,7 +28,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
total += parseFloat(cb.dataset.amount);
|
||||
}
|
||||
});
|
||||
totalEl.textContent = total.toFixed(2) + ' PLN';
|
||||
totalEl.textContent = formatCurrencyAmount(total);
|
||||
}
|
||||
|
||||
function getISOWeek(date) {
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
function getCurrencyCode() {
|
||||
return window.CURRENCY_CODE || 'PLN';
|
||||
}
|
||||
|
||||
function formatCurrencyAmount(amount, options = {}) {
|
||||
const includeCode = options.includeCode !== false;
|
||||
const numeric = Number(amount || 0);
|
||||
const safe = Number.isFinite(numeric) ? numeric : 0;
|
||||
const formatted = safe.toFixed(2);
|
||||
return includeCode ? `${formatted} ${getCurrencyCode()}` : formatted;
|
||||
}
|
||||
|
||||
function currencyLabel(prefix = 'Kwota') {
|
||||
return `${prefix} (${getCurrencyCode()})`;
|
||||
}
|
||||
|
||||
function updateItemState(itemId, isChecked) {
|
||||
const checkbox = document.querySelector(`#item-${itemId} input[type='checkbox']`);
|
||||
if (checkbox) {
|
||||
|
||||
@@ -113,7 +113,7 @@ function setupList(listId, username) {
|
||||
socket.on('expense_added', data => {
|
||||
const badgeEl = document.getElementById('total-expense1');
|
||||
if (badgeEl) {
|
||||
badgeEl.innerHTML = `💸 ${data.total.toFixed(2)} PLN`;
|
||||
badgeEl.innerHTML = `💸 ${formatCurrencyAmount(data.total)}`;
|
||||
badgeEl.classList.remove('bg-secondary');
|
||||
badgeEl.classList.add('bg-success');
|
||||
badgeEl.style.display = '';
|
||||
@@ -121,10 +121,10 @@ function setupList(listId, username) {
|
||||
|
||||
const summaryEl = document.getElementById('total-expense2');
|
||||
if (summaryEl) {
|
||||
summaryEl.innerHTML = `<b>💸 Łącznie wydano:</b> ${data.total.toFixed(2)} PLN`;
|
||||
summaryEl.innerHTML = `<b>💸 Łącznie wydano:</b> ${formatCurrencyAmount(data.total)}`;
|
||||
}
|
||||
|
||||
showToast(`Dodano wydatek: ${data.amount.toFixed(2)} PLN`, 'info');
|
||||
showToast(`Dodano wydatek: ${formatCurrencyAmount(data.amount)}`, 'info');
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
summary.innerHTML = `
|
||||
<p class="mb-1">📦 <strong>${totalCount}</strong> produktów</p>
|
||||
<p class="mb-1">✅ Kupione: <strong>${purchasedCount}</strong> (${percent}%)</p>
|
||||
<p class="mb-0">💸 Wydatek: <strong>${totalExpense.toFixed(2)} zł</strong></p>`;
|
||||
<p class="mb-0">💸 Wydatek: <strong>${formatCurrencyAmount(totalExpense)}</strong></p>`;
|
||||
productList.appendChild(summary);
|
||||
|
||||
const purchased = createSection("✔️ Kupione");
|
||||
|
||||
@@ -22,7 +22,7 @@ async function analyzeReceipts(listId) {
|
||||
|
||||
let html = `<div class="card bg-dark text-white border-secondary p-3">`;
|
||||
html += `<p class="text-secondary"><small>⏱ Czas analizy OCR: ${duration} sek.</small></p>`;
|
||||
html += `<p><b>📊 Łącznie wykryto:</b> ${data.total.toFixed(2)} PLN</p>`;
|
||||
html += `<p><b>📊 Łącznie wykryto:</b> ${formatCurrencyAmount(data.total)}</p>`;
|
||||
|
||||
data.results.forEach((r, i) => {
|
||||
const disabled = r.already_added ? "disabled" : "";
|
||||
|
||||
@@ -12,7 +12,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
total += parseFloat(cb.dataset.amount);
|
||||
}
|
||||
});
|
||||
totalEl.textContent = total.toFixed(2) + ' PLN';
|
||||
totalEl.textContent = formatCurrencyAmount(total);
|
||||
}
|
||||
|
||||
selectAllBtn.addEventListener('click', () => {
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
<span class="progress-label main-list-progress__label small fw-bold {% if percent < 51 %}text-white{% else %}text-dark{% endif %}">
|
||||
Produkty: {{ purchased_count }}/{{ total_count }} ({{ percent|round(0)|int }}%)
|
||||
{% if total_expense > 0 %} — 💸 {{ '%.2f'|format(total_expense) }} PLN{% endif %}
|
||||
{% if total_expense > 0 %} — 💸 {{ format_currency(total_expense) }}{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -51,7 +51,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>💸 Średnia kwota na listę</td>
|
||||
<td class="text-end fw-bold">{{ avg_list_expense }} zł</td>
|
||||
<td class="text-end fw-bold">{{ format_currency(avg_list_expense) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -115,30 +115,30 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Wszystkie</td>
|
||||
<td>{{ '%.2f'|format(expense_summary.all.month) }} PLN</td>
|
||||
<td>{{ '%.2f'|format(expense_summary.all.year) }} PLN</td>
|
||||
<td>{{ '%.2f'|format(expense_summary.all.total) }} PLN</td>
|
||||
<td>{{ format_currency(expense_summary.all.month) }}</td>
|
||||
<td>{{ format_currency(expense_summary.all.year) }}</td>
|
||||
<td>{{ format_currency(expense_summary.all.total) }}</td>
|
||||
<!-- <td>{{ '%.2f'|format(expense_summary.all.avg) }} PLN</td> -->
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Aktywne</td>
|
||||
<td>{{ '%.2f'|format(expense_summary.active.month) }} PLN</td>
|
||||
<td>{{ '%.2f'|format(expense_summary.active.year) }} PLN</td>
|
||||
<td>{{ '%.2f'|format(expense_summary.active.total) }} PLN</td>
|
||||
<td>{{ format_currency(expense_summary.active.month) }}</td>
|
||||
<td>{{ format_currency(expense_summary.active.year) }}</td>
|
||||
<td>{{ format_currency(expense_summary.active.total) }}</td>
|
||||
<!-- <td>{{ '%.2f'|format(expense_summary.active.avg) }} PLN</td> -->
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Archiwalne</td>
|
||||
<td>{{ '%.2f'|format(expense_summary.archived.month) }} PLN</td>
|
||||
<td>{{ '%.2f'|format(expense_summary.archived.year) }} PLN</td>
|
||||
<td>{{ '%.2f'|format(expense_summary.archived.total) }} PLN</td>
|
||||
<td>{{ format_currency(expense_summary.archived.month) }}</td>
|
||||
<td>{{ format_currency(expense_summary.archived.year) }}</td>
|
||||
<td>{{ format_currency(expense_summary.archived.total) }}</td>
|
||||
<!-- <td>{{ '%.2f'|format(expense_summary.archived.avg) }} PLN</td> -->
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Wygasłe</td>
|
||||
<td>{{ '%.2f'|format(expense_summary.expired.month) }} PLN</td>
|
||||
<td>{{ '%.2f'|format(expense_summary.expired.year) }} PLN</td>
|
||||
<td>{{ '%.2f'|format(expense_summary.expired.total) }} PLN</td>
|
||||
<td>{{ format_currency(expense_summary.expired.month) }}</td>
|
||||
<td>{{ format_currency(expense_summary.expired.year) }}</td>
|
||||
<td>{{ format_currency(expense_summary.expired.total) }}</td>
|
||||
<!-- <td>{{ '%.2f'|format(expense_summary.expired.avg) }} PLN</td> -->
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -282,7 +282,7 @@
|
||||
{% if e.total_expense >= 500 %}text-danger
|
||||
{% elif e.total_expense > 0 %}text-success{% endif %}">
|
||||
{% if e.total_expense > 0 %}
|
||||
{{ '%.2f'|format(e.total_expense) }} PLN
|
||||
{{ format_currency(e.total_expense) }}
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<!-- Wydatek i właściciel -->
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-6">
|
||||
<label for="amount" class="form-label">💰 Całkowity wydatek (PLN)</label>
|
||||
<label for="amount" class="form-label">💰 Całkowity wydatek ({{ CURRENCY_CODE }})</label>
|
||||
<input type="number" step="0.01" min="0" class="form-control bg-dark text-white border-secondary ui-consistent-input"
|
||||
id="amount" name="amount" value="{{ '%.2f'|format(total_expense) }}">
|
||||
</div>
|
||||
|
||||
@@ -173,6 +173,10 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
window.CURRENCY_CODE = {{ CURRENCY_CODE|tojson }};
|
||||
</script>
|
||||
|
||||
{% if request.endpoint != 'system_auth' %}
|
||||
<script src="{{ static_asset_url('static_bp.serve_js_lib', 'glightbox.min.js') }}"></script>
|
||||
<script src="{{ static_asset_url('static_bp.serve_js_lib', 'socket.io.min.js') }}"></script>
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
<button id="deselectAllBtn" class="btn btn-sm btn-outline-light active" style="display: none;">Odznacz
|
||||
wszystko</button>
|
||||
</div>
|
||||
<h5 class="text-success m-0">💰 Suma: <span id="listsTotal">0.00 PLN</span></h5>
|
||||
<h5 class="text-success m-0">💰 Suma: <span id="listsTotal">{{ format_currency(0) }}</span></h5>
|
||||
</div>
|
||||
|
||||
<!-- Tabela list z możliwością filtrowania -->
|
||||
@@ -101,7 +101,7 @@
|
||||
<th>Nazwa listy</th>
|
||||
<th>Właściciel</th>
|
||||
<th>Data</th>
|
||||
<th>Wydatki (PLN)</th>
|
||||
<th>Wydatki ({{ CURRENCY_CODE }})</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="listsTableBody">
|
||||
|
||||
@@ -96,11 +96,11 @@
|
||||
<br>
|
||||
{% if total_expense > 0 %}
|
||||
<div id="total-expense2" class="text-success fw-bold mb-3">
|
||||
💸 Łącznie wydano: {{ '%.2f'|format(total_expense) }} PLN
|
||||
💸 Łącznie wydano: {{ format_currency(total_expense) }}
|
||||
</div>
|
||||
{% else %}
|
||||
<div id="total-expense2" class="text-success fw-bold mb-3">
|
||||
💸 Łącznie wydano: 0.00 PLN
|
||||
💸 Łącznie wydano: {{ format_currency(0) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
|
||||
{% if total_expense > 0 %}
|
||||
<span id="total-expense1" class="badge rounded-pill bg-success ms-2">
|
||||
💸 {{ '%.2f'|format(total_expense) }} PLN
|
||||
💸 {{ format_currency(total_expense) }}
|
||||
</span>
|
||||
{% else %}
|
||||
<span id="total-expense" class="badge rounded-pill bg-secondary ms-2" style="display: none;">
|
||||
💸 0.00 PLN
|
||||
💸 {{ format_currency(0) }}
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
<span>💰 Dodaj wydatek</span>
|
||||
|
||||
<span class="badge rounded-pill bg-success" id="total-expense2">
|
||||
💸 Łączna suma: {{ '%.2f'|format(total_expense) }} PLN
|
||||
💸 Łączna suma: {{ format_currency(total_expense) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
<div class="input-group mb-0 shopping-compact-input-group shopping-expense-input-group">
|
||||
<input id="expenseAmount" type="number" step="0.01" min="0"
|
||||
class="form-control bg-dark text-white border-secondary shopping-expense-amount-input"
|
||||
placeholder="Kwota (PLN)">
|
||||
placeholder="{{ currency_placeholder() }}">
|
||||
|
||||
<button onclick="submitExpense({{ list.id }})"
|
||||
class="btn btn-outline-primary share-submit-btn share-submit-btn--expense shopping-compact-submit">
|
||||
@@ -135,7 +135,7 @@
|
||||
{% endif %}
|
||||
|
||||
<p id="total-expense2" style="display: none;">
|
||||
<b>💸 Łącznie wydano:</b> {{ '%.2f'|format(total_expense) }} PLN
|
||||
<b>💸 Łącznie wydano:</b> {{ format_currency(total_expense) }}
|
||||
</p>
|
||||
|
||||
<button id="toggleReceiptBtn" type="button" class="receipt-disclosure mb-3"
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
</div>
|
||||
<div class="main-summary-stat">
|
||||
<span class="main-summary-stat__label">Wydatki</span>
|
||||
<strong>{{ '%.2f'|format(summary.total_expense) }} PLN</strong>
|
||||
<strong>{{ format_currency(summary.total_expense) }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,6 +26,9 @@ def inject_version():
|
||||
|
||||
return {
|
||||
"APP_VERSION": app.config["APP_VERSION"],
|
||||
"CURRENCY_CODE": get_currency_code(),
|
||||
"format_currency": format_currency,
|
||||
"currency_placeholder": currency_placeholder,
|
||||
"static_asset_url": static_asset_url,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user