Skip to content

Commit

Permalink
update reminders cron to not use database
Browse files Browse the repository at this point in the history
  • Loading branch information
avibn committed Apr 12, 2024
1 parent 1db7103 commit fb8c526
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 224 deletions.
2 changes: 1 addition & 1 deletion azure/cron_reminders/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from datetime import UTC, datetime, timezone

from azure.functions import TimerRequest
from database.get_reminders import get_todays_reminders
from network.get_reminders import get_todays_reminders
from utils import queue

# Get the queue proxy
Expand Down
160 changes: 0 additions & 160 deletions azure/database/models.py

This file was deleted.

94 changes: 31 additions & 63 deletions azure/database/get_reminders.py → azure/network/get_reminders.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,12 @@
import datetime
import os
from typing import List

from .models import Lease, LeaseTenant, Payment, User, database

project_reminders_query = """
-- Recurring reminders
WITH recurring_dates AS (
SELECT p."id", g.date::date
FROM "Payment" p
CROSS JOIN LATERAL
generate_series(
p."paymentDate",
(CURRENT_DATE AT TIME ZONE 'UTC') + INTERVAL '10 days',
CASE
WHEN p."recurringInterval" = 'DAILY' THEN '1 day'::interval
WHEN p."recurringInterval" = 'WEEKLY' THEN '7 days'::interval
WHEN p."recurringInterval" = 'MONTHLY' THEN '1 month'::interval
WHEN p."recurringInterval" = 'YEARLY' THEN '1 year'::interval
END
) g(date)
WHERE p."recurringInterval" != 'NONE'
)
SELECT p.*, r.*
FROM recurring_dates rd
JOIN "Payment" p ON rd."id" = p."id"
JOIN "Reminder" r ON p."id" = r."paymentId"
WHERE DATE(rd.date) - r."daysBefore" = (CURRENT_DATE AT TIME ZONE 'UTC')
UNION
-- Non-recurring reminders
SELECT p.*, r.*
FROM "Payment" p
JOIN "Reminder" r ON p."id" = r."paymentId"
WHERE DATE(p."paymentDate") - r."daysBefore" = CURRENT_DATE;
"""
import requests

# Base URL
base_url = os.getenv("BackendBaseUrl")
auth_token = os.getenv("BackendKey")


# Data classes for type hinting
Expand Down Expand Up @@ -68,7 +41,10 @@ def __init__(
self.payment_type = payment_type

# Convert datetime to just date text
self.payment_date = payment_date.strftime("%d-%m-%Y")
payment_datetime = datetime.datetime.strptime(
payment_date, "%Y-%m-%dT%H:%M:%S.%fZ"
)
self.payment_date = payment_datetime.strftime("%d-%m-%Y")

def __str__(self):
return f"{self.payment_id} {self.payment_amount} {self.payment_name} {self.payment_description} {self.payment_type} {self.payment_date}"
Expand Down Expand Up @@ -104,42 +80,34 @@ def get_todays_reminders() -> dict[PaymentData, List[TenantData]]:
Returns:
A dictionary mapping PaymentData instances to a list of TenantData instances.
"""
reminders = database.execute_sql(project_reminders_query)
response = reminders.fetchall()
# reminders = database.execute_sql(project_reminders_query)
# response = reminders.fetchall()

if auth_token is None or base_url is None:
raise ValueError("Base URL and auth token must be set.")

response = requests.get(
f"{base_url}/reminders/all",
headers={"Authorization": auth_token},
).json()

payment_to_tenants = {}
for resp in response:
# Create PaymentData instance to store payment data
(
payment_id,
payment_amount,
payment_name,
payment_description,
payment_type,
payment_date,
*rest,
) = resp

payment_instance = PaymentData(
payment_id,
payment_amount,
payment_name,
payment_description,
payment_type,
payment_date,
resp.get("paymentId"),
resp.get("amount"),
resp.get("name"),
resp.get("description"),
resp.get("type"),
resp.get("paymentDate"),
)

# Get tenants emails and names
tenants = (
User.select(User.email, User.name)
.join(LeaseTenant)
.join(Lease)
.join(Payment)
.where(Payment.id == payment_id)
.distinct() # This is important to avoid duplicates
)

tenants = [TenantData(tenant.name, tenant.email) for tenant in tenants]
tenants = [
TenantData(tenant.get("name"), tenant.get("email"))
for tenant in resp.get("tenants")
]

# Assign tenants to payment
payment_to_tenants[payment_instance] = tenants
Expand Down
103 changes: 103 additions & 0 deletions server/src/controllers/reminders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,106 @@ export const deleteReminder: RequestHandler = async (req, res, next) => {
next(error);
}
};

type AllRemindersQueryResult = {
id: string;
amount: number;
name: string;
description?: string | null;
type: string;
paymentDate: Date;
isDeleted: boolean;
createdAt: Date;
updatedAt: Date;
leaseId?: string | null;
leaseTenantId?: string | null;
recurringInterval: string;
daysBefore: number;
paymentId: string;
}[];

const getAllRemindersQuery = async (): Promise<AllRemindersQueryResult> => {
return prisma.$queryRaw`
-- Recurring reminders
WITH recurring_dates AS (
SELECT p."id", g.date::date
FROM "Payment" p
CROSS JOIN LATERAL
generate_series(
p."paymentDate",
(CURRENT_DATE AT TIME ZONE 'UTC') + INTERVAL '10 days',
CASE
WHEN p."recurringInterval" = 'DAILY' THEN '1 day'::interval
WHEN p."recurringInterval" = 'WEEKLY' THEN '7 days'::interval
WHEN p."recurringInterval" = 'MONTHLY' THEN '1 month'::interval
WHEN p."recurringInterval" = 'YEARLY' THEN '1 year'::interval
END
) g(date)
WHERE p."recurringInterval" != 'NONE'
)
SELECT p.*, r.*
FROM recurring_dates rd
JOIN "Payment" p ON rd."id" = p."id"
JOIN "Reminder" r ON p."id" = r."paymentId"
WHERE DATE(rd.date) - r."daysBefore" = (CURRENT_DATE AT TIME ZONE 'UTC')
UNION
-- Non-recurring reminders
SELECT p.*, r.*
FROM "Payment" p
JOIN "Reminder" r ON p."id" = r."paymentId"
WHERE DATE(p."paymentDate") - r."daysBefore" = CURRENT_DATE;`;
};

export const getAllReminders: RequestHandler = async (req, res, next) => {
try {
const reminders = await getAllRemindersQuery();

// Filter out deleted payments
const filteredReminders = reminders.filter(
(reminder) => !reminder.isDeleted
);

// Add tenants names and emails to the response
const remindersWithTenants = await Promise.all(
filteredReminders.map(async (reminder) => {
if (!reminder.leaseId) {
return reminder;
}

const tenants = await prisma.leaseTenant.findMany({
where: {
leaseId: reminder.leaseId,
isDeleted: false,
tenant: {
isActive: true,
},
},
include: {
tenant: {
select: {
id: true,
name: true,
email: true,
},
},
},
});

return {
...reminder,
tenants: tenants.map((tenant) => ({
id: tenant.tenant.id,
name: tenant.tenant.name,
email: tenant.tenant.email,
})),
};
})
);

res.json(remindersWithTenants);
} catch (error) {
next(error);
}
};
Loading

0 comments on commit fb8c526

Please sign in to comment.