fix(notification): fixed formatting and linting

This commit is contained in:
sankalp committed 2025-12-11 21:09:14 +05:45
1 parent 466d4b868a
commit 63d63d5e5c
7 files changed
+57 -57

No files matched your search

+1 -2
View File
@@ -1,5 +1,4 @@
"""generated with djinit"""
# Create your models here.
from .notifications import Notification
from .notifications import Notification as Notification
+32 -28
View File
@@ -1,19 +1,20 @@
from django.db import models
from django.core.mail import send_mail
from django.conf import settings
from django.utils import timezone
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth import get_user_model
from django.core.mail import send_mail
from django.db import models
from django.utils import timezone
from src.models.base import TimeStampedModel
from src.models.projects import Project, Milestone, Task
from src.models.services import Service
from src.models.finance import Invoice
from src.models.productivity import TimeEntry
from src.models.projects import Milestone, Project, Task
from src.models.services import Service
User = get_user_model()
class Notification(TimeStampedModel):
STATUS_CHOICES = [
("PENDING", "Pending"),
@@ -26,11 +27,13 @@ class Notification(TimeStampedModel):
message = models.TextField()
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="PENDING")
sent_at = models.DateTimeField(null=True, blank=True)
# Generic relation to link to the source object (Project, Invoice, etc.)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, null=True, blank=True)
content_type = models.ForeignKey(
ContentType, on_delete=models.CASCADE, null=True, blank=True
)
object_id = models.PositiveIntegerField(null=True, blank=True)
content_object = GenericForeignKey('content_type', 'object_id')
content_object = GenericForeignKey("content_type", "object_id")
class Meta:
ordering = ["-created_at"]
@@ -62,9 +65,9 @@ def get_admin_emails():
admins = getattr(settings, "ADMINS", [])
if admins:
return [email for name, email in admins]
# Fallback to superusers
return list(User.objects.filter(is_superuser=True).values_list('email', flat=True))
return list(User.objects.filter(is_superuser=True).values_list("email", flat=True))
def create_and_send(recipient, subject, message, obj=None):
@@ -77,7 +80,7 @@ def create_and_send(recipient, subject, message, obj=None):
subject=subject,
content_type=ct,
object_id=obj.id,
created_at__date=timezone.localdate()
created_at__date=timezone.localdate(),
).exists()
if already_sent:
return
@@ -100,7 +103,7 @@ def check_and_send_notifications():
"""
today = timezone.localdate()
tomorrow = today + timezone.timedelta(days=1)
admin_emails = get_admin_emails()
if not admin_emails:
print("Warning: No admin emails found.")
@@ -115,16 +118,16 @@ def check_and_send_notifications():
recipient=project.client.email,
subject=f"Project Deadline Reminder: {project.name}",
message=f"Dear {project.client.name},\n\nThe project '{project.name}' is due on {project.deadline}.\n\nRegards,\nDevSuite",
obj=project
obj=project,
)
# Notify Admin
for email in admin_emails:
create_and_send(
recipient=email,
subject=f"Admin Alert: Project Deadline - {project.name}",
message=f"Project '{project.name}' for client {project.client.name} is due on {project.deadline}.",
obj=project
obj=project,
)
# --- Milestones (Due Date) ---
@@ -138,16 +141,16 @@ def check_and_send_notifications():
recipient=project.client.email,
subject=f"Milestone Due: {milestone.title}",
message=f"Dear {project.client.name},\n\nThe milestone '{milestone.title}' for project '{project.name}' is due on {milestone.due_date}.\n\nRegards,\nDevSuite",
obj=milestone
obj=milestone,
)
# Notify Admin
for email in admin_emails:
create_and_send(
recipient=email,
subject=f"Admin Alert: Milestone Due - {milestone.title}",
message=f"Milestone '{milestone.title}' (Project: {project.name}) is due on {milestone.due_date}.",
obj=milestone
obj=milestone,
)
# --- Tasks (Due Date) ---
@@ -159,7 +162,7 @@ def check_and_send_notifications():
recipient=email,
subject=f"Task Due: {task.title}",
message=f"Task '{task.title}' (Project: {task.project.name}) is due on {task.due_date}.",
obj=task
obj=task,
)
# --- Services (Expiry Date) ---
@@ -171,33 +174,34 @@ def check_and_send_notifications():
recipient=service.client.email,
subject=f"Service Expiry Warning: {service.name}",
message=f"Dear {service.client.name},\n\nYour service '{service.name}' ({service.get_service_type_display()}) expires on {service.expiry_date}.\nPlease renew it soon.\n\nRegards,\nDevSuite",
obj=service
obj=service,
)
# --- Invoices (Due Date) ---
# Notify Client
invoices_due = Invoice.objects.filter(due_date=tomorrow, status__in=["SENT", "OVERDUE"])
invoices_due = Invoice.objects.filter(
due_date=tomorrow, status__in=["SENT", "OVERDUE"]
)
for invoice in invoices_due:
if invoice.client.email:
create_and_send(
recipient=invoice.client.email,
subject=f"Invoice Due: {invoice.invoice_number}",
message=f"Dear {invoice.client.name},\n\nInvoice {invoice.invoice_number} for {invoice.amount} is due on {invoice.due_date}.\nPlease make payment.\n\nRegards,\nDevSuite",
obj=invoice
obj=invoice,
)
# --- Productivity / TimeEntries ---
# Notify Admin for recently completed time entries (last 24h)
recent_entries = TimeEntry.objects.filter(
end_time__gte=timezone.now() - timezone.timedelta(hours=24),
end_time__lte=timezone.now()
end_time__lte=timezone.now(),
)
for entry in recent_entries:
# Check if we already sent a notification for this entry
if Notification.objects.filter(
content_type=ContentType.objects.get_for_model(entry),
object_id=entry.id
content_type=ContentType.objects.get_for_model(entry), object_id=entry.id
).exists():
continue
@@ -206,5 +210,5 @@ def check_and_send_notifications():
recipient=email,
subject=f"Time Entry Logged: {entry.description}",
message=f"User logged time for '{entry.description}'.\nDuration: {entry.duration}\nEnd Time: {entry.end_time}",
obj=entry
obj=entry,
)