From b561a011ad4e316155aeb2fb311ccca98ac82370 Mon Sep 17 00:00:00 2001
From: Christian Heller <c.heller@plomlompom.de>
Date: Tue, 28 Jan 2025 13:39:20 +0100
Subject: [PATCH] Calculate /balance up-and-incl. rather than up-and-excl, name
 last included Booking in view.

---
 ledger.py              | 15 +++++++++------
 templates/_macros.tmpl |  2 +-
 templates/balance.tmpl |  1 +
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/ledger.py b/ledger.py
index d254628..a4a94bd 100755
--- a/ledger.py
+++ b/ledger.py
@@ -304,10 +304,12 @@ class Handler(PlomHttpHandler):
             if self.pagename.startswith('edit_'):
                 ctx['id'] = id_
         if self.pagename == 'balance':
-            valid, balance_roots = self.server.balance_roots(
-                    int(self.params.first('cutoff') or '0'))
+            id_ = int(self.params.first('up_incl') or '-1')
+            valid, balance_roots = self.server.balance_roots(id_)
             self.send_rendered(Path('balance.tmpl'),
-                               ctx | {'roots': balance_roots, 'valid': valid})
+                               ctx | {'roots': balance_roots,
+                                      'valid': valid,
+                                      'booking': self.server.bookings[id_]})
         elif self.pagename == 'booking':
             self.redirect(
                     Path('/').joinpath('edit_structured').joinpath(str(id_)))
@@ -390,11 +392,12 @@ class Server(PlomHttpServer):
         """Return only those .data_lines with .code or .comment."""
         return [dl for dl in self.dat_lines if not dl.is_empty]
 
-    def balance_roots(self, cutoff: int) -> tuple[bool, list[Account]]:
-        """Return tree of calculated Accounts over .bookings[:cutoff]."""
+    def balance_roots(self, up_incl: int) -> tuple[bool, list[Account]]:
+        """Return tree of calculated Accounts over .bookings[:up_incl+1]."""
         account_names = set()
         valid = True
-        to_balance = self.bookings[:cutoff] if cutoff else self.bookings
+        to_balance = (self.bookings[:up_incl + 1] if up_incl >= 0
+                      else self.bookings)
         for booking in to_balance:
             valid = valid if not booking.is_questionable else False
             for account_name in booking.account_changes:
diff --git a/templates/_macros.tmpl b/templates/_macros.tmpl
index 0dfd2fc..7ae7845 100644
--- a/templates/_macros.tmpl
+++ b/templates/_macros.tmpl
@@ -15,7 +15,7 @@ td.invalid, tr.warning td.invalid { background-color: #ff0000; }
   {% endif %}
   <tr class="alternating{% if dat_line.is_questionable %} warning{% endif %}">
   {% if dat_line.is_intro %}
-    <td id="{{dat_line.booking_id}}"><a href="#{{dat_line.booking_id}}">#</a>/<a href="/balance?cutoff={{dat_line.booking_id+1}}">b</a></td>
+    <td id="{{dat_line.booking_id}}"><a href="#{{dat_line.booking_id}}">#</a>/<a href="/balance?up_incl={{dat_line.booking_id}}">b</a></td>
   {% else %}
     <td></td>
   {% endif %}
diff --git a/templates/balance.tmpl b/templates/balance.tmpl
index 14878c9..15ebf83 100644
--- a/templates/balance.tmpl
+++ b/templates/balance.tmpl
@@ -62,6 +62,7 @@ span.indent { letter-spacing: 3em; }
 {% endblock css %}
 
 {% block content %}
+<p>balance after <a href="/booking/{{booking.id_}}">booking {{booking.id_}} ({{booking.intro_line.date}}: {{booking.intro_line.target}})</a></p>
 <table{% if not valid %} class="warning"{% endif %}>
 {% for root in roots %}
 {{ account_with_children(root, indent=0) }}
-- 
2.30.2