Source code for feriennet.models.invoice_action

from functools import cached_property
from datetime import date
from onegov.activity import InvoiceItem


from typing import Literal, TYPE_CHECKING
if TYPE_CHECKING:
    from collections.abc import Collection, Iterator
    from sqlalchemy.orm import Session
    from uuid import UUID


[docs] class InvoiceAction: def __init__( self, session: 'Session', id: 'UUID', action: Literal['mark-paid', 'mark-unpaid', 'remove-manual'], extend_to: Literal['invoice', 'family'] | None = None, text: str | None = None ) -> None:
[docs] self.session = session
[docs] self.id = id
[docs] self.action = action
[docs] self.extend_to = extend_to
[docs] self.text = text
@cached_property
[docs] def item(self) -> InvoiceItem | None: return self.session.query(InvoiceItem).filter_by(id=self.id).first()
@property
[docs] def valid(self) -> bool: if self.action not in ('mark-paid', 'mark-unpaid', 'remove-manual'): return False if self.extend_to not in (None, 'invoice', 'family'): return False if not self.item: return False if self.extend_to == 'family' and self.action != 'remove-manual': return False return True
@property
[docs] def targets(self) -> 'Iterator[InvoiceItem]': item = self.item if item: yield item if self.extend_to == 'invoice': q = self.session.query(InvoiceItem) q = q.filter(InvoiceItem.id != item.id) q = q.filter(InvoiceItem.invoice_id == item.invoice_id) yield from q if self.extend_to == 'family': q = self.session.query(InvoiceItem) q = q.filter(InvoiceItem.id != item.id) q = q.filter(InvoiceItem.family == item.family) yield from q
[docs] def execute(self) -> None: if self.action == 'mark-paid': self.execute_mark_paid(tuple(self.targets)) elif self.action == 'mark-unpaid': self.execute_mark_unpaid(tuple(self.targets)) elif self.action == 'remove-manual': assert self.extend_to in (None, 'family') self.execute_remove_manual(tuple(self.targets)) else: raise NotImplementedError()
[docs] def assert_safe_to_change( self, targets: 'Collection[InvoiceItem]' ) -> None: for target in targets: if target.invoice.disable_changes_for_items((target, )): raise RuntimeError('Item was paid online')
[docs] def execute_mark_paid(self, targets: 'Collection[InvoiceItem]') -> None: self.assert_safe_to_change(targets) for target in targets: target.payment_date = date.today() target.paid = True
[docs] def execute_mark_unpaid(self, targets: 'Collection[InvoiceItem]') -> None: self.assert_safe_to_change(targets) for target in targets: target.payment_date = None target.paid = False target.tid = None target.source = None
[docs] def execute_remove_manual( self, targets: 'Collection[InvoiceItem]' ) -> None: self.assert_safe_to_change(targets) for target in targets: assert target.family and target.family.startswith('manual-') self.session.delete(target)