From: Christian Heller Date: Thu, 13 Mar 2025 23:09:38 +0000 (+0100) Subject: Fix insufficient account updating, refactor. X-Git-Url: https://plomlompom.com/repos/%7B%7Bdb.prefix%7D%7D/%22https:/validator.w3.org/%7B%7Bprefix%7D%7D?a=commitdiff_plain;p=ledgplom Fix insufficient account updating, refactor. --- diff --git a/src/run.py b/src/run.py index b69e0fc..abb849d 100755 --- a/src/run.py +++ b/src/run.py @@ -159,7 +159,6 @@ class DatLine(Dictable): self.comment = halves[1] if len(halves) > 1 else '' self.code = halves[0] self.booking_line: Optional[BookingLine] = None - self.hide_comment_in_ledger = False @property def comment_instructions(self) -> dict[str, str]: @@ -544,12 +543,12 @@ class Server(PlomHttpServer): def load(self) -> None: """Read into ledger file at .path_dat.""" - self.accounts, self.bookings, self.initial_gap_lines = {}, [], [] self.dat_lines = [ DatLine(line) for line in self._path_dat.read_text(encoding='utf8').splitlines()] self.last_save_hash = self._hash_dat_lines() - booked_lines: list[DatLine] = [] + self.bookings, self.initial_gap_lines = [], [] + booked: list[DatLine] = [] gap_lines: list[DatLine] = [] booking: Optional[Booking] = None for dat_line in self.dat_lines + [DatLine('')]: @@ -560,27 +559,46 @@ class Server(PlomHttpServer): else: self.initial_gap_lines = gap_lines[:] gap_lines.clear() - booked_lines += [dat_line] + booked += [dat_line] else: - if booked_lines: - booking = Booking(len(self.bookings), booked_lines[:]) - self._apply_booking_to_accounts(booking) - self.bookings += [booking] - booked_lines.clear() + if booked: + self.bookings += [Booking(len(self.bookings), booked[:])] + booked.clear() + if booking: + booking.gap_lines = gap_lines[:-1] + self._sync(recalc_datlines=False) + + def _sync(self, recalc_datlines=True, check_dates=True): + if recalc_datlines: + self.dat_lines = self.initial_gap_lines[:] + for booking in self.bookings: + self.dat_lines += booking.booked_lines + self.dat_lines += booking.gap_lines + for idx, booking in enumerate(self.bookings[1:]): + booking.prev = self.bookings[idx] + for idx, booking in enumerate(self.bookings[:-1]): + booking.next = self.bookings[idx + 1] + self.bookings[-1].next = None + if check_dates: + last_date = '' + err_msg = 'date < previous valid date' + for booking in self.bookings: + if err_msg in booking.intro_line.errors: + booking.intro_line.errors.remove(err_msg) + if last_date > booking.date: + booking.intro_line.errors += [err_msg] + else: + last_date = booking.date + self._recalc_prev_line_empty() + self.accounts = {} + for dat_line in self.dat_lines: for acc_name, desc in dat_line.comment_instructions.items(): self.ensure_account(acc_name) self.accounts[acc_name].desc = desc - self._check_date_order() for booking in self.bookings: - booking.recalc_prev_next(self.bookings) - if booking: - booking.gap_lines = gap_lines[:-1] - self._recalc_prev_line_empty() - - def _apply_booking_to_accounts(self, booking: Booking) -> None: - for acc_name, wealth in booking.account_changes.items(): - self.ensure_account(acc_name) - self.accounts[acc_name].add_wealth_diff(booking.id_, wealth) + for acc_name, wealth in booking.account_changes.items(): + self.ensure_account(acc_name) + self.accounts[acc_name].add_wealth_diff(booking.id_, wealth) def ensure_account(self, full_path: str) -> None: """If full_path not in self.accounts, add its tree with Accounts.""" @@ -592,17 +610,6 @@ class Server(PlomHttpServer): step_name) parent_path = path - def _check_date_order(self) -> None: - last_date = '' - err_msg = 'date < previous valid date' - for booking in self.bookings: - if err_msg in booking.intro_line.errors: - booking.intro_line.errors.remove(err_msg) - if last_date > booking.date: - booking.intro_line.errors += [err_msg] - else: - last_date = booking.date - def save(self) -> None: """Save current state to ._path_dat.""" self._path_dat.write_text( @@ -633,14 +640,7 @@ class Server(PlomHttpServer): if prev_line or line.code + line.comment_in_ledger: # jump over prev_line = line # empty start - def _recalc_dat_lines(self) -> None: - self.dat_lines = self.initial_gap_lines[:] - for booking in self.bookings: - self.dat_lines += booking.booked_lines - self.dat_lines += booking.gap_lines - self._recalc_prev_line_empty() - - def _move_booking(self, idx_from, idx_to) -> None: + def _move_booking(self, idx_from: int, idx_to: int): moving = self.bookings[idx_from] if idx_from >= idx_to: # moving upward, deletion must del self.bookings[idx_from] # precede insertion to keep @@ -650,34 +650,15 @@ class Server(PlomHttpServer): min_idx, max_idx = min(idx_from, idx_to), max(idx_from, idx_to) for idx, booking in enumerate(self.bookings[min_idx:max_idx + 1]): booking.id_ = min_idx + idx - booking.recalc_prev_next(self.bookings) - def move_booking(self, old_id: int, up: bool) -> int: + def move_booking(self, idx_from: int, up: bool) -> int: """Move Booking of old_id one step up or downwards""" - new_id = old_id + (-1 if up else 1) - self._move_booking(old_id, # moving down implies - new_id + (0 if up else 1)) # jumping over next item - self._recalc_dat_lines() + new_id = idx_from + (-1 if up else 1) + idx_to = new_id + (0 if up else 1) # down-move imlies jump over next + self._move_booking(new_id, idx_to) + self._sync() return new_id - def _remove_booking( - self, - to_remove: Booking, - summed_gap: list[DatLine] - ) -> None: - del self.bookings[to_remove.id_] - for booking in self.bookings[to_remove.id_:]: - booking.id_ -= 1 - if to_remove.id_ == 0: - self.initial_gap_lines += summed_gap - else: - assert to_remove.prev is not None - to_remove.prev.gap_lines += summed_gap - for neighbour in to_remove.prev, to_remove.next: - if neighbour: - neighbour.recalc_prev_next(self.bookings) - self._recalc_dat_lines() - def rewrite_booking(self, old_id: int, new_lines: list[DatLine]) -> int: """Rewrite Booking with new_lines, move if changed date.""" old_booking = self.bookings[old_id] @@ -697,37 +678,42 @@ class Server(PlomHttpServer): after_gap = old_booking.gap_lines_copied # new gap be old gap _plus_ after_gap += new_lines[booked_end:] # any new gap lines if not new_booked_lines: # interpret empty posting as deletion request - self._remove_booking(old_booking, before_gap + after_gap) + del self.bookings[old_id] + for booking in self.bookings[old_id:]: + booking.id_ -= 1 + leftover_gap = before_gap + after_gap + if old_id == 0: + self.initial_gap_lines += leftover_gap + else: + self.bookings[old_id - 1].gap_lines += leftover_gap + self._sync(check_dates=False) return old_id if old_id < len(self.bookings) else 0 + if old_id == 0: + self.initial_gap_lines += before_gap + else: + self.bookings[old_id - 1].gap_lines += before_gap + new_date = new_booked_lines[0].code.lstrip().split(maxsplit=1)[0] updated = Booking(old_id, new_booked_lines, after_gap) self.bookings[old_id] = updated - updated.recalc_prev_next(self.bookings) - new_date = new_booked_lines[0].code.lstrip().split(maxsplit=1)[0] if new_date != old_booking.date: # if changed date, move to there - i_booking = self.bookings[0] - new_idx = None - while i_booking.next: - if (not i_booking.prev) and i_booking.date > new_date: - new_idx = i_booking.id_ - break - if i_booking.next.date > new_date: - break - i_booking = i_booking.next - if new_idx is None: - new_idx = i_booking.id_ + 1 - # ensure that, if we land in group of like-dated Bookings, we - # land on the edge closest to our last position - if i_booking.date == new_date and old_id < i_booking.id_: - new_idx = [b for b in self.bookings - if b != updated and b.date == new_date][0].id_ - self._move_booking(old_id, new_idx) - if updated.id_ == 0: - self.initial_gap_lines += before_gap - else: - assert updated.prev is not None - updated.prev.gap_lines += before_gap - self._recalc_dat_lines() - self._check_date_order() + if self.bookings[0].date > new_date: + new_id = 0 + elif self.bookings[-1].date < new_date: + new_id = self.bookings[-1].id_ + 1 + else: + of_date_1st = i_booking = self.bookings[0] + while i_booking.next: + if of_date_1st.date != i_booking.date: + of_date_1st = i_booking + if i_booking.next.date > new_date: + break + i_booking = i_booking.next + # ensure that, if we land in group of like-dated Bookings, we + # land on the edge closest to our last position + new_id = (of_date_1st.id_ if old_id < i_booking.id_ + else i_booking.id_ + 1) + self._move_booking(old_id, new_id) + self._sync(check_dates=False) return updated.id_ def _add_new_booking( @@ -742,9 +728,7 @@ class Server(PlomHttpServer): + ' ; '.join([''] + [s for s in [intro_comment] if s])) ] + dat_lines_transaction) self.bookings += [booking] - booking.recalc_prev_next(self.bookings) - self._recalc_dat_lines() - self._check_date_order() + self._sync() return booking.id_ def add_empty_booking(self) -> int: