update
This commit is contained in:
123
sheets/templates/Rechnung.html
Normal file
123
sheets/templates/Rechnung.html
Normal file
@@ -0,0 +1,123 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="spreadsheet-container">
|
||||
<style>
|
||||
.spreadsheet-container { padding: 20px; }
|
||||
.sheet-navigation {
|
||||
display:flex; justify-content:space-between; align-items:center;
|
||||
margin-bottom:20px; padding:10px; background:#f8f9fa; border-radius:5px;
|
||||
}
|
||||
.sheet-navigation h2 { margin:0; font-size:20px; font-weight:bold; }
|
||||
.sheet-navigation a { text-decoration:none; color:#007bff; font-weight:bold; }
|
||||
.unit-cell {
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
background: #f9f9f9;
|
||||
}
|
||||
.table-container {
|
||||
background:#fff; border-radius:5px; padding:10px;
|
||||
box-shadow:0 2px 4px rgba(0,0,0,0.05);
|
||||
}
|
||||
.sheet-table { width:100%; border-collapse:collapse; font-size:14px; }
|
||||
.sheet-table th, .sheet-table td { border:1px solid #dee2e6; padding:4px 6px; }
|
||||
.sheet-table th { background:#f2f2f2; font-weight:bold; text-align:center; }
|
||||
.row-label { background:#f9f9f9; font-weight:bold; white-space:nowrap; }
|
||||
.number-cell { text-align:right; white-space:nowrap; }
|
||||
.sheet-table tbody tr:nth-child(even) { background:#fcfcfc; }
|
||||
.sheet-table tbody tr:hover { background:#f1f3f5; }
|
||||
|
||||
.cell-input {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
text-align: right;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 3px;
|
||||
padding: 2px 4px;
|
||||
font-size: 14px;
|
||||
background: #fff;
|
||||
}
|
||||
.sheet-table {
|
||||
table-layout: fixed;
|
||||
width: auto;
|
||||
}
|
||||
.cell-input {
|
||||
width: 80px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.sheet-table th,
|
||||
.sheet-table td {
|
||||
padding: 4px 6px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.actions-bar { margin-top: 12px; display:flex; gap:10px; align-items:center; }
|
||||
.btn {
|
||||
padding: 6px 10px; border:1px solid #ced4da; border-radius:4px;
|
||||
background:#fff; cursor:pointer; font-weight:600;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="sheet-navigation">
|
||||
<a href="{% url 'clients_list' %}">← Übersicht</a>
|
||||
<h2>Rechnung</h2>
|
||||
<a href="{% url 'abrechnung' %}">Abrechnung</a>
|
||||
</div>
|
||||
|
||||
{% if needs_interval %}
|
||||
<div class="table-container">
|
||||
<p style="margin:0;">Bitte zuerst ein 6-Monats-Intervall auf der Übersichtsseite auswählen.</p>
|
||||
</div>
|
||||
{% else %}
|
||||
|
||||
<div class="table-container">
|
||||
<table class="sheet-table spreadsheet-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Arbeitsgruppe</th>
|
||||
<th>Tabellenkürzel</th>
|
||||
<th>Name</th>
|
||||
<th>Heliumverluste (€)</th>
|
||||
<th>Heliumverluste (l)</th>
|
||||
<th>Verbr. u. Repar. (€)</th>
|
||||
<th>Gesamtverflüssigung (l)</th>
|
||||
<th>Preis (€/l)</th>
|
||||
<th>Bezogene Menge (l)</th>
|
||||
<th>Verflüssigungskosten (€)</th>
|
||||
<th>Verlustkosten (€)</th>
|
||||
<th>Gaskosten (€)</th>
|
||||
<th>Gutschriften (€)</th>
|
||||
<th>Personalkosten (€)</th>
|
||||
<th>Anteil Personalkosten (€)</th>
|
||||
<th>Gesamtkosten (€)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for r in rows %}
|
||||
<tr>
|
||||
<td>{{ r.arbeitsgruppe }}</td>
|
||||
<td>{{ r.tabellenkuerzel }}</td>
|
||||
<td>{{ r.name }}</td>
|
||||
|
||||
<td>{{ r.heliumverluste_eur|floatformat:2 }}</td>
|
||||
<td>{{ r.heliumverluste_l|floatformat:2 }}</td>
|
||||
<td>{{ r.verbr_u_repar_eur|floatformat:2 }}</td>
|
||||
<td>{{ r.gesamtverfluessigung_l|floatformat:2 }}</td>
|
||||
<td>{{ r.preis_eur_l|floatformat:4 }}</td>
|
||||
|
||||
<td>{{ r.bezogene_menge_l|floatformat:2 }}</td>
|
||||
<td>{{ r.verfluessigungskosten_eur|floatformat:2 }}</td>
|
||||
<td>{{ r.verlustkosten_eur|floatformat:2 }}</td>
|
||||
<td>{{ r.gaskosten_eur|floatformat:2 }}</td>
|
||||
<td>{{ r.gutschriften_eur|floatformat:2 }}</td>
|
||||
<td>{{ r.personalkosten_eur|floatformat:2 }}</td>
|
||||
<td>{{ r.anteil_personal_eur|floatformat:2 }}</td>
|
||||
<td>{{ r.gesamtkosten_eur|floatformat:2 }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
370
sheets/templates/abrechnung.html
Normal file
370
sheets/templates/abrechnung.html
Normal file
@@ -0,0 +1,370 @@
|
||||
{% extends "base.html" %}
|
||||
{% load dict_extras %}
|
||||
{% block content %}
|
||||
<div class="spreadsheet-container">
|
||||
|
||||
<style>
|
||||
.spreadsheet-container { padding: 20px; }
|
||||
.sheet-navigation {
|
||||
display:flex; justify-content:space-between; align-items:center;
|
||||
margin-bottom:20px; padding:10px; background:#f8f9fa; border-radius:5px;
|
||||
}
|
||||
.sheet-navigation h2 { margin:0; font-size:20px; font-weight:bold; }
|
||||
.sheet-navigation a { text-decoration:none; color:#007bff; font-weight:bold; }
|
||||
.unit-cell {
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
background: #f9f9f9;
|
||||
}
|
||||
.table-container {
|
||||
background:#fff; border-radius:5px; padding:10px;
|
||||
box-shadow:0 2px 4px rgba(0,0,0,0.05);
|
||||
}
|
||||
.sheet-table { width:100%; border-collapse:collapse; font-size:14px; }
|
||||
.sheet-table th, .sheet-table td { border:1px solid #dee2e6; padding:4px 6px; }
|
||||
.sheet-table th { background:#f2f2f2; font-weight:bold; text-align:center; }
|
||||
.row-label { background:#f9f9f9; font-weight:bold; white-space:nowrap; }
|
||||
.number-cell { text-align:right; white-space:nowrap; }
|
||||
.sheet-table tbody tr:nth-child(even) { background:#fcfcfc; }
|
||||
.sheet-table tbody tr:hover { background:#f1f3f5; }
|
||||
|
||||
.cell-input {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
text-align: right;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 3px;
|
||||
padding: 2px 4px;
|
||||
font-size: 14px;
|
||||
background: #fff;
|
||||
}
|
||||
.sheet-table {
|
||||
table-layout: fixed;
|
||||
width: auto;
|
||||
}
|
||||
.cell-input {
|
||||
width: 80px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.sheet-table th,
|
||||
.sheet-table td {
|
||||
padding: 4px 6px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.actions-bar { margin-top: 12px; display:flex; gap:10px; align-items:center; }
|
||||
.btn {
|
||||
padding: 6px 10px; border:1px solid #ced4da; border-radius:4px;
|
||||
background:#fff; cursor:pointer; font-weight:600;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="sheet-navigation">
|
||||
<a href="{% url 'clients_list' %}">← Übersicht</a>
|
||||
<h2>Abrechnung</h2>
|
||||
<a href="{% url 'halfyear_balance' %}">Halbjahres-Bilanz</a>
|
||||
</div>
|
||||
<div id="autosaveStatus" style="margin:8px 0; font-size: 14px;"></div>
|
||||
{% if needs_interval %}
|
||||
<div class="table-container">
|
||||
<p>Bitte zuerst ein Halbjahr auswählen (auf der Übersicht-Seite), damit der Zeitraum bekannt ist.</p>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="table-container">
|
||||
|
||||
<div style="margin-bottom:10px; font-weight:600;">
|
||||
Aufstellung Heliumverbrauch für Zeitraum: <b>{{ interval_text }}</b>
|
||||
</div>
|
||||
<div class="abrechnung-row" style="display:flex; gap:24px; align-items:flex-start; overflow-x:auto;">
|
||||
<div class="abrechnung-left" style="flex: 0 0 auto;">
|
||||
<table class="sheet-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:180px;">← Fachgebiet →</th>
|
||||
|
||||
{% for col_key, col_label in columns %}
|
||||
<th style="width:90px;">{{ col_label }}</th>
|
||||
{% endfor %}
|
||||
|
||||
<th style="width:70px;">Einheit</th> <!-- 👈 ADD THIS -->
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for r in rows %}
|
||||
<tr>
|
||||
<td class="row-label">{{ r.label }}</td>
|
||||
|
||||
{% for c in r.cells %}
|
||||
<td class="number-cell">
|
||||
{% if r.row_key == "sonstiges" %}
|
||||
<span class="sonstiges-text" data-col-key="{{ c.col_key }}">
|
||||
{{ sonstiges_text|get_item:c.col_key }}
|
||||
</span>
|
||||
{% else %}
|
||||
{% if r.editable %}
|
||||
<input
|
||||
class="cell-input editable"
|
||||
type="text"
|
||||
value="{% if c.value is not None %}{{ c.value|floatformat }}{% endif %}"
|
||||
data-row-key="{{ r.row_key }}"
|
||||
data-col-key="{{ c.col_key }}"
|
||||
/>
|
||||
{% else %}
|
||||
<span class="cell-value"
|
||||
data-row-key="{{ r.row_key }}"
|
||||
data-col-key="{{ c.col_key }}">
|
||||
{% if c.value is not None %}{{ c.value|floatformat:2 }}{% endif %}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
|
||||
<td class="unit-cell">{{ r.unit }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
|
||||
</table>
|
||||
</div> <!-- end abrechnung-left -->
|
||||
|
||||
<div class="abrechnung-right" style="flex: 0 0 auto;">
|
||||
<table class="sheet-table spreadsheet-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Summe Lichtwiese<br>IJKL</th>
|
||||
<th style="min-width:180px; text-align:center;">
|
||||
← Fachgebiet →
|
||||
</th>
|
||||
<th>Summe Lichtwiese<br>NOP (Check)</th>
|
||||
<th>Summe<br>Stadtmitte</th>
|
||||
<th>Summe<br>(Check)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for r in right_summary_rows %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if r.is_text %}{{ r.ijkl }}{% else %}{{ r.ijkl|floatformat:2 }}{% endif %}
|
||||
</td>
|
||||
|
||||
<td class="row-label">
|
||||
{{ r.label }}
|
||||
{% if r.unit %}
|
||||
<span style="float:right; opacity:0.7;">{{ r.unit }}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{% if r.is_text %}{{ r.nop }}{% else %}{{ r.nop|floatformat:2 }}{% endif %}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{% if r.is_text %}{{ r.stadt }}{% else %}{{ r.stadt|floatformat:2 }}{% endif %}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{% if r.is_text %}{{ r.check }}{% else %}{{ r.check|floatformat:2 }}{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
</div> <!-- end abrechnung-row -->
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
// ===============================
|
||||
// Helpers
|
||||
// ===============================
|
||||
function getCookie(name) {
|
||||
const value = `; ${document.cookie}`;
|
||||
const parts = value.split(`; ${name}=`);
|
||||
if (parts.length === 2) return parts.pop().split(";").shift();
|
||||
return "";
|
||||
}
|
||||
|
||||
function parseNum(val) {
|
||||
if (val == null) return 0;
|
||||
let s = String(val).trim();
|
||||
if (!s) return 0;
|
||||
s = s.replace(/\s+/g, "");
|
||||
|
||||
const hasComma = s.includes(",");
|
||||
const hasDot = s.includes(".");
|
||||
if (hasComma && hasDot) {
|
||||
// German: 1.234,56 -> 1234.56
|
||||
s = s.replace(/\./g, "").replace(",", ".");
|
||||
} else if (hasComma && !hasDot) {
|
||||
// 35,08 -> 35.08
|
||||
s = s.replace(",", ".");
|
||||
} else {
|
||||
// 35.08 stays 35.08
|
||||
}
|
||||
|
||||
const n = parseFloat(s);
|
||||
return isNaN(n) ? 0 : n;
|
||||
}
|
||||
|
||||
function fmt2(n) {
|
||||
return (Math.round(n * 100) / 100).toFixed(2);
|
||||
}
|
||||
|
||||
function getInputValue(rowKey, colKey) {
|
||||
const inp = document.querySelector(
|
||||
`.cell-input[data-row-key="${rowKey}"][data-col-key="${colKey}"]`
|
||||
);
|
||||
return inp ? inp.value : "";
|
||||
}
|
||||
|
||||
function getCellSpan(rowKey, colKey) {
|
||||
return document.querySelector(
|
||||
`.cell-value[data-row-key="${rowKey}"][data-col-key="${colKey}"]`
|
||||
);
|
||||
}
|
||||
|
||||
function setDisplay(rowKey, colKey, value) {
|
||||
const el = getCellSpan(rowKey, colKey);
|
||||
if (el) el.textContent = fmt2(value);
|
||||
}
|
||||
|
||||
function getDisplayNum(rowKey, colKey) {
|
||||
const el = getCellSpan(rowKey, colKey);
|
||||
if (!el) return 0;
|
||||
return parseNum(el.textContent);
|
||||
}
|
||||
|
||||
function getSonstigesCell(colKey) {
|
||||
return document.querySelector(
|
||||
`.sonstiges-text[data-col-key="${colKey}"]`
|
||||
);
|
||||
}
|
||||
|
||||
function setSonstiges(colKey, betragVal) {
|
||||
const el = getSonstigesCell(colKey);
|
||||
if (!el) return;
|
||||
|
||||
let txt = "--------------";
|
||||
if (betragVal < 0) txt = "Gutschrift";
|
||||
else if (betragVal > 0) txt = "Nachzahlung";
|
||||
|
||||
el.textContent = txt;
|
||||
}
|
||||
|
||||
// ===============================
|
||||
// Config
|
||||
// ===============================
|
||||
const SAVE_URL = "{% url 'abrechnung_autosave' %}";
|
||||
const CSRF = getCookie("csrftoken");
|
||||
|
||||
// from backend: context["bezugskosten_gashe"] = bezugskosten_gashe
|
||||
const BEZUGSKOSTEN_GASHE = parseNum("{{ bezugskosten_gashe|floatformat:6 }}");
|
||||
|
||||
// ===============================
|
||||
// Autosave (debounced)
|
||||
// ===============================
|
||||
let debounceTimer = null;
|
||||
let pending = {}; // "row|col" -> {row_key,col_key,value}
|
||||
|
||||
function queueSave(rowKey, colKey, value) {
|
||||
pending[rowKey + "|" + colKey] = { row_key: rowKey, col_key: colKey, value: value };
|
||||
if (debounceTimer) clearTimeout(debounceTimer);
|
||||
debounceTimer = setTimeout(flushPending, 400);
|
||||
}
|
||||
|
||||
async function flushPending() {
|
||||
const changes = Object.values(pending);
|
||||
pending = {};
|
||||
if (!changes.length) return;
|
||||
|
||||
try {
|
||||
const resp = await fetch(SAVE_URL, {
|
||||
method: "POST",
|
||||
credentials: "same-origin",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRFToken": CSRF,
|
||||
},
|
||||
body: JSON.stringify({ changes })
|
||||
});
|
||||
|
||||
const text = await resp.text();
|
||||
if (!resp.ok) {
|
||||
console.error("Autosave failed:", resp.status, text);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Autosave error:", e);
|
||||
}
|
||||
}
|
||||
|
||||
// ===============================
|
||||
// Live Recalculation (per column)
|
||||
// ===============================
|
||||
function recalcColumn(colKey) {
|
||||
// Editable inputs
|
||||
const ghe = parseNum(getInputValue("ghe_bezug", colKey));
|
||||
const betrag = parseNum(getInputValue("betrag", colKey));
|
||||
const gutschriften = parseNum(getInputValue("gutschriften", colKey));
|
||||
|
||||
// Usually computed display
|
||||
const personal = getDisplayNum("umlage_personal_5", colKey);
|
||||
|
||||
// Computed displays already present from server
|
||||
const sum14 = getDisplayNum("summe_anteile_1_4", colKey);
|
||||
const heVerbrauch = getDisplayNum("he_verbrauch", colKey);
|
||||
|
||||
// 4-Kosten He-Gas-Bezug = GHe-Bezug * Bezugskosten-GasHe
|
||||
const kosten4 = ghe * BEZUGSKOSTEN_GASHE;
|
||||
setDisplay("kosten_he_gas_bezug_4", colKey, kosten4);
|
||||
|
||||
// Rechnungsbetrag = Summe Anteile 1-4 − Gutschriften + Betrag + 5-Umlage Personal
|
||||
const rechnungsbetrag = sum14 - gutschriften + betrag + personal;
|
||||
setDisplay("rechnungsbetrag", colKey, rechnungsbetrag);
|
||||
|
||||
// eff. L-He-Preis = Rechnungsbetrag / He-Verbrauch
|
||||
const eff = heVerbrauch !== 0 ? (rechnungsbetrag / heVerbrauch) : 0;
|
||||
setDisplay("eff_lhe_preis", colKey, eff);
|
||||
|
||||
// Sonstiges = IF(Betrag=0,"--------------",IF(Betrag<0,"Gutschrift","Nachzahlung"))
|
||||
setSonstiges(colKey, betrag);
|
||||
}
|
||||
|
||||
// ===============================
|
||||
// Event listener
|
||||
// ===============================
|
||||
document.addEventListener("input", function (e) {
|
||||
const t = e.target;
|
||||
if (!t.classList.contains("cell-input")) return;
|
||||
if (!t.classList.contains("editable")) return;
|
||||
|
||||
const rowKey = t.dataset.rowKey;
|
||||
const colKey = t.dataset.colKey;
|
||||
if (!rowKey || !colKey) return;
|
||||
|
||||
// autosave this edited cell
|
||||
queueSave(rowKey, colKey, t.value);
|
||||
|
||||
// live recompute dependent rows for this column
|
||||
if (rowKey === "ghe_bezug" || rowKey === "betrag" || rowKey === "gutschriften") {
|
||||
recalcColumn(colKey);
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -35,15 +35,19 @@
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
th:nth-child(1), td:nth-child(1) { width: 5%; } /* # column */
|
||||
th:nth-child(2), td:nth-child(2) { width: 10%; } /* Buchungsdatum */
|
||||
th:nth-child(3), td:nth-child(3) { width: 15%; } /* Rechnungsnummer */
|
||||
th:nth-child(4), td:nth-child(4) { width: 10%; } /* Kostentyp */
|
||||
th:nth-child(5), td:nth-child(5) { width: 10%; } /* Gasvolumen */
|
||||
th:nth-child(6), td:nth-child(6) { width: 10%; } /* Betrag */
|
||||
th:nth-child(7), td:nth-child(7) { width: 25%; } /* Beschreibung */
|
||||
th:nth-child(8), td:nth-child(8) { width: 15%; } /* Actions */
|
||||
|
||||
th:nth-child(1), td:nth-child(1) { width: 4%; }
|
||||
th:nth-child(2), td:nth-child(2) { width: 12%; }
|
||||
th:nth-child(3), td:nth-child(3) { width: 8%; }
|
||||
th:nth-child(4), td:nth-child(4) { width: 12%; }
|
||||
th:nth-child(5), td:nth-child(5) { width: 8%; }
|
||||
th:nth-child(6), td:nth-child(6) { width: 8%; }
|
||||
th:nth-child(7), td:nth-child(7) { width: 8%; }
|
||||
th:nth-child(8), td:nth-child(8) { width: 8%; }
|
||||
th:nth-child(9), td:nth-child(9) { width: 8%; }
|
||||
th:nth-child(10), td:nth-child(10) { width: 8%; }
|
||||
th:nth-child(11), td:nth-child(11) { width: 12%; }
|
||||
th:nth-child(12), td:nth-child(12) { width: 8%; }
|
||||
|
||||
.actions {
|
||||
white-space: nowrap; /* Prevent buttons from wrapping */
|
||||
}
|
||||
@@ -147,74 +151,126 @@
|
||||
|
||||
<h2>Betriebskosten</h2>
|
||||
<div class="table-container">
|
||||
<button class="add-row-btn" id="add-row-btn">Add Row</button>
|
||||
<table id="betriebskosten-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Buchungsdatum</th>
|
||||
<th>Rechnungsnummer</th>
|
||||
<th>Kostentyp</th>
|
||||
<th>Gasvolumen (L)</th>
|
||||
<th>Betrag (€)</th>
|
||||
<th>Beschreibung</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in items %}
|
||||
<tr data-id="{{ item.id }}">
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ item.buchungsdatum|date:"Y-m-d" }}</td>
|
||||
<td>{{ item.rechnungsnummer }}</td>
|
||||
<td>{{ item.get_kostentyp_display }}</td>
|
||||
<td>{{ item.gas_volume|default_if_none:"-" }}</td>
|
||||
<td>{{ item.betrag }}</td>
|
||||
<td>{{ item.beschreibung|default:"" }}</td>
|
||||
<td class="actions">
|
||||
<button class="edit-btn">Edit</button>
|
||||
<button class="delete-btn">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="8" style="text-align: center;">No entries found</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<div style="margin-bottom:20px;">
|
||||
<label><strong>Personalkosten:</strong></label>
|
||||
<input id="personalkosten"
|
||||
type="number"
|
||||
step="0.01"
|
||||
value="{{ summary.personalkosten }}"
|
||||
style="width:200px;">
|
||||
</div>
|
||||
|
||||
<table style="margin-bottom:20px;">
|
||||
<tr>
|
||||
<td>Instandhaltung</td>
|
||||
<td>{{ summary.instandhaltung|floatformat:2 }} €</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Verflüssigungskosten L-He</td>
|
||||
<td>{{ verfluessigungskosten_lhe|floatformat:6 }} €/L-He</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Heliumkosten</td>
|
||||
<td>{{ summary.heliumkosten|floatformat:2 }} €</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Bezugskosten -GasHe</td>
|
||||
<td>{{ summary.bezugskosten_gashe|floatformat:2 }} €/m³</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Umlage Personal</td>
|
||||
<td id="umlage-personal">{{ summary.umlage_personal|floatformat:2 }} €</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<button class="add-row-btn" id="add-row-btn">Add Row</button>
|
||||
<table id="betriebskosten-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Gegenstand</th>
|
||||
<th>Zahlungsdatum</th>
|
||||
<th>Firma</th>
|
||||
<th>Kostentyp</th>
|
||||
<th>Gasvolumen (m³)</th>
|
||||
<th>Gasvolumen (Liter)</th>
|
||||
<th>Preis pro m³ (€)</th>
|
||||
<th>Preis pro Liter (€)</th>
|
||||
<th>Betrag (€)</th>
|
||||
<th>Beschreibung</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for item in items %}
|
||||
<tr data-id="{{ item.id }}">
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ item.gegenstand }}</td>
|
||||
<td>{{ item.buchungsdatum|date:"Y-m-d" }}</td>
|
||||
<td>{{ item.rechnungsnummer }}</td>
|
||||
<td>{{ item.get_kostentyp_display }}</td>
|
||||
|
||||
<td>{{ item.gas_volume|default_if_none:"-" }}</td>
|
||||
<td>{% if item.gas_volume %}{{ item.gas_volume_liter|floatformat:2 }}{% else %}-{% endif %}</td>
|
||||
<td>{% if item.price_per_m3 %}{{ item.price_per_m3|floatformat:2 }}{% else %}-{% endif %}</td>
|
||||
<td>{% if item.price_per_liter %}{{ item.price_per_liter|floatformat:2 }}{% else %}-{% endif %}</td>
|
||||
|
||||
<td>{{ item.betrag }}</td>
|
||||
<td>{{ item.beschreibung|default:"" }}</td>
|
||||
<td class="actions">
|
||||
<button class="edit-btn">Edit</button>
|
||||
<button class="delete-btn">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="12" style="text-align:center; padding:20px;">
|
||||
No entries found
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Add Popup -->
|
||||
<div id="add-popup" class="popup">
|
||||
<span class="close-btn">×</span>
|
||||
<h3>Betriebskosten Eintrag</h3>
|
||||
|
||||
<label for="add-gegenstand">Gegenstand:</label>
|
||||
<input type="text" id="add-gegenstand" required>
|
||||
|
||||
<label for="add-buchungsdatum">Buchungsdatum:</label>
|
||||
<label for="add-buchungsdatum">Zahlungsdatum:</label>
|
||||
<input type="date" id="add-buchungsdatum" required>
|
||||
|
||||
<label for="add-rechnungsnummer">Rechnungsnummer:</label>
|
||||
<label for="add-rechnungsnummer">Firma:</label>
|
||||
<input type="text" id="add-rechnungsnummer" required>
|
||||
|
||||
<label for="add-kostentyp">Kostentyp:</label>
|
||||
<select id="add-kostentyp" required onchange="toggleGasVolume('add')">
|
||||
<option value="">Bitte auswählen</option>
|
||||
<option value="sach">Sachkosten</option>
|
||||
<option value="ln2">LN2</option>
|
||||
<option value="helium">Helium</option>
|
||||
<option value="inv">Inventar</option>
|
||||
</select>
|
||||
<option value="" selected disabled>Bitte auswählen</option>
|
||||
<option value="sach">Sach</option>
|
||||
<option value="helium">Helium</option></select>
|
||||
|
||||
<div id="add-gas-volume-group" style="display: none;">
|
||||
<label for="add-gas-volume">Gasvolumen (Liter):</label>
|
||||
<input type="number" id="add-gas-volume" step="0.01" min="0" oninput="calculatePrice('add')">
|
||||
<label for="add-gas-volume">Gasvolumen (m³):</label>
|
||||
<input type="number" id="add-gas-volume" step="0.01" min="0" oninput="calculateHelium('add')">
|
||||
|
||||
<label for="add-gas-volume-liter">Gasvolumen (Liter):</label>
|
||||
<input type="text" id="add-gas-volume-liter" readonly>
|
||||
</div>
|
||||
|
||||
<label for="add-betrag">Betrag (€):</label>
|
||||
<input type="number" id="add-betrag" step="0.01" min="0" required oninput="calculatePrice('add')">
|
||||
<input type="number" id="add-betrag" step="0.01" min="0" required oninput="calculateHelium('add')">
|
||||
|
||||
<div id="add-price-per-liter-group" style="display: none;">
|
||||
<label for="add-price-per-liter">Preis pro Liter (€):</label>
|
||||
<label for="add-price-per-m3">Preis pro Liter (m³) (€) (auto):</label>
|
||||
<input type="text" id="add-price-per-m3" readonly>
|
||||
|
||||
<label for="add-price-per-liter">Preis (Liter) (€):</label>
|
||||
<input type="text" id="add-price-per-liter" readonly>
|
||||
</div>
|
||||
|
||||
@@ -233,32 +289,38 @@
|
||||
<span class="close-btn">×</span>
|
||||
<h3>Betriebskosten Eintrag</h3>
|
||||
<input type="hidden" id="edit-id">
|
||||
|
||||
<label for="edit-gegenstand">Gegenstand:</label>
|
||||
<input type="text" id="edit-gegenstand" required>
|
||||
|
||||
<label for="edit-buchungsdatum">Buchungsdatum:</label>
|
||||
<label for="edit-buchungsdatum">Zahlungsdatum:</label>
|
||||
<input type="date" id="edit-buchungsdatum" required>
|
||||
|
||||
<label for="edit-rechnungsnummer">Rechnungsnummer:</label>
|
||||
<label for="edit-rechnungsnummer">Firma:</label>
|
||||
<input type="text" id="edit-rechnungsnummer" required>
|
||||
|
||||
<label for="edit-kostentyp">Kostentyp:</label>
|
||||
<select id="edit-kostentyp" required onchange="toggleGasVolume('edit')">
|
||||
<option value="">Bitte auswählen</option>
|
||||
<option value="sach">Sachkosten</option>
|
||||
<option value="ln2">LN2</option>
|
||||
<option value="helium">Helium</option>
|
||||
<option value="inv">Inventar</option>
|
||||
</select>
|
||||
<option value="" selected disabled>Bitte auswählen</option>
|
||||
<option value="sach">Sach</option>
|
||||
<option value="helium">Helium</option></select>
|
||||
|
||||
<div id="edit-gas-volume-group" style="display: none;">
|
||||
<label for="edit-gas-volume">Gasvolumen (Liter):</label>
|
||||
<input type="number" id="edit-gas-volume" step="0.01" min="0" oninput="calculatePrice('edit')">
|
||||
<label for="edit-gas-volume">Gasvolumen (m³):</label>
|
||||
<input type="number" id="edit-gas-volume" step="0.01" min="0" oninput="calculateHelium('edit')">
|
||||
|
||||
<label for="edit-gas-volume-liter">Gasvolumen (Liter) (auto):</label>
|
||||
<input type="text" id="edit-gas-volume-liter" readonly>
|
||||
</div>
|
||||
|
||||
<label for="edit-betrag">Betrag (€):</label>
|
||||
<input type="number" id="edit-betrag" step="0.01" min="0" required oninput="calculatePrice('edit')">
|
||||
<input type="number" id="edit-betrag" step="0.01" min="0" required oninput="calculateHelium('edit')">
|
||||
|
||||
<div id="edit-price-per-liter-group" style="display: none;">
|
||||
<label for="edit-price-per-liter">Preis pro Liter (€):</label>
|
||||
<label for="edit-price-per-m3">Preis pro Liter (m³) (€) (auto):</label>
|
||||
<input type="text" id="edit-price-per-m3" readonly>
|
||||
|
||||
<label for="edit-price-per-liter">Preis (Liter) (€) (auto):</label>
|
||||
<input type="text" id="edit-price-per-liter" readonly>
|
||||
</div>
|
||||
|
||||
@@ -276,6 +338,11 @@
|
||||
$(document).ready(function () {
|
||||
// Open add popup
|
||||
$('#add-row-btn').on('click', function () {
|
||||
// Reset fields so the placeholder "Gegenstand" is shown
|
||||
$('#add-popup input, #add-popup textarea').val('');
|
||||
$('#add-kostentyp').val('');
|
||||
toggleGasVolume('add');
|
||||
calculateHelium('add');
|
||||
$('#add-popup').fadeIn();
|
||||
});
|
||||
|
||||
@@ -287,6 +354,7 @@
|
||||
// Add new entry
|
||||
$('#save-add').on('click', function() {
|
||||
const formData = {
|
||||
'gegenstand': $('#add-gegenstand').val(),
|
||||
'buchungsdatum': $('#add-buchungsdatum').val(),
|
||||
'rechnungsnummer': $('#add-rechnungsnummer').val(),
|
||||
'kostentyp': $('#add-kostentyp').val(),
|
||||
@@ -297,7 +365,8 @@
|
||||
};
|
||||
|
||||
// Validate required fields
|
||||
if (!formData.buchungsdatum || !formData.rechnungsnummer || !formData.kostentyp || !formData.betrag) {
|
||||
if (!formData.gegenstand || !formData.buchungsdatum || !formData.rechnungsnummer || !formData.kostentyp || !formData.betrag) {
|
||||
|
||||
alert('Bitte füllen Sie alle erforderlichen Felder aus');
|
||||
return;
|
||||
}
|
||||
@@ -312,10 +381,14 @@
|
||||
const newRow = `
|
||||
<tr data-id="${response.id}">
|
||||
<td>${$('#betriebskosten-table tbody tr').length + 1}</td>
|
||||
<td>${response.gegenstand || ''}</td>
|
||||
<td>${response.buchungsdatum}</td>
|
||||
<td>${response.rechnungsnummer}</td>
|
||||
<td>${response.kostentyp_display}</td>
|
||||
<td>${response.gas_volume || '-'}</td>
|
||||
<td>${response.gas_volume_m3 || '-'}</td>
|
||||
<td>${response.gas_volume_liter || '-'}</td>
|
||||
<td>${response.price_per_m3 || '-'}</td>
|
||||
<td>${response.price_per_liter || '-'}</td>
|
||||
<td>${response.betrag}</td>
|
||||
<td>${response.beschreibung || ''}</td>
|
||||
<td class="actions">
|
||||
@@ -323,7 +396,7 @@
|
||||
<button class="delete-btn">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
`;
|
||||
$('#betriebskosten-table tbody').append(newRow);
|
||||
$('#add-popup').fadeOut();
|
||||
$('#add-popup input, #add-popup select, #add-popup textarea').val('');
|
||||
@@ -344,26 +417,28 @@
|
||||
|
||||
// Fill the edit form with current data
|
||||
$('#edit-id').val(id);
|
||||
$('#edit-buchungsdatum').val(row.find('td:eq(1)').text());
|
||||
$('#edit-rechnungsnummer').val(row.find('td:eq(2)').text());
|
||||
|
||||
$('#edit-gegenstand').val(row.find('td:eq(1)').text());
|
||||
$('#edit-buchungsdatum').val(row.find('td:eq(2)').text());
|
||||
$('#edit-rechnungsnummer').val(row.find('td:eq(3)').text());
|
||||
|
||||
const kostentypText = row.find('td:eq(4)').text();
|
||||
// Set kostentyp based on display text
|
||||
const kostentypText = row.find('td:eq(3)').text();
|
||||
|
||||
const kostentypMap = {
|
||||
'Sach': 'sach',
|
||||
'Sachkosten': 'sach',
|
||||
'LN2': 'ln2',
|
||||
'Helium': 'helium',
|
||||
'Inventar': 'inv'
|
||||
|
||||
'Helium': 'helium'
|
||||
};
|
||||
$('#edit-kostentyp').val(kostentypMap[kostentypText] || '');
|
||||
|
||||
$('#edit-gas-volume').val(row.find('td:eq(4)').text() === '-' ? '' : row.find('td:eq(4)').text());
|
||||
$('#edit-betrag').val(row.find('td:eq(5)').text());
|
||||
$('#edit-beschreibung').val(row.find('td:eq(6)').text());
|
||||
$('#edit-gas-volume').val(row.find('td:eq(5)').text() === '-' ? '' : row.find('td:eq(5)').text());
|
||||
$('#edit-betrag').val(row.find('td:eq(6)').text());
|
||||
$('#edit-beschreibung').val(row.find('td:eq(7)').text());
|
||||
|
||||
// Show/hide gas volume based on kostentyp
|
||||
toggleGasVolume('edit');
|
||||
calculatePrice('edit');
|
||||
calculateHelium('edit');
|
||||
|
||||
$('#edit-popup').fadeIn();
|
||||
});
|
||||
@@ -372,6 +447,7 @@
|
||||
$('#save-edit').on('click', function() {
|
||||
const formData = {
|
||||
'id': $('#edit-id').val(),
|
||||
'gegenstand': $('#edit-gegenstand').val(),
|
||||
'buchungsdatum': $('#edit-buchungsdatum').val(),
|
||||
'rechnungsnummer': $('#edit-rechnungsnummer').val(),
|
||||
'kostentyp': $('#edit-kostentyp').val(),
|
||||
@@ -395,14 +471,21 @@
|
||||
if (response.status === 'success') {
|
||||
// Update the row in the table
|
||||
const row = $(`tr[data-id="${response.id}"]`);
|
||||
row.find('td:eq(1)').text(response.buchungsdatum);
|
||||
row.find('td:eq(2)').text(response.rechnungsnummer);
|
||||
row.find('td:eq(3)').text(response.kostentyp_display);
|
||||
row.find('td:eq(4)').text(response.gas_volume || '-');
|
||||
row.find('td:eq(5)').text(response.betrag);
|
||||
row.find('td:eq(6)').text(response.beschreibung || '');
|
||||
row.find('td:eq(1)').text(response.gegenstand || '');
|
||||
row.find('td:eq(2)').text(response.buchungsdatum);
|
||||
row.find('td:eq(3)').text(response.rechnungsnummer);
|
||||
row.find('td:eq(4)').text(response.kostentyp_display);
|
||||
row.find('td:eq(5)').text(response.gas_volume_m3 || '-');
|
||||
row.find('td:eq(6)').text(response.gas_volume_liter || '-');
|
||||
row.find('td:eq(7)').text(response.price_per_m3 || '-');
|
||||
row.find('td:eq(8)').text(response.price_per_liter || '-');
|
||||
row.find('td:eq(9)').text(response.betrag);
|
||||
row.find('td:eq(10)').text(response.beschreibung || '');
|
||||
|
||||
$('#edit-popup').fadeOut();
|
||||
$('#betriebskosten-table tbody tr').each(function(index) {
|
||||
$(this).find('td:first').text(index + 1);
|
||||
});
|
||||
} else {
|
||||
alert('Error: ' + (response.message || 'Failed to update entry'));
|
||||
}
|
||||
@@ -417,6 +500,10 @@
|
||||
$(document).on('click', '.delete-btn', function () {
|
||||
const row = $(this).closest('tr');
|
||||
const id = row.data('id');
|
||||
if (!id) {
|
||||
alert("Invalid entry ID. Cannot delete this row.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm('Are you sure you want to delete this entry?')) return;
|
||||
|
||||
@@ -445,35 +532,83 @@
|
||||
});
|
||||
});
|
||||
|
||||
// Toggle gas volume field based on kostentyp
|
||||
// Toggle helium-only fields based on Kostentyp
|
||||
function toggleGasVolume(type) {
|
||||
const kostentyp = $(`#${type}-kostentyp`).val();
|
||||
const gasVolumeGroup = $(`#${type}-gas-volume-group`);
|
||||
const pricePerLiterGroup = $(`#${type}-price-per-liter-group`);
|
||||
|
||||
const priceGroup = $(`#${type}-price-per-liter-group`);
|
||||
|
||||
if (kostentyp === 'helium') {
|
||||
gasVolumeGroup.show();
|
||||
pricePerLiterGroup.show();
|
||||
priceGroup.show();
|
||||
calculateHelium(type);
|
||||
} else {
|
||||
gasVolumeGroup.hide();
|
||||
pricePerLiterGroup.hide();
|
||||
priceGroup.hide();
|
||||
|
||||
// reset helium-only fields
|
||||
$(`#${type}-gas-volume`).val('');
|
||||
$(`#${type}-gas-volume-liter`).val('');
|
||||
$(`#${type}-price-per-m3`).val('');
|
||||
$(`#${type}-price-per-liter`).val('');
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate price per liter
|
||||
function calculatePrice(type) {
|
||||
// Helium calculations (all auto/read-only fields)
|
||||
// Liter = m³ / 0.75
|
||||
// Preis/m³ = Betrag / m³
|
||||
// Preis/Liter = Betrag / Liter
|
||||
function calculateHelium(type) {
|
||||
const kostentyp = $(`#${type}-kostentyp`).val();
|
||||
const volume = parseFloat($(`#${type}-gas-volume`).val()) || 0;
|
||||
const m3 = parseFloat($(`#${type}-gas-volume`).val()) || 0;
|
||||
const betrag = parseFloat($(`#${type}-betrag`).val()) || 0;
|
||||
|
||||
if (kostentyp === 'helium' && volume > 0 && betrag > 0) {
|
||||
$(`#${type}-price-per-liter`).val((betrag / volume).toFixed(2) + ' €/L');
|
||||
|
||||
if (kostentyp !== 'helium') return;
|
||||
|
||||
if (m3 > 0) {
|
||||
const liters = m3 / 0.75;
|
||||
$(`#${type}-gas-volume-liter`).val(liters.toFixed(2));
|
||||
|
||||
if (betrag > 0) {
|
||||
const priceM3 = betrag / m3;
|
||||
const priceLiter = betrag / liters;
|
||||
|
||||
$(`#${type}-price-per-m3`).val(priceM3.toFixed(2));
|
||||
$(`#${type}-price-per-liter`).val(priceLiter.toFixed(2));
|
||||
} else {
|
||||
$(`#${type}-price-per-m3`).val('');
|
||||
$(`#${type}-price-per-liter`).val('');
|
||||
}
|
||||
} else {
|
||||
$(`#${type}-gas-volume-liter`).val('');
|
||||
$(`#${type}-price-per-m3`).val('');
|
||||
$(`#${type}-price-per-liter`).val('');
|
||||
}
|
||||
}
|
||||
$('#personalkosten').on('change', function () {
|
||||
$.ajax({
|
||||
url: "{% url 'update_personalkosten' %}",
|
||||
method: "POST",
|
||||
data: {
|
||||
personalkosten: $(this).val(),
|
||||
csrfmiddlewaretoken: "{{ csrf_token }}"
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.status === "success") {
|
||||
$('#umlage-personal').text(
|
||||
parseFloat(response.umlage_personal).toFixed(2) + " €"
|
||||
);
|
||||
} else {
|
||||
alert(response.message || "Failed to save Personalkosten");
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
alert(xhr.responseJSON?.message || "Server error while saving Personalkosten");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -72,18 +72,33 @@
|
||||
<td class="total">{{ data.year_total|floatformat:2 }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr class="total">
|
||||
<td><strong>Σ (all clients, selected 6-month interval)</strong></td>
|
||||
|
||||
{% for month in months %}
|
||||
<td>-</td>
|
||||
{% endfor %}
|
||||
|
||||
<td class="total"><strong>{{ interval_total_output_lhe|floatformat:2 }}</strong></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Navigation Buttons -->
|
||||
<div class="navigation-buttons">
|
||||
<a href="{% url 'table_one' %}" class="nav-button">Go to Helium Input</a>
|
||||
<a href="{% url 'table_one' %}" class="nav-button">Go to Helium Input</a>
|
||||
<a href="{% url 'table_two' %}" class="nav-button">Go to Helium Output</a>
|
||||
<a href="/admin/" class="nav-button admin-button">Go to Admin Panel</a>
|
||||
<a href="{% url 'betriebskosten_list' %}" class="nav-button">Betriebskosten</a>
|
||||
<a href="{% url 'monthly_sheet' year=2024 month=1 %}">Monthly Sheets</a>
|
||||
<a href="{% url 'halfyear_balance' %}">Halbjahres Bilanz</a>
|
||||
|
||||
<a href="{% url 'monthly_sheet' year=2024 month=1 %}" class="nav-button">Monthly Sheets</a>
|
||||
<a href="{% url 'halfyear_balance' %}" class="nav-button">Halbjahres Bilanz</a>
|
||||
|
||||
<!-- ✅ NEW -->
|
||||
<a href="{% url 'abrechnung' %}" class="nav-button">Abrechnung</a>
|
||||
<a href="{% url 'rechnung' %}" class="nav-button">Rechnung</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@@ -145,10 +160,11 @@
|
||||
}
|
||||
|
||||
.navigation-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
margin-top: 30px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
margin-top: 30px;
|
||||
flex-wrap: wrap; /* ✅ allow wrapping */
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
|
||||
@@ -117,9 +117,13 @@
|
||||
Halbjahres-Bilanz ({{ first.1 }}/{{ first.0 }} – {{ last.1 }}/{{ last.0 }})
|
||||
{% endwith %}
|
||||
</h2>
|
||||
{% with first=window.0 %}
|
||||
<a href="{% url 'monthly_sheet' first.0 first.1 %}">Monatsblätter</a>
|
||||
{% endwith %}
|
||||
{% if window and window.0 and window.0.0 and window.0.1 %}
|
||||
{% with first=window.0 %}
|
||||
<a href="{% url 'monthly_sheet' first.0 first.1 %}">Monatsblätter</a>
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
<a href="{% url 'monthly_sheet' interval_year interval_start_month %}">Monatsblätter</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="top-tables">
|
||||
@@ -204,7 +208,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<div class="table-container overall-summary-table">
|
||||
<h3>Summe</h3>
|
||||
<table class="sheet-table spreadsheet-table">
|
||||
<thead>
|
||||
@@ -219,9 +223,10 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for r in rows_sum %}
|
||||
<tr data-row-index="{{ r.row_index }}">
|
||||
<tr>
|
||||
<td>{{ r.label }}</td>
|
||||
<td class="sum-col">
|
||||
<td class="sum-col sum-cell">
|
||||
{% if r.is_percent %}
|
||||
{{ r.total|floatformat:2 }}%
|
||||
{% else %}
|
||||
@@ -293,6 +298,155 @@
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="table-container bottom-table-2">
|
||||
<h3>Bottom Table 2 – Verbraucherbestand L-He (read-only)</h3>
|
||||
|
||||
<table class="sheet-table spreadsheet-table">
|
||||
<tbody>
|
||||
<!-- Row 38 -->
|
||||
<tr>
|
||||
<td class="row-label" colspan="5">Verbraucherbestand</td>
|
||||
<td class="readonly-cell">{{ bottom2.j38|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom2.k38|floatformat:2 }}</td>
|
||||
</tr>
|
||||
|
||||
<!-- Row 39 -->
|
||||
<tr>
|
||||
<td class="row-label">+ Anlage:</td>
|
||||
<td>Gefäss 2,5:</td>
|
||||
<td class="readonly-cell">{{ bottom2.g39|floatformat:2 }}</td>
|
||||
<td>Gefäss 1,0:</td>
|
||||
<td class="readonly-cell">{{ bottom2.i39|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom2.j39|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom2.k39|floatformat:2 }}</td>
|
||||
</tr>
|
||||
|
||||
<!-- Row 40 -->
|
||||
<tr>
|
||||
<td class="row-label">+ Kaltgas:</td>
|
||||
<td>Gefäss 2,5:</td>
|
||||
<td class="readonly-cell">{{ bottom2.g40|default_if_none:""|floatformat:2 }}</td>
|
||||
<td>Gefäss 1,0:</td>
|
||||
<td class="readonly-cell">{{ bottom2.i40|default_if_none:""|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom2.j40|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom2.k40|floatformat:2 }}</td>
|
||||
</tr>
|
||||
|
||||
<!-- Row 43 -->
|
||||
<tr>
|
||||
<td class="row-label" colspan="5">Bestand flüssig He</td>
|
||||
<td class="readonly-cell">{{ bottom2.j43|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom2.k43|floatformat:2 }}</td>
|
||||
</tr>
|
||||
|
||||
<!-- Row 44 -->
|
||||
<tr>
|
||||
<td class="row-label" colspan="5">Gesamtbestand neu:</td>
|
||||
<td class="readonly-cell">{{ bottom2.j44|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom2.k44|floatformat:2 }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="table-container bottom-table-3" style="margin-top: 20px;">
|
||||
<h3>Bottom Table 3 – Bilanz (read-only)</h3>
|
||||
|
||||
<table class="sheet-table spreadsheet-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Bezeichnung</th>
|
||||
<th>F</th>
|
||||
<th>G</th>
|
||||
<th>I</th>
|
||||
<th>Nm³ (J)</th>
|
||||
<th>Lit. L-He (K)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- Row 46 -->
|
||||
<tr>
|
||||
<td class="row-label">Gesamtbestand Vormonat</td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell">{{ bottom3.j46|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom3.k46|floatformat:2 }}</td>
|
||||
</tr>
|
||||
|
||||
<!-- Row 47 -->
|
||||
<tr>
|
||||
<td class="row-label">+ Verbrauch / Anlage</td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell">{{ bottom3.g47|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom3.i47|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom3.j47|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom3.k47|floatformat:2 }}</td>
|
||||
</tr>
|
||||
|
||||
<!-- Row 48 -->
|
||||
<tr>
|
||||
<td class="row-label">Gesamtbestand inkl. Anlage</td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell">{{ bottom3.j48|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom3.k48|floatformat:2 }}</td>
|
||||
</tr>
|
||||
|
||||
<!-- Row 49 -->
|
||||
<tr>
|
||||
<td class="row-label">Gesamtbestand (akt. Monat)</td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell">{{ bottom3.j49|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom3.k49|floatformat:2 }}</td>
|
||||
</tr>
|
||||
|
||||
<!-- Row 50 -->
|
||||
<tr>
|
||||
<td class="row-label">Verbrauch Sonstiges</td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell">{{ bottom3.g50|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom3.i50|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom3.j50|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom3.k50|floatformat:2 }}</td>
|
||||
</tr>
|
||||
|
||||
<!-- Row 51 -->
|
||||
<tr>
|
||||
<td class="row-label">Differenz Bestand</td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell">{{ bottom3.j51|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom3.k51|floatformat:2 }}</td>
|
||||
</tr>
|
||||
|
||||
<!-- Row 52 -->
|
||||
<tr>
|
||||
<td class="row-label">Verbraucherverluste (aus Übersicht)</td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell">{{ bottom3.j52|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom3.k52|floatformat:2 }}</td>
|
||||
</tr>
|
||||
|
||||
<!-- Row 53 -->
|
||||
<tr>
|
||||
<td class="row-label">Differenz Bilanz</td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell"></td>
|
||||
<td class="readonly-cell">{{ bottom3.j53|floatformat:2 }}</td>
|
||||
<td class="readonly-cell">{{ bottom3.k53|floatformat:2 }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -391,13 +391,13 @@
|
||||
<td>{{ entry.client.name }}</td>
|
||||
<td>{{ entry.pressure|floatformat:2 }}</td>
|
||||
<td>{{ entry.purity|floatformat:2 }}</td>
|
||||
<td>{{ entry.druckkorrektur|floatformat:3 }}</td>
|
||||
<td>{{ entry.constant_300|floatformat:3 }}</td>
|
||||
<td>{{ entry.korrig_druck|floatformat:6 }}</td>
|
||||
<td>{{ entry.nm3|floatformat:6 }}</td>
|
||||
<td>{{ entry.lhe|floatformat:6 }}</td>
|
||||
<td>{{ entry.lhe_zus|floatformat:3 }}</td>
|
||||
<td>{{ entry.lhe_ges|floatformat:6 }}</td>
|
||||
<td>{{ entry.druckkorrektur|floatformat:2 }}</td>
|
||||
<td>{{ entry.constant_300|floatformat:2 }}</td>
|
||||
<td>{{ entry.korrig_druck|floatformat:2 }}</td>
|
||||
<td>{{ entry.nm3|floatformat:2 }}</td>
|
||||
<td>{{ entry.lhe|floatformat:2 }}</td>
|
||||
<td>{{ entry.lhe_zus|floatformat:2 }}</td>
|
||||
<td>{{ entry.lhe_ges|floatformat:2 }}</td>
|
||||
<td>
|
||||
{% if entry.date %}
|
||||
{{ entry.date|date:"d.m.Y" }}
|
||||
@@ -468,8 +468,9 @@
|
||||
<!-- Auto-calculated Fields with Formulas -->
|
||||
<div class="input-with-label">
|
||||
<label for="add-constant-300">ges. Flasch. Inhalt:</label>
|
||||
<input type="number" id="add-constant-300" value="300.000" step="0.001" readonly class="readonly-field">
|
||||
<input type="number" id="add-constant-300" step="0.001" min="0">
|
||||
</div>
|
||||
<div class="formula-display">Editable value</div>
|
||||
<div class="formula-display">Formula: Fixed value (300)</div>
|
||||
|
||||
<div class="input-with-label">
|
||||
@@ -554,7 +555,7 @@
|
||||
<!-- Auto-calculated Fields with Formulas -->
|
||||
<div class="input-with-label">
|
||||
<label for="edit-constant-300">ges. Flasch. Inhalt:</label>
|
||||
<input type="number" id="edit-constant-300" value="300.000" step="0.001" readonly class="readonly-field">
|
||||
<input type="number" id="edit-constant-300" step="0.001" min="0">
|
||||
</div>
|
||||
<div class="formula-display">Formula: Fixed value (300)</div>
|
||||
|
||||
@@ -640,19 +641,19 @@
|
||||
|
||||
// Calculate Korrig. Druck
|
||||
const korrigDruck = pressure * druckkorrektur / ((pressure * druckkorrektur) / 2000 + 1);
|
||||
$(`#${prefix}-korrig-druck`).val(korrigDruck.toFixed(6));
|
||||
|
||||
// Calculate Nm³ - Updated to divide by 1000
|
||||
$(`#${prefix}-korrig-druck`).val(korrigDruck.toFixed(2));
|
||||
|
||||
// Calculate Nm³
|
||||
const nm3 = (gesFlaschInhalt * korrigDruck) / 1000;
|
||||
$(`#${prefix}-nm3`).val(nm3.toFixed(6));
|
||||
|
||||
$(`#${prefix}-nm3`).val(nm3.toFixed(2));
|
||||
|
||||
// Calculate L-He
|
||||
const lhe = nm3 * (1 - purity/100) / 0.75;
|
||||
$(`#${prefix}-lhe`).val(lhe.toFixed(6));
|
||||
|
||||
$(`#${prefix}-lhe`).val(lhe.toFixed(2));
|
||||
|
||||
// Calculate L-He ges.
|
||||
const lheGes = lheZus + lhe;
|
||||
$(`#${prefix}-lhe-ges`).val(lheGes.toFixed(6));
|
||||
$(`#${prefix}-lhe-ges`).val(lheGes.toFixed(2));
|
||||
}
|
||||
|
||||
// Institute change handler for add popup
|
||||
@@ -668,12 +669,13 @@
|
||||
});
|
||||
|
||||
// Add event listeners for calculation triggers in add popup
|
||||
$('#add-pressure, #add-purity, #add-druckkorrektur, #add-lhe-zus').on('input change', function() {
|
||||
$('#add-pressure, #add-purity, #add-druckkorrektur, #add-lhe-zus, #add-constant-300')
|
||||
.on('input change', function() {
|
||||
calculateDerivedValues('add');
|
||||
});
|
||||
|
||||
// Add event listeners for calculation triggers in edit popup
|
||||
$('#edit-pressure, #edit-purity, #edit-druckkorrektur, #edit-lhe-zus').on('input change', function() {
|
||||
$('#edit-pressure, #edit-purity, #edit-druckkorrektur, #edit-lhe-zus, #edit-constant-300')
|
||||
.on('input change', function() {
|
||||
calculateDerivedValues('edit');
|
||||
});
|
||||
|
||||
@@ -684,10 +686,10 @@
|
||||
$('#add-client-id').prop('disabled', true);
|
||||
$('#add-date').val('');
|
||||
$('#add-pressure').val('');
|
||||
$('#add-purity').val('');
|
||||
$('#add-purity').val('0.1');
|
||||
$('#add-druckkorrektur').val('1.0');
|
||||
$('#add-lhe-zus').val('0.0');
|
||||
$('#add-constant-300').val('300.000');
|
||||
$('#add-constant-300').val('604.00');
|
||||
$('#add-korrig-druck').val('');
|
||||
$('#add-nm3').val('');
|
||||
$('#add-lhe').val('');
|
||||
|
||||
@@ -208,6 +208,8 @@
|
||||
<th>Date</th>
|
||||
<th>Warm</th>
|
||||
<th>LHe Delivery</th>
|
||||
<th>Vor</th>
|
||||
<th>Nach</th>
|
||||
<th>LHe Output</th>
|
||||
<th>Notes</th>
|
||||
<th>Actions</th>
|
||||
@@ -223,7 +225,9 @@
|
||||
<td>{{ entry.date }}</td>
|
||||
<td>{{ entry.is_warm|yesno:"Yes,No" }}</td>
|
||||
<td>{{ entry.lhe_delivery }}</td>
|
||||
<td>{{ entry.lhe_output }}</td>
|
||||
<td>{% if entry.vor is not None %}{{ entry.vor|floatformat:1 }}{% endif %}</td>
|
||||
<td>{% if entry.nach is not None %}{{ entry.nach|floatformat:1 }}{% endif %}</td>
|
||||
<td>{% if entry.lhe_output is not None %}{{ entry.lhe_output|floatformat:1 }}{% endif %}</td>
|
||||
<td>{{ entry.notes }}</td>
|
||||
<td class="actions">
|
||||
<button class="edit-btn-two">Edit</button>
|
||||
@@ -272,9 +276,19 @@
|
||||
<input type="text" id="add-lhe-delivery" placeholder="Enter delivery amount">
|
||||
</div>
|
||||
|
||||
<div class="input-with-label">
|
||||
<label for="add-vor">Vor:</label>
|
||||
<input type="number" id="add-vor" step="0.1">
|
||||
</div>
|
||||
|
||||
<div class="input-with-label">
|
||||
<label for="add-nach">Nach:</label>
|
||||
<input type="number" id="add-nach" step="0.1">
|
||||
</div>
|
||||
|
||||
<div class="input-with-label">
|
||||
<label for="add-lhe-output">LHe Ausgabe:</label>
|
||||
<input type="number" id="add-lhe-output" placeholder="Enter output amount (numbers only)" step="0.01" min="0">
|
||||
<input type="number" id="add-lhe-output" readonly>
|
||||
</div>
|
||||
|
||||
<label for="add-notes">Notes:</label>
|
||||
@@ -326,9 +340,20 @@
|
||||
</div>
|
||||
|
||||
<div class="input-with-label">
|
||||
<label for="edit-lhe-output">LHe Ausgabe:</label>
|
||||
<input type="number" id="edit-lhe-output" placeholder="Enter output amount">
|
||||
<label for="edit-vor">Vor:</label>
|
||||
<input type="number" id="edit-vor" step="0.1">
|
||||
</div>
|
||||
|
||||
<div class="input-with-label">
|
||||
<label for="edit-nach">Nach:</label>
|
||||
<input type="number" id="edit-nach" step="0.1">
|
||||
</div>
|
||||
|
||||
<div class="input-with-label">
|
||||
<label for="edit-lhe-output">LHe Ausgabe:</label>
|
||||
<input type="number" id="edit-lhe-output" readonly>
|
||||
</div>
|
||||
|
||||
|
||||
<label for="edit-notes">Notes:</label>
|
||||
<textarea id="edit-notes" placeholder="Additional notes"></textarea>
|
||||
@@ -346,7 +371,30 @@
|
||||
// Store all client options for both dropdowns
|
||||
const allClientOptions = $('#add-client-id').html();
|
||||
const allEditClientOptions = $('#edit-client-id').html();
|
||||
function calculateAddOutput() {
|
||||
let vor = parseFloat($('#add-vor').val()) || 0;
|
||||
let nach = parseFloat($('#add-nach').val()) || 0;
|
||||
|
||||
let output = nach - vor;
|
||||
|
||||
if (output < 0) output = 0;
|
||||
|
||||
$('#add-lhe-output').val(output.toFixed(1));
|
||||
}
|
||||
|
||||
$('#add-vor, #add-nach').on('input', calculateAddOutput);
|
||||
function calculateEditOutput() {
|
||||
let vor = parseFloat($('#edit-vor').val()) || 0;
|
||||
let nach = parseFloat($('#edit-nach').val()) || 0;
|
||||
|
||||
let output = nach - vor;
|
||||
|
||||
if (output < 0) output = 0;
|
||||
|
||||
$('#edit-lhe-output').val(output.toFixed(1));
|
||||
}
|
||||
|
||||
$('#edit-vor, #edit-nach').on('input', calculateEditOutput);
|
||||
// Function to filter clients based on institute selection
|
||||
function filterClients(instituteId, targetSelect, allOptions) {
|
||||
if (!instituteId) {
|
||||
@@ -469,15 +517,21 @@
|
||||
}
|
||||
|
||||
let formData = {
|
||||
'client_id': clientId,
|
||||
'date': $('#add-date').val(),
|
||||
'is_warm': warmValue,
|
||||
'lhe_delivery': $('#add-lhe-delivery').val(),
|
||||
'lhe_output': $('#add-lhe-output').val(),
|
||||
'notes': $('#add-notes').val(),
|
||||
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
||||
};
|
||||
'client_id': clientId,
|
||||
'date': $('#add-date').val(),
|
||||
'is_warm': warmValue,
|
||||
'lhe_delivery': $('#add-lhe-delivery').val(),
|
||||
|
||||
// ✅ NEW: send vor/nach to backend
|
||||
'vor': $('#add-vor').val(),
|
||||
'nach': $('#add-nach').val(),
|
||||
|
||||
// ❌ DO NOT send lhe_output anymore (backend should compute it)
|
||||
// 'lhe_output': $('#add-lhe-output').val(),
|
||||
|
||||
'notes': $('#add-notes').val(),
|
||||
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
||||
};
|
||||
// Validate date format
|
||||
if (!formData.date) {
|
||||
alert('Please select a date');
|
||||
@@ -485,9 +539,16 @@
|
||||
}
|
||||
|
||||
// Validate LHe Output is a number
|
||||
if (formData.lhe_output && isNaN(parseFloat(formData.lhe_output))) {
|
||||
alert('LHe Output must be a valid number');
|
||||
return;
|
||||
const vorVal = $('#add-vor').val();
|
||||
const nachVal = $('#add-nach').val();
|
||||
|
||||
if (vorVal !== "" && isNaN(parseFloat(vorVal))) {
|
||||
alert('Vor must be a valid number');
|
||||
return;
|
||||
}
|
||||
if (nachVal !== "" && isNaN(parseFloat(nachVal))) {
|
||||
alert('Nach must be a valid number');
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
@@ -498,22 +559,25 @@
|
||||
if (response.status === 'success') {
|
||||
// Add the new row to the table
|
||||
let newRow = `
|
||||
<tr data-id="${response.id}">
|
||||
<td>${$('#table-two tbody tr').length + 1}</td>
|
||||
<td>${response.id}</td>
|
||||
<td>${response.institute_name || ''}</td>
|
||||
<td>${response.client_name}</td>
|
||||
<td>${response.date || ''}</td>
|
||||
<td>${response.is_warm ? 'Yes' : 'No'}</td>
|
||||
<td>${response.lhe_delivery}</td>
|
||||
<td>${response.lhe_output || ''}</td>
|
||||
<td>${response.notes || ''}</td>
|
||||
<td class="actions">
|
||||
<button class="edit-btn-two">Edit</button>
|
||||
<button class="delete-btn-two">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr data-id="${response.id}">
|
||||
<td>${$('#table-two tbody tr').length + 1}</td>
|
||||
<td>${response.id}</td>
|
||||
<td>${response.institute_name || ''}</td>
|
||||
<td>${response.client_name}</td>
|
||||
<td>${response.date || ''}</td>
|
||||
<td>${response.is_warm ? 'Yes' : 'No'}</td>
|
||||
<td>${response.lhe_delivery || ''}</td>
|
||||
<td>${response.vor ?? ''}</td>
|
||||
<td>${response.nach ?? ''}</td>
|
||||
<td>${response.lhe_output ?? ''}</td>
|
||||
<td>${response.notes || ''}</td>
|
||||
<td class="actions">
|
||||
<button class="edit-btn-two">Edit</button>
|
||||
<button class="delete-btn-two">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
|
||||
$('#table-two tbody').append(newRow);
|
||||
$('#add-popup-two').fadeOut();
|
||||
} else {
|
||||
@@ -558,15 +622,16 @@
|
||||
|
||||
// Set other fields
|
||||
$('#edit-id').val(entryId);
|
||||
$('#edit-date').val(row.find('td:eq(3)').text().trim());
|
||||
|
||||
// Set warm value (convert from "Yes"/"No" to 1/0)
|
||||
const warmValue = row.find('td:eq(4)').text().trim() === 'Yes' ? 1 : 0;
|
||||
$('#edit-date').val(row.find('td:eq(4)').text().trim());
|
||||
|
||||
const warmValue = row.find('td:eq(5)').text().trim() === 'Yes' ? 1 : 0;
|
||||
$('#edit-is-warm').val(warmValue);
|
||||
|
||||
$('#edit-lhe-delivery').val(row.find('td:eq(5)').text().trim());
|
||||
$('#edit-lhe-output').val(row.find('td:eq(6)').text().trim());
|
||||
$('#edit-notes').val(row.find('td:eq(7)').text().trim());
|
||||
|
||||
$('#edit-lhe-delivery').val(row.find('td:eq(6)').text().trim());
|
||||
$('#edit-vor').val(row.find('td:eq(7)').text().trim());
|
||||
$('#edit-nach').val(row.find('td:eq(8)').text().trim());
|
||||
$('#edit-lhe-output').val(row.find('td:eq(9)').text().trim());
|
||||
$('#edit-notes').val(row.find('td:eq(10)').text().trim());
|
||||
|
||||
// Apply warm field logic
|
||||
handleWarmFieldChange($('#edit-is-warm'), $('#edit-lhe-delivery'));
|
||||
@@ -597,15 +662,22 @@
|
||||
}
|
||||
|
||||
let formData = {
|
||||
'id': $('#edit-id').val(),
|
||||
'client_id': clientId,
|
||||
'date': $('#edit-date').val(),
|
||||
'is_warm': warmValue,
|
||||
'lhe_delivery': $('#edit-lhe-delivery').val(),
|
||||
'lhe_output': $('#edit-lhe-output').val(),
|
||||
'notes': $('#edit-notes').val(),
|
||||
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
||||
};
|
||||
'id': $('#edit-id').val(),
|
||||
'client_id': clientId,
|
||||
'date': $('#edit-date').val(),
|
||||
'is_warm': warmValue,
|
||||
'lhe_delivery': $('#edit-lhe-delivery').val(),
|
||||
|
||||
// ✅ NEW
|
||||
'vor': $('#edit-vor').val(),
|
||||
'nach': $('#edit-nach').val(),
|
||||
|
||||
// ❌ DO NOT send lhe_output anymore
|
||||
// 'lhe_output': $('#edit-lhe-output').val(),
|
||||
|
||||
'notes': $('#edit-notes').val(),
|
||||
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
||||
};
|
||||
|
||||
// Validate inputs
|
||||
if (!formData.date) {
|
||||
@@ -623,13 +695,16 @@
|
||||
data: formData,
|
||||
success: function(response) {
|
||||
if (response.status === 'success') {
|
||||
let row = $(`tr[data-id="${response.id}"]`);
|
||||
row.find('td:eq(2)').text(response.client_name);
|
||||
row.find('td:eq(3)').text(response.date || '');
|
||||
row.find('td:eq(4)').text(response.is_warm ? 'Yes' : 'No');
|
||||
row.find('td:eq(5)').text(response.lhe_delivery);
|
||||
row.find('td:eq(6)').text(response.lhe_output || '');
|
||||
row.find('td:eq(7)').text(response.notes || '');
|
||||
let row = $(`tr[data-id="${response.id}"]`);
|
||||
row.find('td:eq(2)').text(response.institute_name || '');
|
||||
row.find('td:eq(3)').text(response.client_name || '');
|
||||
row.find('td:eq(4)').text(response.date || '');
|
||||
row.find('td:eq(5)').text(response.is_warm ? 'Yes' : 'No');
|
||||
row.find('td:eq(6)').text(response.lhe_delivery || '');
|
||||
row.find('td:eq(7)').text(response.vor ?? '');
|
||||
row.find('td:eq(8)').text(response.nach ?? '');
|
||||
row.find('td:eq(9)').text(response.lhe_output ?? '');
|
||||
row.find('td:eq(10)').text(response.notes || '');
|
||||
$('#edit-popup-two').fadeOut();
|
||||
} else {
|
||||
alert('Update failed: ' + (response.message || 'Unknown error'));
|
||||
|
||||
Reference in New Issue
Block a user