UI cleanup
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -432,6 +432,7 @@ def log_payment():
|
|||||||
total = float(data.get('total', 0))
|
total = float(data.get('total', 0))
|
||||||
balance_before = float(data.get('balance_before', 0))
|
balance_before = float(data.get('balance_before', 0))
|
||||||
balance_after = float(data.get('balance_after', 0))
|
balance_after = float(data.get('balance_after', 0))
|
||||||
|
buyer = (data.get('buyer') or '').strip()
|
||||||
cart_items = data.get('cart_items', []) # [{id, name, price, qty, image}]
|
cart_items = data.get('cart_items', []) # [{id, name, price, qty, image}]
|
||||||
|
|
||||||
# Deduct stock for each sold item
|
# Deduct stock for each sold item
|
||||||
@@ -447,7 +448,7 @@ def log_payment():
|
|||||||
# Update balance atomically with payment log
|
# Update balance atomically with payment log
|
||||||
data_manager.set_balance(balance_after)
|
data_manager.set_balance(balance_after)
|
||||||
|
|
||||||
if data_manager.log_payment(items, total, balance_before, balance_after):
|
if data_manager.log_payment(items, total, balance_before, balance_after, buyer):
|
||||||
return jsonify({'success': True})
|
return jsonify({'success': True})
|
||||||
return jsonify({'success': False, 'message': 'Error logging payment'}), 400
|
return jsonify({'success': False, 'message': 'Error logging payment'}), 400
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -7,5 +7,212 @@
|
|||||||
"scan_result": "MANUAL",
|
"scan_result": "MANUAL",
|
||||||
"reason": "Unregistered",
|
"reason": "Unregistered",
|
||||||
"timestamp": "2026-02-12T13:34:11.034695"
|
"timestamp": "2026-02-12T13:34:11.034695"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "test",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T22:59:26.155886"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "teste",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T22:59:33.908972"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "testeste",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T22:59:36.542642"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "testst",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T22:59:39.726511"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "etsetset",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T22:59:42.367083"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 7,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "etsetst",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T22:59:44.990438"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "testestest",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T22:59:47.949316"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 9,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "testestes",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T22:59:50.328739"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 10,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "setsettes",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T22:59:53.062096"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 11,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "setests",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T22:59:55.647214"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 12,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "esttset",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T22:59:58.394528"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 13,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "etestest",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T23:00:00.890154"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 14,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "etsetset",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T23:00:03.952926"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 15,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "settet",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T23:00:07.040332"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 16,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "tetetet",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T23:00:09.693125"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 17,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "tetete",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T23:00:12.375991"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 18,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "tetetet",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T23:00:15.544080"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 19,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "eeee",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T23:00:17.805205"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 20,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "eeeee",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T23:00:39.566745"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 21,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "eeee",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T23:00:42.970896"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 22,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "eeeee",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T23:00:52.390520"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 23,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "wwww",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T23:00:55.606973"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 24,
|
||||||
|
"card_uid": null,
|
||||||
|
"key_uid": null,
|
||||||
|
"name": "ewqewqeqw",
|
||||||
|
"scan_result": "MANUAL",
|
||||||
|
"reason": "Unregistered",
|
||||||
|
"timestamp": "2026-05-30T23:07:00.557343"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
+100
-5
File diff suppressed because one or more lines are too long
+2
-1
@@ -309,7 +309,7 @@ class DataManager:
|
|||||||
print(f"Error deleting item: {e}")
|
print(f"Error deleting item: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def log_payment(self, items: list, total: float, balance_before: float, balance_after: float) -> bool:
|
def log_payment(self, items: list, total: float, balance_before: float, balance_after: float, buyer: str = '') -> bool:
|
||||||
try:
|
try:
|
||||||
store = self.load_store()
|
store = self.load_store()
|
||||||
payments = store.get('payments', [])
|
payments = store.get('payments', [])
|
||||||
@@ -317,6 +317,7 @@ class DataManager:
|
|||||||
payments.append({
|
payments.append({
|
||||||
'id': new_id,
|
'id': new_id,
|
||||||
'timestamp': datetime.now().isoformat(),
|
'timestamp': datetime.now().isoformat(),
|
||||||
|
'buyer': buyer,
|
||||||
'items': items,
|
'items': items,
|
||||||
'total': round(total, 2),
|
'total': round(total, 2),
|
||||||
'balance_before': round(balance_before, 2),
|
'balance_before': round(balance_before, 2),
|
||||||
|
|||||||
+596
-420
File diff suppressed because it is too large
Load Diff
+254
-19
@@ -1,6 +1,11 @@
|
|||||||
let editingParticipantId = null;
|
let editingParticipantId = null;
|
||||||
let isAdmin = false;
|
let isAdmin = false;
|
||||||
|
|
||||||
|
function fmtDate(iso) {
|
||||||
|
const [y, m, d] = iso.split('-');
|
||||||
|
return `${d}-${m}-${y.slice(2)}`;
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize on page load
|
// Initialize on page load
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
checkAdminStatus();
|
checkAdminStatus();
|
||||||
@@ -412,8 +417,8 @@ async function refreshLogs() {
|
|||||||
filteredLogs.forEach(log => {
|
filteredLogs.forEach(log => {
|
||||||
const row = document.createElement('tr');
|
const row = document.createElement('tr');
|
||||||
const timestamp = log.timestamp;
|
const timestamp = log.timestamp;
|
||||||
const date = timestamp.split('T')[0];
|
const date = fmtDate(timestamp.split('T')[0]);
|
||||||
const time = timestamp.split('T')[1].substring(0, 8);
|
const time = timestamp.split('T')[1].substring(0, 5);
|
||||||
|
|
||||||
// Determine status class
|
// Determine status class
|
||||||
let statusClass = 'pass';
|
let statusClass = 'pass';
|
||||||
@@ -728,7 +733,14 @@ function switchTab(tabName, event) {
|
|||||||
|
|
||||||
// Load tab-specific data
|
// Load tab-specific data
|
||||||
if (tabName === 'documents') loadDocuments();
|
if (tabName === 'documents') loadDocuments();
|
||||||
if (tabName === 'store') loadStore();
|
if (tabName === 'store') {
|
||||||
|
// Always return to shop view when switching to store tab
|
||||||
|
storeViewIsHistory = false;
|
||||||
|
document.getElementById('storeShopView').style.display = '';
|
||||||
|
document.getElementById('storeHistoryView').style.display = 'none';
|
||||||
|
document.getElementById('storeViewToggleBtn').textContent = 'Zgodovina plačil';
|
||||||
|
loadStore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close modal when clicking outside
|
// Close modal when clicking outside
|
||||||
@@ -746,6 +758,10 @@ window.onclick = function(event) {
|
|||||||
if (event.target === addUnregisteredModal) closeAddUnregisteredModal();
|
if (event.target === addUnregisteredModal) closeAddUnregisteredModal();
|
||||||
if (event.target === addItemModal) closeAddItemModal();
|
if (event.target === addItemModal) closeAddItemModal();
|
||||||
if (event.target === editBalanceModal) closeEditBalanceModal();
|
if (event.target === editBalanceModal) closeEditBalanceModal();
|
||||||
|
const checkoutModal = document.getElementById('checkoutModal');
|
||||||
|
const monthlyModal = document.getElementById('monthlyModal');
|
||||||
|
if (event.target === checkoutModal) closeCheckoutModal();
|
||||||
|
if (event.target === monthlyModal) closeMonthlyOverview();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== LAST SCAN RESULT =====
|
// ===== LAST SCAN RESULT =====
|
||||||
@@ -909,9 +925,10 @@ function renderInventory() {
|
|||||||
storeItems.forEach(item => {
|
storeItems.forEach(item => {
|
||||||
const card = document.createElement('div');
|
const card = document.createElement('div');
|
||||||
card.className = 'inventory-card' + (item.stock === 0 ? ' out-of-stock' : '');
|
card.className = 'inventory-card' + (item.stock === 0 ? ' out-of-stock' : '');
|
||||||
const imgHtml = item.image
|
const imgHtml = `<div class="inventory-card-img-wrap">${item.image
|
||||||
? `<img src="${item.image}" alt="${item.name}" class="inventory-card-img">`
|
? `<img src="${item.image}" alt="${item.name}" class="inventory-card-img">`
|
||||||
: `<div class="inventory-card-img-placeholder">${ITEM_FALLBACK_SVG}</div>`;
|
: `<div class="inventory-card-img-placeholder">${ITEM_FALLBACK_SVG}</div>`
|
||||||
|
}</div>`;
|
||||||
card.innerHTML = `
|
card.innerHTML = `
|
||||||
${imgHtml}
|
${imgHtml}
|
||||||
<div class="inventory-card-body">
|
<div class="inventory-card-body">
|
||||||
@@ -1008,16 +1025,40 @@ function updateCartTotals() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processPayment() {
|
function processPayment() {
|
||||||
if (cart.length === 0) {
|
if (cart.length === 0) {
|
||||||
alert('Košarica je prazna');
|
alert('Košarica je prazna');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const total = cart.reduce((sum, i) => sum + i.price * i.qty, 0);
|
const total = cart.reduce((sum, i) => sum + i.price * i.qty, 0);
|
||||||
const balanceAfter = currentBalance + total;
|
const balanceAfter = currentBalance + total;
|
||||||
|
|
||||||
if (!confirm(`Skupaj: €${total.toFixed(2)}\nStanje po plačilu: €${balanceAfter.toFixed(2)}\n\nPotrdite plačilo?`)) return;
|
document.getElementById('checkoutFirstName').value = '';
|
||||||
|
document.getElementById('checkoutLastName').value = '';
|
||||||
|
document.getElementById('checkoutTotal').textContent = '€' + total.toFixed(2);
|
||||||
|
document.getElementById('checkoutBalanceAfter').textContent = '€' + balanceAfter.toFixed(2);
|
||||||
|
document.getElementById('checkoutModal').classList.add('show');
|
||||||
|
document.getElementById('checkoutFirstName').focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeCheckoutModal() {
|
||||||
|
document.getElementById('checkoutModal').classList.remove('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function confirmCheckout() {
|
||||||
|
const firstName = document.getElementById('checkoutFirstName').value.trim();
|
||||||
|
const lastName = document.getElementById('checkoutLastName').value.trim();
|
||||||
|
|
||||||
|
if (!firstName || !lastName) {
|
||||||
|
alert('Prosimo, vnesite ime in priimek kupca');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const buyer = firstName + ' ' + lastName;
|
||||||
|
const total = cart.reduce((sum, i) => sum + i.price * i.qty, 0);
|
||||||
|
const balanceAfter = currentBalance + total;
|
||||||
|
|
||||||
|
closeCheckoutModal();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const cartItems = cart.map(cartItem => {
|
const cartItems = cart.map(cartItem => {
|
||||||
@@ -1036,6 +1077,7 @@ async function processPayment() {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
buyer,
|
||||||
items: cart.map(i => ({ name: i.name, qty: i.qty, price: i.price })),
|
items: cart.map(i => ({ name: i.name, qty: i.qty, price: i.price })),
|
||||||
cart_items: cartItems,
|
cart_items: cartItems,
|
||||||
total,
|
total,
|
||||||
@@ -1047,9 +1089,18 @@ async function processPayment() {
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
if (!data.success) { alert('Napaka: ' + data.message); return; }
|
if (!data.success) { alert('Napaka: ' + data.message); return; }
|
||||||
|
|
||||||
|
const payment = {
|
||||||
|
buyer,
|
||||||
|
items: cart.map(i => ({ name: i.name, qty: i.qty, price: i.price })),
|
||||||
|
total,
|
||||||
|
balance_before: currentBalance,
|
||||||
|
balance_after: balanceAfter,
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
};
|
||||||
|
|
||||||
cart = [];
|
cart = [];
|
||||||
await loadStore();
|
await loadStore();
|
||||||
alert('Plačilo uspešno!');
|
printReceipt(payment);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert('Napaka: ' + error.message);
|
alert('Napaka: ' + error.message);
|
||||||
}
|
}
|
||||||
@@ -1212,15 +1263,18 @@ async function saveBalance() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ===== PAYMENT HISTORY =====
|
// ===== PAYMENT HISTORY =====
|
||||||
let paymentHistoryVisible = false;
|
let storeViewIsHistory = false;
|
||||||
|
|
||||||
function togglePaymentHistory() {
|
function toggleStoreView() {
|
||||||
paymentHistoryVisible = !paymentHistoryVisible;
|
storeViewIsHistory = !storeViewIsHistory;
|
||||||
const panel = document.getElementById('paymentHistoryPanel');
|
document.getElementById('storeShopView').style.display = storeViewIsHistory ? 'none' : '';
|
||||||
panel.style.display = paymentHistoryVisible ? 'block' : 'none';
|
document.getElementById('storeHistoryView').style.display = storeViewIsHistory ? '' : 'none';
|
||||||
if (paymentHistoryVisible) loadPaymentHistory();
|
document.getElementById('storeViewToggleBtn').textContent = storeViewIsHistory ? '← Nazaj v trgovino' : 'Zgodovina plačil';
|
||||||
|
if (storeViewIsHistory) loadPaymentHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function togglePaymentHistory() { toggleStoreView(); }
|
||||||
|
|
||||||
async function loadPaymentHistory() {
|
async function loadPaymentHistory() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/store/payments');
|
const response = await fetch('/api/store/payments');
|
||||||
@@ -1232,25 +1286,27 @@ async function loadPaymentHistory() {
|
|||||||
if (clearBtn) clearBtn.style.display = isAdmin ? 'inline-block' : 'none';
|
if (clearBtn) clearBtn.style.display = isAdmin ? 'inline-block' : 'none';
|
||||||
|
|
||||||
if (payments.length === 0) {
|
if (payments.length === 0) {
|
||||||
tbody.innerHTML = `<tr><td colspan="7" style="text-align:center;padding:20px;color:var(--text-secondary);">Ni zabeleženih plačil</td></tr>`;
|
tbody.innerHTML = `<tr><td colspan="9" style="text-align:center;padding:20px;color:var(--text-secondary);">Ni zabeleženih plačil</td></tr>`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody.innerHTML = '';
|
tbody.innerHTML = '';
|
||||||
[...payments].reverse().forEach(p => {
|
[...payments].reverse().forEach(p => {
|
||||||
const ts = p.timestamp;
|
const ts = p.timestamp;
|
||||||
const date = ts.split('T')[0];
|
const date = fmtDate(ts.split('T')[0]);
|
||||||
const time = ts.split('T')[1].substring(0, 8);
|
const time = ts.split('T')[1].substring(0, 5);
|
||||||
const itemsSummary = p.items.map(i => `${i.name} ×${i.qty}`).join(', ');
|
const itemsSummary = p.items.map(i => `${i.name} ×${i.qty}`).join(', ');
|
||||||
const row = document.createElement('tr');
|
const row = document.createElement('tr');
|
||||||
row.innerHTML = `
|
row.innerHTML = `
|
||||||
<td>${p.id}</td>
|
<td>${p.id}</td>
|
||||||
|
<td style="font-weight:600;">${p.buyer || '-'}</td>
|
||||||
<td>${date}</td>
|
<td>${date}</td>
|
||||||
<td>${time}</td>
|
<td>${time}</td>
|
||||||
<td style="max-width:220px;word-break:break-word;">${itemsSummary}</td>
|
<td style="max-width:200px;word-break:break-word;">${itemsSummary}</td>
|
||||||
<td style="font-weight:700;color:var(--accent-blue);">€${p.total.toFixed(2)}</td>
|
<td style="font-weight:700;color:var(--accent-blue);">€${p.total.toFixed(2)}</td>
|
||||||
<td>€${p.balance_before.toFixed(2)}</td>
|
<td>€${p.balance_before.toFixed(2)}</td>
|
||||||
<td>€${p.balance_after.toFixed(2)}</td>
|
<td>€${p.balance_after.toFixed(2)}</td>
|
||||||
|
<td><button class="action-btn edit-btn" onclick="printReceipt(${JSON.stringify(p).replace(/"/g, '"')})">🖨 Natisni</button></td>
|
||||||
`;
|
`;
|
||||||
tbody.appendChild(row);
|
tbody.appendChild(row);
|
||||||
});
|
});
|
||||||
@@ -1259,6 +1315,185 @@ async function loadPaymentHistory() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== RECEIPT PRINT =====
|
||||||
|
const LOGO_URL = '/static/assets/logo.png';
|
||||||
|
|
||||||
|
function printReceipt(payment) {
|
||||||
|
const ts = payment.timestamp || new Date().toISOString();
|
||||||
|
const date = fmtDate(ts.split('T')[0]);
|
||||||
|
const time = ts.split('T')[1] ? ts.split('T')[1].substring(0, 5) : '';
|
||||||
|
const rows = payment.items.map(i =>
|
||||||
|
`<tr><td class="rp-td-name">${i.name}</td><td class="rp-td-qty">${i.qty}×</td><td class="rp-td-price">€${i.price.toFixed(2)}</td><td class="rp-td-sub">€${(i.price * i.qty).toFixed(2)}</td></tr>`
|
||||||
|
).join('');
|
||||||
|
|
||||||
|
const html = `
|
||||||
|
<div class="rp-page">
|
||||||
|
<div class="rp-logo-block">
|
||||||
|
<img src="${LOGO_URL}" alt="Logo" class="rp-logo" onerror="this.style.display='none'">
|
||||||
|
</div>
|
||||||
|
<div class="rp-divider"></div>
|
||||||
|
<div class="rp-title">POTRDILO O PLAČILU</div>
|
||||||
|
<div class="rp-meta">
|
||||||
|
<span>${date} ${time}</span>
|
||||||
|
<span>Prodajalec: <strong>${payment.buyer || '-'}</strong></span>
|
||||||
|
</div>
|
||||||
|
<div class="rp-divider-dashed"></div>
|
||||||
|
<table class="rp-table">
|
||||||
|
<thead><tr><th>Artikel</th><th>Kol.</th><th>Cena</th><th style="text-align:right;">Znesek</th></tr></thead>
|
||||||
|
<tbody>${rows}</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="rp-divider"></div>
|
||||||
|
<div class="rp-total">
|
||||||
|
<span>SKUPAJ</span>
|
||||||
|
<span>€${payment.total.toFixed(2)}</span>
|
||||||
|
</div>
|
||||||
|
<div class="rp-divider-dashed"></div>
|
||||||
|
<div class="rp-footer">Hvala za nakup!</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const area = document.getElementById('receiptPrintArea');
|
||||||
|
area.innerHTML = html;
|
||||||
|
area.style.display = 'block';
|
||||||
|
document.body.classList.add('printing-receipt');
|
||||||
|
window.print();
|
||||||
|
document.body.classList.remove('printing-receipt');
|
||||||
|
area.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== MONTHLY OVERVIEW =====
|
||||||
|
let allPaymentsCache = [];
|
||||||
|
|
||||||
|
function openMonthlyOverview() {
|
||||||
|
const now = new Date();
|
||||||
|
const ym = now.toISOString().substring(0, 7);
|
||||||
|
document.getElementById('monthlyPickerInput').value = ym;
|
||||||
|
document.getElementById('monthlyModal').classList.add('show');
|
||||||
|
renderMonthlyOverview();
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeMonthlyOverview() {
|
||||||
|
document.getElementById('monthlyModal').classList.remove('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function renderMonthlyOverview() {
|
||||||
|
const picker = document.getElementById('monthlyPickerInput').value;
|
||||||
|
if (!picker) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/store/payments');
|
||||||
|
allPaymentsCache = await response.json();
|
||||||
|
} catch (e) { return; }
|
||||||
|
|
||||||
|
const filtered = allPaymentsCache.filter(p => p.timestamp.startsWith(picker));
|
||||||
|
const content = document.getElementById('monthlyOverviewContent');
|
||||||
|
|
||||||
|
if (filtered.length === 0) {
|
||||||
|
content.innerHTML = '<p style="color:var(--text-secondary);padding:16px 0;">Ni plačil v izbranem mesecu.</p>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const grandTotal = filtered.reduce((s, p) => s + p.total, 0);
|
||||||
|
|
||||||
|
// Per-item breakdown
|
||||||
|
const itemTotals = {};
|
||||||
|
filtered.forEach(p => p.items.forEach(i => {
|
||||||
|
if (!itemTotals[i.name]) itemTotals[i.name] = { qty: 0, revenue: 0 };
|
||||||
|
itemTotals[i.name].qty += i.qty;
|
||||||
|
itemTotals[i.name].revenue += i.price * i.qty;
|
||||||
|
}));
|
||||||
|
|
||||||
|
const itemRows = Object.entries(itemTotals).map(([name, v]) =>
|
||||||
|
`<tr><td>${name}</td><td style="text-align:center;">${v.qty}</td><td style="text-align:right;font-weight:600;">€${v.revenue.toFixed(2)}</td></tr>`
|
||||||
|
).join('');
|
||||||
|
|
||||||
|
const txRows = [...filtered].reverse().map(p => {
|
||||||
|
const date = fmtDate(p.timestamp.split('T')[0]);
|
||||||
|
const time = p.timestamp.split('T')[1].substring(0, 5);
|
||||||
|
return `<tr><td>${date}</td><td>${time}</td><td style="font-weight:600;">${p.buyer || '-'}</td><td>${p.items.map(i => `${i.name} ×${i.qty}`).join(', ')}</td><td style="text-align:right;font-weight:700;color:var(--accent-blue);">€${p.total.toFixed(2)}</td></tr>`;
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
content.innerHTML = `
|
||||||
|
<div class="monthly-summary-total">Skupaj prihodek: <strong>€${grandTotal.toFixed(2)}</strong> (${filtered.length} transakcij)</div>
|
||||||
|
<h4 class="monthly-section-title">Po artiklih</h4>
|
||||||
|
<div class="table-container" style="margin-bottom:16px;">
|
||||||
|
<table><thead><tr><th>Artikel</th><th style="text-align:center;">Količina</th><th style="text-align:right;">Prihodek</th></tr></thead>
|
||||||
|
<tbody>${itemRows}</tbody></table>
|
||||||
|
</div>
|
||||||
|
<h4 class="monthly-section-title">Vse transakcije</h4>
|
||||||
|
<div class="table-container">
|
||||||
|
<table><thead><tr><th>Datum</th><th>Čas</th><th>Prodajalec</th><th>Artikli</th><th style="text-align:right;">Skupaj</th></tr></thead>
|
||||||
|
<tbody>${txRows}</tbody></table>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function printMonthlyOverview() {
|
||||||
|
const picker = document.getElementById('monthlyPickerInput').value;
|
||||||
|
if (!picker || !allPaymentsCache.length) return;
|
||||||
|
|
||||||
|
const filtered = allPaymentsCache.filter(p => p.timestamp.startsWith(picker));
|
||||||
|
if (filtered.length === 0) { alert('Ni podatkov za izbrani mesec.'); return; }
|
||||||
|
|
||||||
|
const grandTotal = filtered.reduce((s, p) => s + p.total, 0);
|
||||||
|
|
||||||
|
const itemTotals = {};
|
||||||
|
filtered.forEach(p => p.items.forEach(i => {
|
||||||
|
if (!itemTotals[i.name]) itemTotals[i.name] = { qty: 0, revenue: 0 };
|
||||||
|
itemTotals[i.name].qty += i.qty;
|
||||||
|
itemTotals[i.name].revenue += i.price * i.qty;
|
||||||
|
}));
|
||||||
|
|
||||||
|
const itemRows = Object.entries(itemTotals).map(([name, v]) =>
|
||||||
|
`<tr><td>${name}</td><td style="text-align:center;">${v.qty}</td><td style="text-align:right;font-weight:600;">€${v.revenue.toFixed(2)}</td></tr>`
|
||||||
|
).join('');
|
||||||
|
|
||||||
|
const txRows = [...filtered].reverse().map(p => {
|
||||||
|
const date = fmtDate(p.timestamp.split('T')[0]);
|
||||||
|
const time = p.timestamp.split('T')[1].substring(0, 5);
|
||||||
|
const items = p.items.map(i => `${i.name} ×${i.qty} (€${(i.price*i.qty).toFixed(2)})`).join(', ');
|
||||||
|
return `<tr><td>${date}</td><td>${time}</td><td style="font-weight:600;">${p.buyer || '-'}</td><td>${items}</td><td style="text-align:right;font-weight:700;">€${p.total.toFixed(2)}</td></tr>`;
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
const [year, month] = picker.split('-');
|
||||||
|
const monthName = new Date(year, month - 1, 1).toLocaleDateString('sl-SI', { month: 'long', year: 'numeric' });
|
||||||
|
const printDate = fmtDate(new Date().toISOString().split('T')[0]);
|
||||||
|
|
||||||
|
const html = `
|
||||||
|
<div class="rp-page rp-monthly">
|
||||||
|
<div class="rp-logo-block">
|
||||||
|
<img src="${LOGO_URL}" alt="Logo" class="rp-logo" onerror="this.style.display='none'">
|
||||||
|
</div>
|
||||||
|
<div class="rp-divider"></div>
|
||||||
|
<div class="rp-title">MESEČNI PREGLED</div>
|
||||||
|
<div class="rp-meta"><span>${monthName}</span><span>Natisnjeno: ${printDate}</span></div>
|
||||||
|
<div class="rp-divider-dashed"></div>
|
||||||
|
<div class="rp-monthly-kpi">
|
||||||
|
<div class="rp-kpi-box"><div class="rp-kpi-label">Skupaj prihodek</div><div class="rp-kpi-value">€${grandTotal.toFixed(2)}</div></div>
|
||||||
|
<div class="rp-kpi-box"><div class="rp-kpi-label">Št. transakcij</div><div class="rp-kpi-value">${filtered.length}</div></div>
|
||||||
|
</div>
|
||||||
|
<div class="rp-section-title">Po artiklih</div>
|
||||||
|
<table class="rp-table">
|
||||||
|
<thead><tr><th>Artikel</th><th style="text-align:center;">Količina</th><th style="text-align:right;">Prihodek</th></tr></thead>
|
||||||
|
<tbody>${itemRows}</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="rp-section-title" style="margin-top:16px;">Vse transakcije</div>
|
||||||
|
<table class="rp-table">
|
||||||
|
<thead><tr><th>Datum</th><th>Čas</th><th>Prodajalec</th><th>Artikli</th><th style="text-align:right;">Skupaj</th></tr></thead>
|
||||||
|
<tbody>${txRows}</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const area = document.getElementById('receiptPrintArea');
|
||||||
|
area.innerHTML = html;
|
||||||
|
area.style.display = 'block';
|
||||||
|
document.body.classList.add('printing-receipt');
|
||||||
|
window.print();
|
||||||
|
document.body.classList.remove('printing-receipt');
|
||||||
|
area.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
async function clearPaymentHistory() {
|
async function clearPaymentHistory() {
|
||||||
if (!confirm('Izbriši celotno zgodovino plačil?')) return;
|
if (!confirm('Izbriši celotno zgodovino plačil?')) return;
|
||||||
try {
|
try {
|
||||||
|
|||||||
+104
-67
@@ -52,7 +52,7 @@
|
|||||||
<div class="right-panel">
|
<div class="right-panel">
|
||||||
<!-- Tab Navigation -->
|
<!-- Tab Navigation -->
|
||||||
<div class="tab-nav">
|
<div class="tab-nav">
|
||||||
<button class="tab-nav-btn active" onclick="switchTab('logs', event)">Dnevnik skeniranja</button>
|
<button class="tab-nav-btn active" onclick="switchTab('logs', event)">Dnevnik</button>
|
||||||
<button class="tab-nav-btn" onclick="switchTab('participants', event)">Člani</button>
|
<button class="tab-nav-btn" onclick="switchTab('participants', event)">Člani</button>
|
||||||
<button class="tab-nav-btn" onclick="switchTab('documents', event)">Dokumenti</button>
|
<button class="tab-nav-btn" onclick="switchTab('documents', event)">Dokumenti</button>
|
||||||
<button class="tab-nav-btn" onclick="switchTab('store', event)">Trgovina</button>
|
<button class="tab-nav-btn" onclick="switchTab('store', event)">Trgovina</button>
|
||||||
@@ -60,9 +60,11 @@
|
|||||||
|
|
||||||
<!-- Participants Tab -->
|
<!-- Participants Tab -->
|
||||||
<div id="participants-tab" class="tab-panel">
|
<div id="participants-tab" class="tab-panel">
|
||||||
<div class="panel-header">
|
<div class="toolbar">
|
||||||
<h2>Člani</h2>
|
<span class="toolbar-title">Člani</span>
|
||||||
<button class="btn btn-primary" onclick="openAddParticipantModal()">Dodaj udeleženca</button>
|
<div class="toolbar-actions">
|
||||||
|
<button class="tb-btn tb-btn-primary" onclick="openAddParticipantModal()">+ Dodaj udeleženca</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-content">
|
<div class="panel-content">
|
||||||
<div class="table-container">
|
<div class="table-container">
|
||||||
@@ -78,8 +80,7 @@
|
|||||||
<th>Dejanja</th>
|
<th>Dejanja</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="participantsTable">
|
<tbody id="participantsTable"></tbody>
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -87,49 +88,43 @@
|
|||||||
|
|
||||||
<!-- Scan Logs Tab -->
|
<!-- Scan Logs Tab -->
|
||||||
<div id="logs-tab" class="tab-panel active">
|
<div id="logs-tab" class="tab-panel active">
|
||||||
<div class="panel-header">
|
<div class="toolbar">
|
||||||
<h2>Zgodovina skeniranja</h2>
|
<div class="toolbar-filters">
|
||||||
<div class="header-actions">
|
<div class="tf-group">
|
||||||
<button class="btn btn-primary" onclick="exportLogs()">Izvozi v Excel</button>
|
<label>Rezultat</label>
|
||||||
<button class="btn btn-primary" onclick="printLogs()">Natisni</button>
|
|
||||||
<button id="addUnregisteredBtn" class="btn btn-primary" onclick="openAddUnregisteredModal()">Dodaj neregistriranega</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="panel-filters">
|
|
||||||
<div class="filters-row">
|
|
||||||
<div class="filter-group">
|
|
||||||
<label>Rezultat:</label>
|
|
||||||
<select id="filterSelect" onchange="refreshLogs()">
|
<select id="filterSelect" onchange="refreshLogs()">
|
||||||
<option value="All">Vse</option>
|
<option value="All">Vse</option>
|
||||||
<option value="PASS">Samo PASS</option>
|
<option value="PASS">PASS</option>
|
||||||
<option value="FAIL">Samo FAIL</option>
|
<option value="FAIL">FAIL</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-group">
|
<div class="tf-group">
|
||||||
<label>Udeleženec:</label>
|
<label>Udeleženec</label>
|
||||||
<select id="participantFilter" onchange="refreshLogs()">
|
<select id="participantFilter" onchange="refreshLogs()">
|
||||||
<option value="">Vsi udeleženci</option>
|
<option value="">Vsi</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-group">
|
<div class="tf-group">
|
||||||
<label>Od:</label>
|
<label>Od</label>
|
||||||
<input type="date" id="startDateFilter" onchange="refreshLogs()">
|
<input type="date" id="startDateFilter" onchange="refreshLogs()">
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-group">
|
<div class="tf-group">
|
||||||
<label>Do:</label>
|
<label>Do</label>
|
||||||
<input type="date" id="endDateFilter" onchange="refreshLogs()">
|
<input type="date" id="endDateFilter" onchange="refreshLogs()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="tf-quick">
|
||||||
<div class="filters-quick">
|
|
||||||
<button class="btn-quick-filter" onclick="filterByToday()">Danes</button>
|
<button class="btn-quick-filter" onclick="filterByToday()">Danes</button>
|
||||||
<button class="btn-quick-filter" onclick="filterByLastWeek()">Teden</button>
|
<button class="btn-quick-filter" onclick="filterByLastWeek()">Teden</button>
|
||||||
<button class="btn-quick-filter" onclick="filterByLastMonth()">Mesec</button>
|
<button class="btn-quick-filter" onclick="filterByLastMonth()">Mesec</button>
|
||||||
<button class="btn-quick-filter" onclick="filterByLastYear()">Leto</button>
|
<button class="btn-quick-filter" onclick="filterByLastYear()">Leto</button>
|
||||||
<button class="btn-filter" onclick="resetFilters()">Resetiraj</button>
|
<button class="btn-filter" onclick="resetFilters()">×</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-actions">
|
||||||
|
<button class="tb-btn" onclick="printLogs()">Natisni</button>
|
||||||
|
<button id="addUnregisteredBtn" class="tb-btn tb-btn-primary" onclick="openAddUnregisteredModal()">+ Neregistriran</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-content">
|
<div class="panel-content">
|
||||||
<div class="table-container">
|
<div class="table-container">
|
||||||
<table>
|
<table>
|
||||||
@@ -145,8 +140,7 @@
|
|||||||
<th id="logs-actions-header">Dejanja</th>
|
<th id="logs-actions-header">Dejanja</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="logsTable">
|
<tbody id="logsTable"></tbody>
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -154,8 +148,8 @@
|
|||||||
|
|
||||||
<!-- Documents Tab -->
|
<!-- Documents Tab -->
|
||||||
<div id="documents-tab" class="tab-panel">
|
<div id="documents-tab" class="tab-panel">
|
||||||
<div class="panel-header">
|
<div class="toolbar">
|
||||||
<h2>Dokumenti</h2>
|
<span class="toolbar-title">Dokumenti</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-content">
|
<div class="panel-content">
|
||||||
<div id="documentsGrid" class="documents-grid">
|
<div id="documentsGrid" class="documents-grid">
|
||||||
@@ -166,35 +160,32 @@
|
|||||||
|
|
||||||
<!-- Store Tab -->
|
<!-- Store Tab -->
|
||||||
<div id="store-tab" class="tab-panel">
|
<div id="store-tab" class="tab-panel">
|
||||||
<div class="panel-header">
|
<!-- Single shared toolbar -->
|
||||||
<h2>Trgovina</h2>
|
<div class="toolbar">
|
||||||
<div class="header-actions">
|
<span class="toolbar-title">Trgovina</span>
|
||||||
<div class="store-balance-display">
|
<div class="toolbar-actions">
|
||||||
<span class="store-balance-label">Stanje:</span>
|
<div class="store-balance-chip">
|
||||||
|
<span class="store-balance-label">Stanje</span>
|
||||||
<span id="storeBalanceDisplay" class="store-balance-value">€0.00</span>
|
<span id="storeBalanceDisplay" class="store-balance-value">€0.00</span>
|
||||||
<button id="editBalanceBtn" class="btn btn-primary" onclick="openEditBalanceModal()" style="display:none;">Uredi stanje</button>
|
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-primary" onclick="togglePaymentHistory()">Zgodovina plačil</button>
|
<button id="editBalanceBtn" class="tb-btn" onclick="openEditBalanceModal()" style="display:none;">Uredi stanje</button>
|
||||||
|
<button id="addItemBtn" class="tb-btn tb-btn-primary" onclick="openAddItemModal()" style="display:none;">+ Artikel</button>
|
||||||
|
<button id="storeViewToggleBtn" class="tb-btn" onclick="toggleStoreView()">Zgodovina plačil</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="store-tab-scroll panel-content">
|
|
||||||
|
<!-- Shop view -->
|
||||||
|
<div id="storeShopView" class="store-tab-scroll panel-content">
|
||||||
<div class="store-layout">
|
<div class="store-layout">
|
||||||
<!-- Inventory -->
|
|
||||||
<div class="store-inventory">
|
<div class="store-inventory">
|
||||||
<div class="store-section-header">
|
|
||||||
<h3>Zaloga</h3>
|
|
||||||
<button id="addItemBtn" class="btn btn-primary" onclick="openAddItemModal()" style="display:none;">+ Dodaj artikel</button>
|
|
||||||
</div>
|
|
||||||
<div class="inventory-grid" id="inventoryGrid">
|
<div class="inventory-grid" id="inventoryGrid">
|
||||||
<p style="color: var(--text-secondary);">Nalaganje...</p>
|
<p style="color: var(--text-secondary);">Nalaganje...</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Cart -->
|
|
||||||
<div class="store-cart">
|
<div class="store-cart">
|
||||||
<div class="store-section-header">
|
<div class="store-cart-header">
|
||||||
<h3>Košarica</h3>
|
<span class="store-cart-title">Košarica</span>
|
||||||
<button class="btn btn-primary" onclick="clearCart()">Počisti</button>
|
<button class="tb-btn" onclick="clearCart()">Počisti</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="cart-items" id="cartItems">
|
<div class="cart-items" id="cartItems">
|
||||||
<p style="color: var(--text-secondary); text-align: center; padding: 20px;">Košarica je prazna</p>
|
<p style="color: var(--text-secondary); text-align: center; padding: 20px;">Košarica je prazna</p>
|
||||||
@@ -212,36 +203,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div><!-- end store-layout -->
|
|
||||||
|
|
||||||
<!-- Payment History Panel -->
|
|
||||||
<div id="paymentHistoryPanel" class="payment-history-panel" style="display:none;">
|
|
||||||
<div class="store-section-header" style="padding: 0 16px 12px;">
|
|
||||||
<h3>Zgodovina plačil</h3>
|
|
||||||
<button id="clearHistoryBtn" class="action-btn delete-btn" onclick="clearPaymentHistory()" style="display:none;">Izbriši zgodovino</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="table-container" style="margin: 0 16px 16px;">
|
|
||||||
|
<!-- History view -->
|
||||||
|
<div id="storeHistoryView" class="panel-content" style="display:none;">
|
||||||
|
<div class="history-toolbar">
|
||||||
|
<button class="tb-btn" onclick="openMonthlyOverview()">Mesečni pregled</button>
|
||||||
|
<button id="clearHistoryBtn" class="tb-btn" onclick="clearPaymentHistory()" style="display:none;color:var(--accent-red);border-color:#fca5a5;">Izbriši zgodovino</button>
|
||||||
|
</div>
|
||||||
|
<div class="table-container" style="height:calc(100% - 46px);">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>#</th>
|
<th>#</th>
|
||||||
|
<th>Prodajalec</th>
|
||||||
<th>Datum</th>
|
<th>Datum</th>
|
||||||
<th>Čas</th>
|
<th>Čas</th>
|
||||||
<th>Artikli</th>
|
<th>Artikli</th>
|
||||||
<th>Skupaj</th>
|
<th>Skupaj</th>
|
||||||
<th>Stanje pred</th>
|
<th>Stanje pred</th>
|
||||||
<th>Stanje po</th>
|
<th>Stanje po</th>
|
||||||
|
<th>Potrdilo</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="paymentHistoryTable">
|
<tbody id="paymentHistoryTable"></tbody>
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Add Item Modal -->
|
<!-- Add Item Modal -->
|
||||||
<div id="addItemModal" class="modal">
|
<div id="addItemModal" class="modal">
|
||||||
@@ -367,6 +356,54 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Checkout Modal -->
|
||||||
|
<div id="checkoutModal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<span class="close" onclick="closeCheckoutModal()">×</span>
|
||||||
|
<h2>Podatki prodajalca</h2>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Ime:</label>
|
||||||
|
<input type="text" id="checkoutFirstName" placeholder="Ime">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Priimek:</label>
|
||||||
|
<input type="text" id="checkoutLastName" placeholder="Priimek" onkeydown="if(event.key==='Enter')confirmCheckout()">
|
||||||
|
</div>
|
||||||
|
<div class="checkout-summary">
|
||||||
|
<div class="checkout-summary-row">
|
||||||
|
<span>Skupaj za plačilo:</span>
|
||||||
|
<span id="checkoutTotal" class="checkout-total-val"></span>
|
||||||
|
</div>
|
||||||
|
<div class="checkout-summary-row">
|
||||||
|
<span>Stanje po plačilu:</span>
|
||||||
|
<span id="checkoutBalanceAfter" class="checkout-balance-val"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" onclick="confirmCheckout()">Potrdi plačilo</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Monthly Overview Modal -->
|
||||||
|
<div id="monthlyModal" class="modal">
|
||||||
|
<div class="modal-content modal-content-wide">
|
||||||
|
<div class="monthly-modal-header">
|
||||||
|
<h2>Mesečni pregled</h2>
|
||||||
|
<span class="close" onclick="closeMonthlyOverview()">×</span>
|
||||||
|
</div>
|
||||||
|
<div class="monthly-modal-toolbar">
|
||||||
|
<div class="filter-group" style="flex:0 0 auto;min-width:180px;">
|
||||||
|
<label>Mesec:</label>
|
||||||
|
<input type="month" id="monthlyPickerInput" onchange="renderMonthlyOverview()">
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" onclick="printMonthlyOverview()" style="width:auto;padding:10px 18px;margin:0;font-size:12px;flex-shrink:0;">Natisni pregled</button>
|
||||||
|
</div>
|
||||||
|
<div id="monthlyOverviewContent" class="monthly-modal-body"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Hidden receipt for printing -->
|
||||||
|
<div id="receiptPrintArea" style="display:none;"></div>
|
||||||
|
|
||||||
<div id="print-header" style="visibility:hidden;position:fixed;">
|
<div id="print-header" style="visibility:hidden;position:fixed;">
|
||||||
<img src="{{ url_for('static', filename='assets/logo.png') }}" alt="Logo">
|
<img src="{{ url_for('static', filename='assets/logo.png') }}" alt="Logo">
|
||||||
<p id="print-date-range" style="font-size:13px;color:#444;margin-top:4px;"></p>
|
<p id="print-date-range" style="font-size:13px;color:#444;margin-top:4px;"></p>
|
||||||
|
|||||||
Reference in New Issue
Block a user