Kgshop commited on
Commit
91d3e20
·
verified ·
1 Parent(s): c1770d9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +24 -13
app.py CHANGED
@@ -656,10 +656,17 @@ TEMPLATE = """
656
  const totalSection = document.getElementById('invoiceTotalSection');
657
  const totalAmount = parseFloat(invoiceData.total_amount);
658
  const bonusesDeducted = parseFloat(invoiceData.bonuses_deducted || 0);
 
 
 
 
 
 
 
659
 
660
  let html = `<div class="total-row"><span>Сумма</span> <span>${totalAmount.toFixed(2)}</span></div>`;
661
  if (bonusesDeducted > 0) {
662
- html += `<div class="total-row"><span>Списано бонусов</span> <span class="deduction">- ${bonusesDeducted.toFixed(2)}</span></div>`;
663
  html += `<div class="total-row final"><span>К оплате</span> <span>${(totalAmount - bonusesDeducted).toFixed(2)}</span></div>`;
664
  } else {
665
  html += `<div class="total-row final"><span>К оплате</span> <span>${totalAmount.toFixed(2)}</span></div>`;
@@ -1405,20 +1412,22 @@ ADMIN_TEMPLATE = """
1405
  }
1406
 
1407
  function addNewInvoiceItemRow() {
1408
- const tableBody = document.getElementById('newInvoiceItemsTable').getElementsByTagName('tbody')[0];
1409
- const rowIndex = tableBody.rows.length;
1410
  newInvoiceItems.push({ product_name: '', quantity: 1, unit_price: 0, item_total: 0 });
1411
  renderNewInvoiceItems();
1412
  }
1413
 
1414
  function updateInvoiceItem(index, field, value) {
1415
- if (newInvoiceItems[index]) {
1416
- newInvoiceItems[index][field] = value;
1417
- const qty = parseFloat(newInvoiceItems[index].quantity) || 0;
1418
- const price = parseFloat(newInvoiceItems[index].unit_price) || 0;
1419
- newInvoiceItems[index].item_total = qty * price;
1420
- renderNewInvoiceItems();
 
 
 
1421
  }
 
1422
  }
1423
 
