-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpayment.py
More file actions
66 lines (52 loc) · 2.07 KB
/
payment.py
File metadata and controls
66 lines (52 loc) · 2.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
"""Payment model and related helpers."""
from datetime import datetime, timedelta
import numpy as np
class Payment:
"""Represents a single payment entry with due date and status."""
amount: float
paid: bool
excel_row: int
due_date: datetime
def __init__(self, paid=False, due_date=None, amount=0.0, excel_row=0):
"""Create a payment with defaults for status, date, amount and row.
Note: avoid using datetime.now() as a default argument value.
"""
self.due_date = due_date or datetime.now()
self.amount: float = amount
self.paid: bool = paid
self.excel_row: int = excel_row
def __str__(self):
"""Return a human-readable description of the payment."""
return f"{self.amount:.2f}zł - {self.paid_status} - {self.due_date:%Y-%m-%d}"
@property
def paid_status(self):
"""Text label describing whether the payment is paid."""
if self.paid:
return "paid"
return "not yet paid"
@property
def payable_within_2days(self) -> bool:
"""True if unpaid and either overdue or due within the next two days.
Note: includes past-due items (negative delta) as "within 2 days" to
reflect urgency.
"""
today = datetime.now()
delta = self.due_date - today
return (not self.paid) and (delta <= timedelta(days=2))
@property
def due_soon_or_overdue(self) -> bool:
"""Alias for readability; same semantics as `payable_within_2days`."""
today = datetime.now()
delta = self.due_date - today
return (not self.paid) and (delta <= timedelta(days=2))
@property
def overdue(self) -> bool:
"""True if past due and still unpaid."""
today = datetime.now()
delta = self.due_date - today
return (delta.total_seconds() < 0) and (not self.paid)
@property
def b_days_left(self) -> int:
"""Business days left until due date."""
today = datetime.now()
return int(np.busday_count(f'{today:%Y-%m-%d}', f'{self.due_date:%Y-%m-%d}'))