updated
This commit is contained in:
+187
-277
@@ -59,6 +59,12 @@ CLIENT_GROUPS = {
|
||||
'M3 Gutfleisch',
|
||||
],
|
||||
},
|
||||
'merck': {
|
||||
'label': 'Merck',
|
||||
'names': [
|
||||
'Merck',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
# Add this CALCULATION_CONFIG at the top of views.py
|
||||
@@ -275,12 +281,12 @@ def build_halfyear_window(interval_year: int, start_month: int):
|
||||
# Halbjahres-Bilanz helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# You can adjust these indices if needed.
|
||||
|
||||
# Assuming:
|
||||
# - bottom_1.table has row "Gasbestand" at some fixed row index,
|
||||
# and columns: ... Nm³, Lit. LHe
|
||||
GASBESTAND_ROW_INDEX = 9 # <-- adjust if your bottom_1 has a different row index
|
||||
GASBESTAND_COL_NM3 = 3 # <-- adjust to the column index for Nm³ in bottom_1
|
||||
GASBESTAND_ROW_INDEX = 9
|
||||
GASBESTAND_COL_NM3 = 3
|
||||
|
||||
# In top_left / top_right, "Bestand in Kannen-1 (Lit. L-He)" is row_index 5
|
||||
BESTAND_KANNEN_ROW_INDEX = 5
|
||||
@@ -382,6 +388,7 @@ HALFYEAR_RIGHT_CLIENTS = [
|
||||
"M3 Thiele",
|
||||
"M3 Buntkowsky",
|
||||
"M3 Gutfleisch",
|
||||
"Merck",
|
||||
]
|
||||
BOTTOM1_COL_VOLUME = 0
|
||||
BOTTOM1_COL_BAR = 1
|
||||
@@ -461,6 +468,7 @@ def get_group_clients(group_key):
|
||||
group = CLIENT_GROUPS.get(group_key)
|
||||
if not group:
|
||||
return Client.objects.none()
|
||||
|
||||
return Client.objects.filter(name__in=group['names'])
|
||||
|
||||
def calculate_summation(sheet, table_type, row_index, sum_column_index):
|
||||
@@ -575,6 +583,7 @@ class MonthlySheetView(TemplateView):
|
||||
"M3 Thiele", # Column index 4 (P)
|
||||
"M3 Buntkowsky", # Column index 5 (Q)
|
||||
"M3 Gutfleisch", # Column index 6 (R)
|
||||
"Merck",
|
||||
]
|
||||
|
||||
# For each client in top-right table
|
||||
@@ -735,6 +744,7 @@ class MonthlySheetView(TemplateView):
|
||||
"M3 Thiele",
|
||||
"M3 Buntkowsky",
|
||||
"M3 Gutfleisch",
|
||||
"Merck",
|
||||
]
|
||||
current_summary = MonthlySummary.objects.filter(sheet=sheet).first()
|
||||
|
||||
@@ -765,6 +775,10 @@ class MonthlySheetView(TemplateView):
|
||||
("Dr. Fohrer", "AG Buntk."),
|
||||
("AG Alff", "AG Gutfl."),
|
||||
]
|
||||
|
||||
MERGED_TRIPLES = [
|
||||
("M3 Thiele", "M3 Buntkowsky", "M3 Gutfleisch"),
|
||||
]
|
||||
rows = []
|
||||
|
||||
# Determine row count
|
||||
@@ -813,13 +827,29 @@ class MonthlySheetView(TemplateView):
|
||||
has_value = False
|
||||
|
||||
merged_second_indices = set()
|
||||
|
||||
if table_type == 'top_right' and row_idx in MERGED_ROWS:
|
||||
|
||||
# Handle pairs
|
||||
for left_name, right_name in MERGED_PAIRS:
|
||||
try:
|
||||
right_idx = client_names.index(right_name)
|
||||
merged_second_indices.add(right_idx)
|
||||
except ValueError:
|
||||
# client not in this table; just ignore
|
||||
pass
|
||||
|
||||
# Handle M3 triple group
|
||||
MERGED_TRIPLES = [
|
||||
("M3 Thiele", "M3 Buntkowsky", "M3 Gutfleisch"),
|
||||
]
|
||||
|
||||
for a, b, c in MERGED_TRIPLES:
|
||||
try:
|
||||
b_idx = client_names.index(b)
|
||||
c_idx = client_names.index(c)
|
||||
merged_second_indices.add(b_idx)
|
||||
merged_second_indices.add(c_idx)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
for col_idx, cell in enumerate(display_cells):
|
||||
@@ -1250,100 +1280,8 @@ def get_factor_value(table_type, row_index):
|
||||
# Save Cells View
|
||||
# views.py - Updated SaveCellsView
|
||||
# views.py - Update SaveCellsView class
|
||||
def debug_cell_values(self, sheet, client_id):
|
||||
"""Debug method to check cell values"""
|
||||
from .models import Cell
|
||||
cells = Cell.objects.filter(
|
||||
sheet=sheet,
|
||||
table_type='top_left',
|
||||
client_id=client_id
|
||||
).order_by('row_index')
|
||||
|
||||
debug_info = {}
|
||||
for cell in cells:
|
||||
debug_info[f"row_{cell.row_index}"] = {
|
||||
'value': str(cell.value) if cell.value else 'None',
|
||||
'ui_row': cell.row_index + 1,
|
||||
'excel_ref': f"B{cell.row_index + 3}"
|
||||
}
|
||||
|
||||
return debug_info
|
||||
class DebugCalculationView(View):
|
||||
"""Debug view to test calculations directly"""
|
||||
def get(self, request):
|
||||
sheet_id = request.GET.get('sheet_id', 1)
|
||||
client_name = request.GET.get('client', 'AG Vogel')
|
||||
|
||||
try:
|
||||
sheet = MonthlySheet.objects.get(id=sheet_id)
|
||||
client = Client.objects.get(name=client_name)
|
||||
|
||||
# Get SaveCellsView instance
|
||||
save_view = SaveCellsView()
|
||||
|
||||
# Create a dummy cell to trigger calculations
|
||||
dummy_cell = Cell.objects.filter(
|
||||
sheet=sheet,
|
||||
table_type='top_left',
|
||||
client=client,
|
||||
row_index=0 # B3
|
||||
).first()
|
||||
|
||||
if not dummy_cell:
|
||||
return JsonResponse({'error': 'No cells found for this client'})
|
||||
|
||||
# Trigger calculation
|
||||
updated = save_view.calculate_top_left_dependents(sheet, dummy_cell)
|
||||
|
||||
# Get updated cell values
|
||||
cells = Cell.objects.filter(
|
||||
sheet=sheet,
|
||||
table_type='top_left',
|
||||
client=client
|
||||
).order_by('row_index')
|
||||
|
||||
cell_data = []
|
||||
for cell in cells:
|
||||
cell_data.append({
|
||||
'row_index': cell.row_index,
|
||||
'ui_row': cell.row_index + 1,
|
||||
'excel_ref': f"B{cell.row_index + 3}",
|
||||
'value': str(cell.value) if cell.value else 'None',
|
||||
'description': self.get_row_description(cell.row_index)
|
||||
})
|
||||
|
||||
return JsonResponse({
|
||||
'sheet': f"{sheet.year}-{sheet.month:02d}",
|
||||
'client': client.name,
|
||||
'cells': cell_data,
|
||||
'updated_count': len(updated),
|
||||
'calculation': 'B5 = IF(B3>0; B3-B4; 0)'
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
return JsonResponse({'error': str(e)}, status=400)
|
||||
|
||||
def get_row_description(self, row_index):
|
||||
"""Get description for row index"""
|
||||
descriptions = {
|
||||
0: "B3: Stand der Gaszähler (Nm³)",
|
||||
1: "B4: Stand der Gaszähler (Vormonat) (Nm³)",
|
||||
2: "B5: Gasrückführung (Nm³)",
|
||||
3: "B6: Rückführung flüssig (Lit. L-He)",
|
||||
4: "B7: Sonderrückführungen (Lit. L-He)",
|
||||
5: "B8: Bestand in Kannen-1 (Lit. L-He)",
|
||||
6: "B9: Summe Bestand (Lit. L-He)",
|
||||
7: "B10: Best. in Kannen Vormonat (Lit. L-He)",
|
||||
8: "B11: Bezug (Liter L-He)",
|
||||
9: "B12: Rückführ. Soll (Lit. L-He)",
|
||||
10: "B13: Verluste (Soll-Rückf.) (Lit. L-He)",
|
||||
11: "B14: Füllungen warm (Lit. L-He)",
|
||||
12: "B15: Kaltgas Rückgabe (Lit. L-He) – Faktor",
|
||||
13: "B16: Faktor",
|
||||
14: "B17: Verbraucherverluste (Liter L-He)",
|
||||
15: "B18: %"
|
||||
}
|
||||
return descriptions.get(row_index, f"Row {row_index}")
|
||||
|
||||
|
||||
def recalculate_stand_der_gaszahler(self, sheet):
|
||||
"""Recalculate Stand der Gaszähler for all client pairs"""
|
||||
from decimal import Decimal
|
||||
@@ -1443,82 +1381,7 @@ def recalculate_stand_der_gaszahler(self, sheet):
|
||||
ag_gutfl_row0.save()
|
||||
except Exception as e:
|
||||
print(f"Error recalculating Stand der Gaszähler for AG Alff/AG Gutfl.: {e}")
|
||||
# In your SaveCellsView class in views.py
|
||||
class DebugTopRightView(View):
|
||||
"""Debug view to check top_right calculations"""
|
||||
def get(self, request):
|
||||
sheet_id = request.GET.get('sheet_id', 1)
|
||||
client_name = request.GET.get('client', 'Dr. Fohrer')
|
||||
|
||||
try:
|
||||
sheet = MonthlySheet.objects.get(id=sheet_id)
|
||||
client = Client.objects.get(name=client_name)
|
||||
|
||||
# Get all cells for this client in top_right
|
||||
cells = Cell.objects.filter(
|
||||
sheet=sheet,
|
||||
table_type='top_right',
|
||||
client=client
|
||||
).order_by('row_index')
|
||||
|
||||
cell_data = []
|
||||
descriptions = {
|
||||
0: "Stand der Gaszähler (Vormonat)",
|
||||
1: "Gasrückführung (Nm³)",
|
||||
2: "Rückführung flüssig",
|
||||
3: "Sonderrückführungen",
|
||||
4: "Sammelrückführungen",
|
||||
5: "Bestand in Kannen-1",
|
||||
6: "Summe Bestand",
|
||||
7: "Best. in Kannen Vormonat",
|
||||
8: "Same as row 9 from prev sheet",
|
||||
9: "Bezug",
|
||||
10: "Rückführ. Soll",
|
||||
11: "Verluste",
|
||||
12: "Füllungen warm",
|
||||
13: "Kaltgas Rückgabe",
|
||||
14: "Faktor 0.06",
|
||||
15: "Verbraucherverluste",
|
||||
16: "%"
|
||||
}
|
||||
|
||||
for cell in cells:
|
||||
cell_data.append({
|
||||
'row_index': cell.row_index,
|
||||
'ui_row': cell.row_index + 1,
|
||||
'description': descriptions.get(cell.row_index, f"Row {cell.row_index}"),
|
||||
'value': str(cell.value) if cell.value else 'Empty',
|
||||
'cell_id': cell.id
|
||||
})
|
||||
|
||||
# Test calculation
|
||||
row3_cell = cells.filter(row_index=3).first()
|
||||
row5_cell = cells.filter(row_index=5).first()
|
||||
row6_cell = cells.filter(row_index=6).first()
|
||||
|
||||
calculation_info = {
|
||||
'row3_value': str(row3_cell.value) if row3_cell and row3_cell.value else '0',
|
||||
'row5_value': str(row5_cell.value) if row5_cell and row5_cell.value else '0',
|
||||
'row6_value': str(row6_cell.value) if row6_cell and row6_cell.value else '0',
|
||||
'expected_sum': '0'
|
||||
}
|
||||
|
||||
if row3_cell and row5_cell and row6_cell:
|
||||
row3_val = Decimal(str(row3_cell.value)) if row3_cell.value else Decimal('0')
|
||||
row5_val = Decimal(str(row5_cell.value)) if row5_cell.value else Decimal('0')
|
||||
expected = row3_val + row5_val
|
||||
calculation_info['expected_sum'] = str(expected)
|
||||
calculation_info['is_correct'] = row6_cell.value == expected
|
||||
|
||||
return JsonResponse({
|
||||
'sheet': f"{sheet.year}-{sheet.month}",
|
||||
'client': client.name,
|
||||
'cells': cell_data,
|
||||
'calculation': calculation_info
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
return JsonResponse({'error': str(e)}, status=400)
|
||||
|
||||
ABRECHNUNG_COL_CLIENTS = {
|
||||
# first 3 columns
|
||||
"pkm_vogel": ["AG Vogel"],
|
||||
@@ -1582,7 +1445,12 @@ class AbrechnungView(TemplateView):
|
||||
("rechnungsbetrag", "Rechnungsbetrag", "EUR"),
|
||||
("eff_lhe_preis", "eff. L-He-Preis", "EUR/L"),
|
||||
]
|
||||
|
||||
SUMMARY_ROWS = {
|
||||
"bezogen_menge",
|
||||
"kaltg_warmfuell",
|
||||
"he_verbrauch",
|
||||
"lhe_verluste",
|
||||
}
|
||||
|
||||
# Editable rows = your yellow rows
|
||||
EDITABLE_ROW_KEYS = {"ghe_bezug", "betrag", "gutschriften"}
|
||||
@@ -1706,9 +1574,12 @@ class AbrechnungView(TemplateView):
|
||||
def sum_all_cols(values_dict):
|
||||
return sum(v for k, v in values_dict.items() if k != "gesamt_summe")
|
||||
|
||||
bezogen["gesamt_summe"] = sum_all_cols(bezogen)
|
||||
warmfills["gesamt_summe"] = sum_all_cols(warmfills)
|
||||
|
||||
bezogen["gesamt_summe"] = (
|
||||
d(bezogen.get("chemie")) + d(bezogen.get("mawi")) + d(bezogen.get("physik"))
|
||||
)
|
||||
warmfills["gesamt_summe"] = (
|
||||
d(warmfills.get("chemie")) + d(warmfills.get("mawi")) + d(warmfills.get("physik"))
|
||||
)
|
||||
# ---- Row: Bezogen. Menge ----
|
||||
for col_key in bezogen:
|
||||
computed[("bezogen_menge", col_key)] = bezogen[col_key]
|
||||
@@ -1765,12 +1636,30 @@ class AbrechnungView(TemplateView):
|
||||
for col_key in he_verbrauch:
|
||||
if col_key in first3:
|
||||
row1_vals[col_key] = instandhaltung * safe_div(he_verbrauch[col_key], physik_hv) / Decimal("3")
|
||||
|
||||
elif col_key in next3:
|
||||
row1_vals[col_key] = instandhaltung / Decimal("9")
|
||||
|
||||
elif col_key in next2:
|
||||
row1_vals[col_key] = instandhaltung / Decimal("6")
|
||||
|
||||
# ✅ NEW: summary columns
|
||||
elif col_key in ("chemie", "mawi"):
|
||||
row1_vals[col_key] = instandhaltung / Decimal("3")
|
||||
|
||||
elif col_key == "physik":
|
||||
row1_vals[col_key] = (
|
||||
d(row1_vals.get("pkm_vogel")) +
|
||||
d(row1_vals.get("iap_halfmann")) +
|
||||
d(row1_vals.get("ikp"))
|
||||
)
|
||||
|
||||
elif col_key == "gesamt_summe":
|
||||
row1_vals[col_key] = sum(row1_vals.get(k, Decimal("0")) for k in first3)
|
||||
# keep whatever you want here; example: chemie+mawi+physik
|
||||
row1_vals[col_key] = (
|
||||
d(row1_vals.get("chemie")) + d(row1_vals.get("mawi")) + d(row1_vals.get("physik"))
|
||||
)
|
||||
|
||||
else:
|
||||
row1_vals[col_key] = Decimal("0")
|
||||
|
||||
@@ -1820,23 +1709,21 @@ class AbrechnungView(TemplateView):
|
||||
elif col_key == "chemie":
|
||||
v = (
|
||||
d(verbrauch_right.get("Dr. Fohrer")) +
|
||||
d(verbrauch_right.get("AG Buntk.")) +
|
||||
d(verbrauch_right.get("M3 Buntkowsky")) +
|
||||
d(verbrauch_right.get("M3 Thiele"))
|
||||
d(verbrauch_right.get("AG Buntk."))
|
||||
)
|
||||
|
||||
elif col_key == "mawi":
|
||||
# MaWi = MaWi Gutfl + MaWi Alff (Abrechnung columns)
|
||||
v = (
|
||||
d(verbrauch_right.get("AG Alff")) +
|
||||
d(verbrauch_right.get("AG Gutfl.")) +
|
||||
d(verbrauch_right.get("M3 Gutfleisch"))
|
||||
d(lhe_verluste.get("AG Gutfl")) +
|
||||
d(lhe_verluste.get("mawi_alff"))
|
||||
)
|
||||
|
||||
elif col_key == "physik":
|
||||
v = (
|
||||
d(verbrauch_left.get("AG Vogel")) +
|
||||
d(verbrauch_left.get("AG Halfm")) +
|
||||
d(verbrauch_left.get("IKP"))
|
||||
v = (
|
||||
d(verbrauch_right.get("M3 Thiele")) +
|
||||
d(verbrauch_right.get("M3 Buntkowsky")) +
|
||||
d(verbrauch_right.get("M3 Gutfleisch"))
|
||||
)
|
||||
|
||||
elif col_key == "gesamt_summe":
|
||||
@@ -1851,14 +1738,41 @@ class AbrechnungView(TemplateView):
|
||||
|
||||
|
||||
# --- Gesamt-summe ---
|
||||
lhe_verluste["gesamt_summe"] = sum(v for k, v in lhe_verluste.items())
|
||||
lhe_verluste["gesamt_summe"] = (
|
||||
d(lhe_verluste.get("chemie")) + d(lhe_verluste.get("mawi")) + d(lhe_verluste.get("physik"))
|
||||
)
|
||||
computed[("lhe_verluste", "gesamt_summe")] = lhe_verluste["gesamt_summe"]
|
||||
|
||||
|
||||
# ---- Row: 3 Umlage Heliumkosten = heliumkosten * (LHe-Verluste col / LHe-Verluste gesamt_summe) ----
|
||||
for col_key in lhe_verluste:
|
||||
computed[("umlage_heliumkosten_3", col_key)] = heliumkosten * safe_div(lhe_verluste[col_key], lhe_verluste["gesamt_summe"])
|
||||
FIRST8 = [
|
||||
"pkm_vogel",
|
||||
"iap_halfmann",
|
||||
"ikp",
|
||||
"orgchem_thiele",
|
||||
"phychem_m3_buntkow",
|
||||
"orgchem_fohrer",
|
||||
"mawi_m3_gutfl",
|
||||
"mawi_alff",
|
||||
]
|
||||
|
||||
den = sum(d(lhe_verluste.get(k)) for k in FIRST8) # denominator = sum of first 8 LHe–Verluste
|
||||
|
||||
# 1) compute first 8 columns
|
||||
for k in FIRST8:
|
||||
computed[("umlage_heliumkosten_3", k)] = heliumkosten * safe_div(d(lhe_verluste.get(k)), den)
|
||||
|
||||
# 2) compute the 3 summary columns from those first 8 (so they stay consistent)
|
||||
# 2) compute the 3 summary columns directly from their LHe–Verluste shares (Excel logic)
|
||||
computed[("umlage_heliumkosten_3", "chemie")] = heliumkosten * safe_div(d(lhe_verluste.get("chemie")), den)
|
||||
computed[("umlage_heliumkosten_3", "mawi")] = heliumkosten * safe_div(d(lhe_verluste.get("mawi")), den)
|
||||
computed[("umlage_heliumkosten_3", "physik")] = heliumkosten * safe_div(d(lhe_verluste.get("physik")), den)
|
||||
|
||||
|
||||
# 3) last column = sum of first 8 columns (your requirement)
|
||||
computed[("umlage_heliumkosten_3", "gesamt_summe")] = sum(
|
||||
d(computed.get(("umlage_heliumkosten_3", k))) for k in FIRST8
|
||||
)
|
||||
# ---- Row: 4-Kosten He-Gas-Bezug = Umlage Heliumkosten * Bezugskosten-GasHe ----
|
||||
for col_key, _label in self.COLUMNS:
|
||||
ghe = d(value_map.get(("ghe_bezug", col_key)))
|
||||
@@ -1901,7 +1815,17 @@ class AbrechnungView(TemplateView):
|
||||
elif col_key in ("chemie", "mawi", "physik"):
|
||||
v = safe_div(he_verbrauch[col_key], sum3) * umlage_personal_total
|
||||
elif col_key == "gesamt_summe":
|
||||
v = sum(d(computed.get(("umlage_personal_5", k))) for k in he_verbrauch if k != "gesamt_summe")
|
||||
# sum of the FIRST 8 columns only (exclude chemie/mawi/physik/gesamt_summe)
|
||||
v = (
|
||||
d(computed.get(("umlage_personal_5", "pkm_vogel"))) +
|
||||
d(computed.get(("umlage_personal_5", "iap_halfmann"))) +
|
||||
d(computed.get(("umlage_personal_5", "ikp"))) +
|
||||
d(computed.get(("umlage_personal_5", "orgchem_thiele"))) +
|
||||
d(computed.get(("umlage_personal_5", "phychem_m3_buntkow"))) +
|
||||
d(computed.get(("umlage_personal_5", "orgchem_fohrer"))) +
|
||||
d(computed.get(("umlage_personal_5", "mawi_m3_gutfl"))) +
|
||||
d(computed.get(("umlage_personal_5", "mawi_alff")))
|
||||
)
|
||||
else:
|
||||
v = Decimal("0")
|
||||
computed[("umlage_personal_5", col_key)] = v
|
||||
@@ -1932,6 +1856,19 @@ class AbrechnungView(TemplateView):
|
||||
else:
|
||||
sonstiges_text[col_key] = "Nachzahlung"
|
||||
# overwrite display values for non-editable computed rows
|
||||
FIRST4 = {"bezogen_menge", "kaltg_warmfuell", "anzahl_15", "he_verbrauch"}
|
||||
FIRST8 = ["pkm_vogel", "iap_halfmann", "ikp", "orgchem_thiele",
|
||||
"phychem_m3_buntkow", "orgchem_fohrer", "mawi_m3_gutfl", "mawi_alff"]
|
||||
|
||||
for rk, _label, _unit in self.ROWS:
|
||||
if rk in FIRST4:
|
||||
computed[(rk, "gesamt_summe")] = (
|
||||
d(computed.get((rk, "chemie"))) +
|
||||
d(computed.get((rk, "mawi"))) +
|
||||
d(computed.get((rk, "physik")))
|
||||
)
|
||||
else:
|
||||
computed[(rk, "gesamt_summe")] = sum(d(computed.get((rk, ck))) for ck in FIRST8)
|
||||
non_editable_formula_rows = {
|
||||
"bezogen_menge",
|
||||
"kaltg_warmfuell",
|
||||
@@ -1981,19 +1918,31 @@ class AbrechnungView(TemplateView):
|
||||
# -------------------------------
|
||||
|
||||
GROUP_IJKL = ["orgchem_thiele", "phychem_m3_buntkow", "orgchem_fohrer", "mawi_m3_gutfl", "mawi_alff"]
|
||||
GROUP_NOP = GROUP_IJKL + ["chemie", "mawi", "physik"]
|
||||
GROUP_NOP = ["chemie", "mawi", "physik"]
|
||||
GROUP_STADT = ["pkm_vogel", "iap_halfmann", "ikp"]
|
||||
def nop_cols_for_row(row_key: str):
|
||||
# For gutschriften, NOP should sum the 5 IJKL client columns
|
||||
if row_key == "gutschriften":
|
||||
return GROUP_IJKL
|
||||
# otherwise NOP is the 3 summary columns (Chemie/MaWi/Physik)
|
||||
return GROUP_NOP
|
||||
|
||||
def val(row_key, col_key):
|
||||
"""Get the final numeric value for a cell (computed if available, else stored)."""
|
||||
v = value_map.get((row_key, col_key))
|
||||
return d(v)
|
||||
"""Get the final numeric value for a cell (prefer computed, fallback to stored)."""
|
||||
if (row_key, col_key) in computed:
|
||||
return d(computed.get((row_key, col_key)))
|
||||
return d(value_map.get((row_key, col_key)))
|
||||
|
||||
def sum_group(row_key, cols):
|
||||
return sum(val(row_key, ck) for ck in cols)
|
||||
|
||||
right_rows = []
|
||||
|
||||
def nop_cols_for_row(row_key: str):
|
||||
# For gutschriften, NOP should sum the 5 IJKL client columns
|
||||
if row_key == "gutschriften":
|
||||
return GROUP_IJKL
|
||||
# otherwise NOP is the 3 summary columns
|
||||
return GROUP_NOP
|
||||
# These are your normal rows (same order as UI)
|
||||
# We will create one summary row per Abrechnung row_key.
|
||||
for row_key, label, unit in self.ROWS:
|
||||
@@ -2011,14 +1960,27 @@ class AbrechnungView(TemplateView):
|
||||
continue
|
||||
|
||||
ijkl = sum_group(row_key, GROUP_IJKL)
|
||||
nop = sum_group(row_key, GROUP_NOP)
|
||||
if row_key == "umlage_heliumkosten_3":
|
||||
nop = (
|
||||
val(row_key, "chemie") +
|
||||
val(row_key, "mawi") +
|
||||
val(row_key, "physik")
|
||||
)
|
||||
else:
|
||||
nop = sum_group(row_key, nop_cols_for_row(row_key))
|
||||
stadt = sum_group(row_key, GROUP_STADT)
|
||||
check = nop + stadt
|
||||
|
||||
# Special rule: Rechnungsbetrag row gets +Betrag +Gutschriften (for NOP only)
|
||||
if row_key == "rechnungsbetrag":
|
||||
nop_extra = sum_group("betrag", GROUP_NOP) + sum_group("gutschriften", GROUP_NOP)
|
||||
nop = nop + nop_extra
|
||||
# Rechnungsbetrag (NOP) = (Chemie+MaWi+Physik Rechnungsbetrag)
|
||||
# + (Chemie+MaWi+Physik Betrag)
|
||||
# + (IJKL Gutschriften) <-- because you want gutschriften NOP from IJKL
|
||||
nop = (
|
||||
sum_group("rechnungsbetrag", GROUP_NOP)
|
||||
+ sum_group("betrag", GROUP_NOP)
|
||||
+ sum_group("gutschriften", GROUP_IJKL)
|
||||
)
|
||||
check = nop + stadt
|
||||
|
||||
right_rows.append({
|
||||
@@ -2180,7 +2142,7 @@ class RechnungView(TemplateView):
|
||||
|
||||
bs = BetriebskostenSummary.objects.first()
|
||||
instandhaltung = d(bs.instandhaltung) if bs else Decimal("0")
|
||||
personalkosten = d(bs.personalkosten) if bs else Decimal("0")
|
||||
personalkosten = d(bs.umlage_personal) if bs else Decimal("0")
|
||||
|
||||
preis_eur_pro_l = (instandhaltung / interval_total_output_lhe) if interval_total_output_lhe != 0 else Decimal("0")
|
||||
|
||||
@@ -2537,6 +2499,7 @@ class SaveCellsView(View):
|
||||
"M3 Thiele", # P
|
||||
"M3 Buntkowsky", # Q
|
||||
"M3 Gutfleisch", # R
|
||||
"Merck"
|
||||
]
|
||||
|
||||
# Define merged pairs
|
||||
@@ -2553,6 +2516,7 @@ class SaveCellsView(View):
|
||||
"fohrer_buntk": ["Dr. Fohrer", "AG Buntk."],
|
||||
"alff_gutfl": ["AG Alff", "AG Gutfl."],
|
||||
"m3": ["M3 Thiele", "M3 Buntkowsky", "M3 Gutfleisch"],
|
||||
"merck": ["Merck"],
|
||||
}
|
||||
|
||||
year = sheet.year
|
||||
@@ -2797,6 +2761,26 @@ class SaveCellsView(View):
|
||||
else:
|
||||
prozent = Decimal('0')
|
||||
set_val(m3_client, 15, prozent, is_calculated=True)
|
||||
# 9. Simple client(s): only Bezug, Sammelrückführungen, Verbraucherverluste = Sammel - Bezug
|
||||
SIMPLE_RIGHT_CLIENTS = ["Merck"] # use the exact database name here
|
||||
|
||||
for client_name in SIMPLE_RIGHT_CLIENTS:
|
||||
# Bezug (row 8)
|
||||
bezug = get_val(client_name, 8)
|
||||
|
||||
# Sammelrückführungen (row 4)
|
||||
sammel = get_val(client_name, 4)
|
||||
|
||||
# Verbraucherverluste (row 14) = Sammelrückführungen - Bezug
|
||||
verbrauch = bezug - sammel
|
||||
set_val(client_name, 14, verbrauch, is_calculated=True)
|
||||
|
||||
# % (row 15) = Verbraucherverluste / Bezug
|
||||
if bezug != 0:
|
||||
prozent = verbrauch / bezug
|
||||
else:
|
||||
prozent = Decimal("0")
|
||||
set_val(client_name, 15, prozent, is_calculated=True)
|
||||
|
||||
return updated_cells
|
||||
|
||||
@@ -4360,41 +4344,7 @@ class CheckSheetView(View):
|
||||
})
|
||||
|
||||
|
||||
class QuickDebugView(View):
|
||||
def get(self, request):
|
||||
# Get ALL sheets
|
||||
sheets = MonthlySheet.objects.all().order_by('year', 'month')
|
||||
|
||||
result = {
|
||||
'sheets': []
|
||||
}
|
||||
|
||||
for sheet in sheets:
|
||||
sheet_info = {
|
||||
'id': sheet.id,
|
||||
'display': f"{sheet.year}-{sheet.month:02d}",
|
||||
'url': f"/sheet/{sheet.year}/{sheet.month}/", # CHANGED THIS LINE
|
||||
'sheet_url_pattern': 'sheet/{year}/{month}/', # Add this for clarity
|
||||
}
|
||||
|
||||
# Count cells with data for first client in top_left table
|
||||
first_client = Client.objects.first()
|
||||
if first_client:
|
||||
test_cells = sheet.cells.filter(
|
||||
client=first_client,
|
||||
table_type='top_left',
|
||||
row_index__in=[8, 9, 10] # Rows 9, 10, 11
|
||||
).order_by('row_index')
|
||||
|
||||
cell_values = {}
|
||||
for cell in test_cells:
|
||||
cell_values[f"row_{cell.row_index}"] = str(cell.value) if cell.value else "Empty"
|
||||
|
||||
sheet_info['test_cells'] = cell_values
|
||||
else:
|
||||
sheet_info['test_cells'] = "No clients"
|
||||
|
||||
result['sheets'].append(sheet_info)
|
||||
|
||||
|
||||
return JsonResponse(result)
|
||||
class TestFormulaView(View):
|
||||
@@ -4417,46 +4367,6 @@ class TestFormulaView(View):
|
||||
})
|
||||
|
||||
|
||||
class SimpleDebugView(View):
|
||||
"""Simplest debug view to check if things are working"""
|
||||
def get(self, request):
|
||||
sheet_id = request.GET.get('sheet_id', 1)
|
||||
|
||||
try:
|
||||
sheet = MonthlySheet.objects.get(id=sheet_id)
|
||||
|
||||
# Get first client
|
||||
client = Client.objects.first()
|
||||
if not client:
|
||||
return JsonResponse({'error': 'No clients found'})
|
||||
|
||||
# Check a few cells
|
||||
cells = Cell.objects.filter(
|
||||
sheet=sheet,
|
||||
client=client,
|
||||
table_type='top_left',
|
||||
row_index__in=[8, 9, 10]
|
||||
).order_by('row_index')
|
||||
|
||||
cell_data = []
|
||||
for cell in cells:
|
||||
cell_data.append({
|
||||
'row_index': cell.row_index,
|
||||
'ui_row': cell.row_index + 1,
|
||||
'value': str(cell.value) if cell.value is not None else 'Empty',
|
||||
'cell_id': cell.id
|
||||
})
|
||||
|
||||
return JsonResponse({
|
||||
'sheet': f"{sheet.year}-{sheet.month}",
|
||||
'sheet_id': sheet.id,
|
||||
'client': client.name,
|
||||
'cells': cell_data,
|
||||
'note': 'Row 8 = UI Row 9, Row 9 = UI Row 10, Row 10 = UI Row 11'
|
||||
})
|
||||
|
||||
except MonthlySheet.DoesNotExist:
|
||||
return JsonResponse({'error': f'Sheet with id {sheet_id} not found'})
|
||||
|
||||
def halfyear_settings(request):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user