@property
def booking_id(self) -> int:
"""If .booking_line, its .booking_id, else -1."""
- return self.booking_line.booking.id_ if self.booking_line 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:
"""Represents lines of individual booking."""
# pylint: disable=too-few-public-methods
- def __init__(self, id_: int, dat_lines: list[DatLine]) -> None:
- self.intro_line = IntroLine(self, dat_lines[0].code)
- dat_lines[0].booking_line = self.intro_line
+ def __init__(self,
+ id_: int,
+ dat_lines: list[DatLine],
+ prev_booking: Optional[Self]
+ ) -> None:
+ self.intro = IntroLine(self, dat_lines[0].code)
+ dat_lines[0].booking_line = self.intro
self._transfer_lines = []
for i, dat_line in enumerate(dat_lines[1:]):
dat_line.booking_line = TransferLine(self, dat_line.code, i + 1)
self._transfer_lines[-1].errors += ['needed sink missing']
self.id_ = id_
self.dat_lines = dat_lines
+ self.prev = prev_booking
+ if self.prev:
+ self.prev.next = self
+ self.next: Optional[Self] = None
+
+ def can_move(self, up: bool) -> bool:
+ """Whether movement rules would allow self to move up or down."""
+ if (up and ((not self.prev)
+ or self.prev.intro.date != self.intro.date)):
+ return False
+ if ((not up) and ((not self.next)
+ or self.next.intro.date != self.intro.date)):
+ return False
+ return True
@property
def is_questionable(self) -> bool:
"""Whether lines count any errors."""
- for _ in [bl for bl in [self.intro_line] + self._transfer_lines
+ for _ in [bl for bl in [self.intro] + self._transfer_lines
if bl.errors]:
return True
return False
id_ = int(self.path_toks[2])
if self.pagename.startswith('edit_'):
ctx['id'] = id_
- elif self.pagename.startswith('ledger_'):
- ctx['max_id'] = self.server.bookings[-1].id_
if self.pagename == 'balance':
id_ = int(self.params.first('up_incl') or '-1')
valid, balance_roots = self.server.balance_roots(id_)
if dat_line.code:
booking_lines += [dat_line]
elif booking_lines:
- booking = Booking(len(self.bookings), booking_lines)
- if last_date > booking.intro_line.date:
- booking.intro_line.errors += ['date < previous valid date']
+ booking = Booking(
+ len(self.bookings), booking_lines,
+ self.bookings[-1] if self.bookings else None)
+ if last_date > booking.intro.date:
+ booking.intro.errors += ['date < previous valid date']
else:
- last_date = booking.intro_line.date
+ last_date = booking.intro.date
self.bookings += [booking]
booking_lines = []
if to_end or copied is self.bookings[-1]:
intro = DatLine(
f'{dt_date.today().isoformat()} '
- f'{copied.intro_line.target} ; {copied.dat_lines[0].comment}')
+ f'{copied.intro.target} ; {copied.dat_lines[0].comment}')
self.dat_lines += [empty_line, intro] + copied.dat_lines[1:]
prev_id = self.bookings[-1].id_
else:
table.ledger tr > td:first-child { background-color: white; }
{% endmacro %}
-{% macro table_dat_lines(dat_lines, max_id, raw) %}
+{% macro table_dat_lines(dat_lines, raw) %}
<form action="/ledger_{% if raw %}raw{% else %}structured{% endif %}" method="POST">
<table class="ledger">
{% for dat_line in dat_lines %}
{% 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><input type="submit" name="move_{{dat_line.booking_id}}_up" value="^"{% if dat_line.booking_id == 0 %} disabled{% endif %}/></td>
+ <td id="{{dat_line.booking_id}}"><a href="#{{dat_line.booking_id}}">[#]</a><input type="submit" name="move_{{dat_line.booking_id}}_up" value="^"{% if not dat_line.booking.can_move(1) %} disabled{% endif %}/></td>
{% elif dat_line.booking_line.idx == 1 %}
- <td><a href="/balance?up_incl={{dat_line.booking_id}}">[b]</a><input type="submit" name="move_{{dat_line.booking_id}}_down" value="v"{% if dat_line.booking_id == max_id %} disabled{% endif %}/></td>
+ <td><a href="/balance?up_incl={{dat_line.booking_id}}">[b]</a><input type="submit" name="move_{{dat_line.booking_id}}_down" value="v"{% if not dat_line.booking.can_move(0) %} disabled{% endif %}/></td>
{% elif dat_line.booking_line.idx == 2 %}
<td><input type="submit" name="copy_{{dat_line.booking_id}}_here" value="c" /><input type="submit" name="copy_{{dat_line.booking_id}}_to_end" value="C" /></td>
{% else %}