home · contact · privacy
Remove unnecessary _BookedLine.booking.
authorChristian Heller <c.heller@plomlompom.de>
Wed, 19 Mar 2025 10:44:51 +0000 (11:44 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Wed, 19 Mar 2025 10:44:51 +0000 (11:44 +0100)
src/ledgplom/ledger.py
src/templates/_macros.tmpl
src/templates/edit_structured.tmpl

index c2213bfe739f1b85e37186bf32c8a1f2153ad1d9..762e6c31e319f86e5f4b1125efa5bb4f2e5c57b7 100644 (file)
@@ -127,7 +127,7 @@ class Account:
 
 class DatLine(_Dictable):
     """Line of .dat file parsed into comments and machine-readable data."""
-    dictables = {'booking_line', 'code', 'comment', 'error', 'is_intro'}
+    dictables = {'booked', 'code', 'comment', 'error', 'is_intro'}
     prev_line_empty: bool
 
     def __init__(self, line: str) -> None:
@@ -135,7 +135,8 @@ class DatLine(_Dictable):
         halves = [t.rstrip() for t in line.split(';', maxsplit=1)]
         self.comment = halves[1] if len(halves) > 1 else ''
         self.code = halves[0]
-        self.booking_line: Optional[_BookingLine] = None
+        self.booking: Optional['_Booking'] = None
+        self.booked: Optional[_BookingLine] = None
 
     @property
     def comment_instructions(self) -> dict[str, str]:
@@ -158,28 +159,22 @@ class DatLine(_Dictable):
     @property
     def is_intro(self) -> bool:
         """Return if intro line of a _Booking."""
-        return isinstance(self.booking_line, _IntroLine)
+        return isinstance(self.booked, _IntroLine)
 
     @property
     def booking_id(self) -> int:
-        """If .booking_line, its .booking_id, else -1."""
+        """If .booking, its .booking_id, else -1."""
         return self.booking.id_ if self.booking else -1
 
-    @property
-    def booking(self) -> Optional['_Booking']:
-        """If .booking_line, matching _Booking, else None."""
-        return self.booking_line.booking if self.booking_line else None
-
     @property
     def error(self) -> str:
         """Return error if registered on attempt to parse into _BookingLine."""
-        return '; '.join(self.booking_line.errors) if self.booking_line else ''
+        return '; '.join(self.booked.errors) if self.booked else ''
 
     @property
     def is_questionable(self) -> bool:
         """Return whether line be questionable per associated _Booking."""
-        return (self.booking_line.booking.is_questionable if self.booking_line
-                else False)
+        return self.booking.is_questionable if self.booking else False
 
     @property
     def raw_nbsp(self) -> str:
@@ -192,9 +187,8 @@ class DatLine(_Dictable):
 class _BookingLine(_Dictable):
     """Parsed code part of a DatLine belonging to a _Booking."""
 
-    def __init__(self, booking: '_Booking') -> None:
+    def __init__(self) -> None:
         self.errors: list[str] = []
-        self.booking = booking
         self.idx = 0
 
 
@@ -202,8 +196,8 @@ class _IntroLine(_BookingLine):
     """First line of a _Booking, expected to carry date etc."""
     dictables = {'date', 'target'}
 
-    def __init__(self, booking: '_Booking', code: str) -> None:
-        super().__init__(booking)
+    def __init__(self, code: str) -> None:
+        super().__init__()
         if code[0].isspace():
             self.errors += ['intro line indented']
         toks = code.lstrip().split(maxsplit=1)
@@ -221,8 +215,8 @@ class _TransferLine(_BookingLine):
     """Non-first _Booking line, expected to carry value movement."""
     dictables = {'amount', 'account', 'currency'}
 
-    def __init__(self, booking: '_Booking', code: str, idx: int) -> None:
-        super().__init__(booking)
+    def __init__(self, code: str, idx: int) -> None:
+        super().__init__()
         self.idx = idx
         self.currency = ''
         self.amount: Optional[Decimal] = None
@@ -263,13 +257,14 @@ class _Booking:
         self.id_, self.booked_lines = id_, booked_lines[:]
         self._gap_lines = gap_lines[:] if gap_lines else []
         # parse booked_lines into Intro- and _TransferLines
-        self.intro_line = _IntroLine(self, self.booked_lines[0].code)
-        self._transfer_lines = [
-                _TransferLine(self, b_line.code, i+1) for i, b_line
-                in enumerate(self.booked_lines[1:])]
-        self.booked_lines[0].booking_line = self.intro_line
+        for line in booked_lines:
+            line.booking = self
+        self.intro_line = _IntroLine(self.booked_lines[0].code)
+        self._transfer_lines = [_TransferLine(b_line.code, i+1) for i, b_line
+                                in enumerate(self.booked_lines[1:])]
+        self.booked_lines[0].booked = self.intro_line
         for i, b_line in enumerate(self._transfer_lines):
-            self.booked_lines[i + 1].booking_line = b_line
+            self.booked_lines[i + 1].booked = b_line
         # calculate .account_changes
         changes = _Wealth()
         sink_account = None
index 97eddaf5e0f7e72e5cab8a09b6934c1bff8f3ff3..9135e51c743e6188b0386a12bbf2f21e476d376c 100644 (file)
@@ -43,10 +43,10 @@ table.ledger tr > td:first-child { background-color: white; text-align: right; }
     {% if dat_line.is_intro %}
       <a href="#{{dat_line.booking_id}}">[#]</a>
       {{ table_dat_lines_action_button(dat_line, "moveup", "^", dat_line.booking.can_move(1)) }}
-    {% elif dat_line.booking_line.idx == 1 %}
+    {% elif dat_line.booked.idx == 1 %}
       <a href="/balance?up_incl={{dat_line.booking_id}}">[b]</a>
       {{ table_dat_lines_action_button(dat_line, "movedown", "v", dat_line.booking.can_move(0)) }}
-    {% elif dat_line.booking_line.idx == 2 %}
+    {% elif dat_line.booked.idx == 2 %}
       {{ table_dat_lines_action_button(dat_line, "copy", "C") }}
     {% endif %}
     </td>
@@ -69,10 +69,10 @@ table.ledger tr > td:first-child { background-color: white; text-align: right; }
       {% elif dat_line.error %}
         <td class="invalid" colspan=3>{{dat_line.code}}</td>
         <td>{{dat_line.comment_in_ledger}}</td>
-      {% elif dat_line.booking_line %}
-        <td class="amt">{{dat_line.booking_line.amount_short}}</td>
-        <td class="curr">{{dat_line.booking_line.currency|truncate(4,true,"…")}}</td>
-        <td>{{dat_line.booking_line.account}}</td>
+      {% elif dat_line.booked %}
+        <td class="amt">{{dat_line.booked.amount_short}}</td>
+        <td class="curr">{{dat_line.booked.currency|truncate(4,true,"…")}}</td>
+        <td>{{dat_line.booked.account}}</td>
         <td>{{dat_line.comment_in_ledger}}</td>
       {% else %}
         <td colspan=2></td>
index 959574c381823803705038d5cf165f79b4d32620..cab68dea9052f78175373ec2c4843e586c19937e 100644 (file)
@@ -46,15 +46,15 @@ function update_form() {
           } else if (input.name.endsWith('error')) {
             line_to_update.code = input.value;
           } else if (input.name.endsWith('date')) {
-            line_to_update.booking_line.date = input.value;
+            line_to_update.booked.date = input.value;
           } else if (input.name.endsWith('target')) {
-            line_to_update.booking_line.target = input.value;
+            line_to_update.booked.target = input.value;
           } else if (input.name.endsWith('account')) {
-            line_to_update.booking_line.account = input.value;
+            line_to_update.booked.account = input.value;
           } else if (input.name.endsWith('amount')) {
-            line_to_update.booking_line.amount = input.value;
+            line_to_update.booked.amount = input.value;
           } else if (input.name.endsWith('currency')) {
-            line_to_update.booking_line.currency = input.value;
+            line_to_update.booked.currency = input.value;
           }
         }
       }
@@ -111,21 +111,21 @@ function update_form() {
     // actual input lines
     if (dat_line.is_intro) {
       const td = setup_input_td(tr, 3);
-      const date_input = add_input(td, 'date', dat_line.booking_line.date, 10)
+      const date_input = add_input(td, 'date', dat_line.booked.date, 10)
       date_input.classList.add('date_input');
-      add_input(td, 'target', dat_line.booking_line.target, 37)
+      add_input(td, 'target', dat_line.booked.target, 37)
     } else if (!dat_line.error) {  // i.e. valid TransferLine
-      const acc_input = add_td_input('account', dat_line.booking_line.account, 30);
+      const acc_input = add_td_input('account', dat_line.booked.account, 30);
       acc_input.setAttribute ('list', 'all_accounts');
       acc_input.autocomplete = 'off';
       // not using input[type=number] cuz no minimal step size, therefore regex test instead
-      const amt_input = add_td_input('amount', dat_line.booking_line.amount == 'None' ? '' : dat_line.booking_line.amount, 12);
+      const amt_input = add_td_input('amount', dat_line.booked.amount == 'None' ? '' : dat_line.booked.amount, 12);
       amt_input.pattern = '^-?[0-9]+(\.[0-9]+)?$';
       amt_input.classList.add("number_input");
       // ensure integer amounts at least line up with double-digit decimals
       if (amt_input.value.match(/^-?[0-9]+$/)) { amt_input.value += '.00'; }
       // imply that POST handler will set '€' currency if unset, but amount set
-      const curr_input = add_td_input('currency', dat_line.booking_line.currency, 3);
+      const curr_input = add_td_input('currency', dat_line.booked.currency, 3);
       curr_input.placeholder = '€';
     } else {
       add_td_input('error', dat_line.code, 20, 3)
@@ -135,7 +135,7 @@ function update_form() {
     // line deletion and addition buttons
     td_add_del = add_td(tr);
     add_button(td_add_del, 'add new',  false, function() {
-        new_line = {error: '', comment: '', booking_line: {account: '', amount: '', currency: ''}};
+        new_line = {error: '', comment: '', booked: {account: '', amount: '', currency: ''}};
         dat_lines.splice(i + 1, 0, new_line);
     });
     if (i > 0) {
@@ -170,8 +170,8 @@ function replace() {
         dat_line.code = dat_line.code.replaceAll(from, to);
       }
       ['date', 'target', 'account', 'amount', 'currency'].forEach((key) => {
-          if (key in dat_line.booking_line) {
-              dat_line.booking_line[key] = dat_line.booking_line[key].replaceAll(from, to);
+          if (key in dat_line.booked) {
+              dat_line.booked[key] = dat_line.booked[key].replaceAll(from, to);
           }
       });
   });
@@ -181,17 +181,17 @@ function replace() {
 
 function mirror() {
   dat_lines.slice(1).forEach((dat_line) => {
-      let inverted_amount = `-${dat_line.booking_line.amount}`;
+      let inverted_amount = `-${dat_line.booked.amount}`;
       if (inverted_amount.startsWith('--')) {
           inverted_amount = inverted_amount.slice(2);
       }
       dat_lines.push({
           error: '',
           comment: '',
-          booking_line: {
+          booked: {
               account: '?',
               amount: inverted_amount,
-              currency: dat_line.booking_line.currency
+              currency: dat_line.booked.currency
           }
       });
   })