aboutsummaryrefslogtreecommitdiff
path: root/libs/invoice.py
diff options
context:
space:
mode:
Diffstat (limited to 'libs/invoice.py')
-rw-r--r--libs/invoice.py69
1 files changed, 69 insertions, 0 deletions
diff --git a/libs/invoice.py b/libs/invoice.py
new file mode 100644
index 0000000..92b82f7
--- /dev/null
+++ b/libs/invoice.py
@@ -0,0 +1,69 @@
1from enum import StrEnum, auto
2
3from pydantic import BaseModel
4from sqlalchemy import and_, select
5from sqlalchemy.ext.asyncio import AsyncSession
6
7from models import Invoice, Payment, PaymentStatus, User, UserRole
8
9
10class InvoiceStatus(StrEnum):
11 PAID = auto()
12 UNPAID = auto()
13
14
15class InvoicePayments(BaseModel):
16 user_status: dict[int, PaymentStatus]
17 status: InvoiceStatus
18
19
20async def get_invoice_payments(
21 session: AsyncSession,
22 invoice: Invoice,
23) -> InvoicePayments:
24 users = await session.scalars(
25 select(User).where(
26 and_(
27 User.role != UserRole.ADMIN,
28 User.datetime <= invoice.datetime,
29 )
30 )
31 )
32 payments = await session.scalars(
33 select(Payment).where(Payment.invoice_id == invoice.id)
34 )
35
36 user_status = {u.id: PaymentStatus.REJECTED for u in users}
37 for p in payments:
38 if (
39 p.status != PaymentStatus.REJECTED
40 and user_status[p.user_id] == PaymentStatus.REJECTED
41 ):
42 user_status[p.user_id] = p.status
43
44 status = (
45 InvoiceStatus.PAID
46 if all(s == PaymentStatus.ACCEPTED for s in user_status.values())
47 else InvoiceStatus.UNPAID
48 )
49
50 return InvoicePayments(user_status=user_status, status=status)
51
52
53async def get_payment_status(
54 session: AsyncSession,
55 invoice_id: int,
56 user_id: int,
57) -> PaymentStatus:
58 payments = await session.scalars(
59 select(Payment).where(
60 and_(
61 Payment.invoice_id == invoice_id,
62 Payment.user_id == user_id,
63 )
64 )
65 )
66 for p in payments:
67 if p.status != PaymentStatus.REJECTED:
68 return p.status
69 return PaymentStatus.REJECTED