1424
  function removeInvoiceItemRow(index) {
@@ -1431,7 +1440,8 @@ ADMIN_TEMPLATE = """
1431
  tableBody.innerHTML = '';
1432
  newInvoiceItems.forEach((item, index) => {
1433
  const newRow = tableBody.insertRow();
1434
- newRow.innerHTML = `<td><input type="text" placeholder="Название товара" value="${item.product_name}" oninput="updateInvoiceItem(${index}, 'product_name', this.value)"></td><td><input type="number" step="1" min="1" placeholder="1" value="${item.quantity || '1'}" oninput="updateInvoiceItem(${index}, 'quantity', parseFloat(this.value))"></td><td><input type="number" step="0.01" min="0" placeholder="0.00" value="${item.unit_price || ''}" oninput="updateInvoiceItem(${index}, 'unit_price', parseFloat(this.value))"></td><td class="item-total-display">${(item.item_total || 0).toFixed(2)}</td><td><button class="action-btn" onclick="removeInvoiceItemRow(${index})">🗑️</button></td>`;
 
1435
  });
1436
  updateNewInvoiceTotal();
1437
  }
@@ -1449,8 +1459,9 @@ ADMIN_TEMPLATE = """
1449
  let deductAmount = parseFloat(deductBonusesInput.value) || 0;
1450
 
1451
  let cappedDeductAmount = Math.max(0, Math.min(deductAmount, availableBonuses, total));
1452
- if (deductAmount !== cappedDeductAmount && document.activeElement === deductBonusesInput) {
1453
- deductBonusesInput.value = cappedDeductAmount > 0 ? cappedDeductAmount.toFixed(2) : '';
 
1454
  }
1455
 
1456
  let finalAmount = total - cappedDeductAmount;
@@ -1466,7 +1477,7 @@ ADMIN_TEMPLATE = """
1466
  statusEl.textContent = 'Пользователь не выбран.';
1467
  return;
1468
  }
1469
- const itemsToAdd = newInvoiceItems.filter(item => item.product_name && (item.quantity > 0 || item.unit_price > 0));
1470
  if (itemsToAdd.length === 0) {
1471
  statusEl.style.color = 'var(--admin-danger)';
1472
  statusEl.textContent = 'Добавьте хотя бы один товар.';
 
656
  const totalSection = document.getElementById('invoiceTotalSection');
657
  const totalAmount = parseFloat(invoiceData.total_amount);
658
  const bonusesDeducted = parseFloat(invoiceData.bonuses_deducted || 0);
659
+ const bonusSource = invoiceData.bonus_source_used;
660
+ let bonusSourceText = '';
661
+ if (bonusSource === 'referral') {
662
+ bonusSourceText = ' (от друзей)';
663
+ } else if (bonusSource === 'main') {
664
+ bonusSourceText = ' (основных)';
665
+ }
666
 
667
  let html = `<div class="total-row"><span>Сумма</span> <span>${totalAmount.toFixed(2)}</span></div>`;
668
  if (bonusesDeducted > 0) {
669
+ html += `<div class="total-row"><span>Списано бонусов${bonusSourceText}</span> <span class="deduction">- ${bonusesDeducted.toFixed(2)}</span></div>`;
670
  html += `<div class="total-row final"><span>К оплате</span> <span>${(totalAmount - bonusesDeducted).toFixed(2)}</span></div>`;
671
  } else {
672
  html += `<div class="total-row final"><span>К оплате</span> <span>${totalAmount.toFixed(2)}</span></div>`;
 
1412
  }
1413
 
1414
  function addNewInvoiceItemRow() {
 
 
1415
  newInvoiceItems.push({ product_name: '', quantity: 1, unit_price: 0, item_total: 0 });
1416
  renderNewInvoiceItems();
1417
  }
1418
 
1419
  function updateInvoiceItem(index, field, value) {
1420
+ if (!newInvoiceItems[index]) return;
1421
+ newInvoiceItems[index][field] = value;
1422
+ const qty = parseFloat(newInvoiceItems[index].quantity) || 0;
1423
+ const price = parseFloat(newInvoiceItems[index].unit_price) || 0;
1424
+ const itemTotal = qty * price;
1425
+ newInvoiceItems[index].item_total = itemTotal;
1426
+ const tableBody = document.getElementById('newInvoiceItemsTable').getElementsByTagName('tbody')[0];
1427
+ if (tableBody.rows[index]) {
1428
+ tableBody.rows[index].querySelector('.item-total-display').textContent = itemTotal.toFixed(2);
1429
  }
1430
+ updateNewInvoiceTotal();
1431
  }
1432
 
1433
  function removeInvoiceItemRow(index) {
 
1440
  tableBody.innerHTML = '';
1441
  newInvoiceItems.forEach((item, index) => {
1442
  const newRow = tableBody.insertRow();
1443
+ const productName = item.product_name ? String(item.product_name).replace(/"/g, '&quot;') : '';
1444
+ newRow.innerHTML = `<td><input type="text" placeholder="Название товара" value="${productName}" oninput="updateInvoiceItem(${index}, 'product_name', this.value)"></td><td><input type="number" step="1" min="1" placeholder="1" value="${item.quantity || '1'}" oninput="updateInvoiceItem(${index}, 'quantity', this.value)"></td><td><input type="number" step="0.01" min="0" placeholder="0.00" value="${item.unit_price || ''}" oninput="updateInvoiceItem(${index}, 'unit_price', this.value)"></td><td class="item-total-display">${(item.item_total || 0).toFixed(2)}</td><td><button class="action-btn" onclick="removeInvoiceItemRow(${index})">🗑️</button></td>`;
1445
  });
1446
  updateNewInvoiceTotal();
1447
  }
 
1459
  let deductAmount = parseFloat(deductBonusesInput.value) || 0;
1460
 
1461
  let cappedDeductAmount = Math.max(0, Math.min(deductAmount, availableBonuses, total));
1462
+
1463
+ if (deductAmount > cappedDeductAmount) {
1464
+ deductBonusesInput.value = cappedDeductAmount > 0 ? cappedDeductAmount.toFixed(2) : '';
1465
  }
1466
 
1467
  let finalAmount = total - cappedDeductAmount;
 
1477
  statusEl.textContent = 'Пользователь не выбран.';
1478
  return;
1479
  }
1480
+ const itemsToAdd = newInvoiceItems.filter(item => item.product_name && item.product_name.trim() !== '' && (item.quantity > 0 || item.unit_price > 0));
1481
  if (itemsToAdd.length === 0) {
1482
  statusEl.style.color = 'var(--admin-danger)';
1483
  statusEl.textContent = 'Добавьте хотя бы один товар.';