Coverage for apps/communications/models.py: 94%
51 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-04 17:24 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-04 17:24 +0000
1from __future__ import annotations
3from django.db import models
6class MessageTemplate(models.Model):
7 name = models.CharField(max_length=200)
8 channel = models.CharField(max_length=20) # email, sms, voice
9 category = models.CharField(max_length=100, default="Custom")
10 subject = models.CharField(max_length=255, blank=True, null=True)
11 body = models.TextField()
12 description = models.TextField(blank=True, null=True)
13 trigger = models.CharField(max_length=100, blank=True, null=True)
14 auto_send = models.BooleanField(default=True)
15 active = models.BooleanField(default=True)
16 system = models.BooleanField(default=False)
17 created_at = models.DateTimeField(auto_now_add=True)
18 updated_at = models.DateTimeField(auto_now=True)
20 class Meta:
21 db_table = "communications_templates"
22 ordering = ["category", "name"]
24 def __str__(self) -> str:
25 return f"{self.name} ({self.channel})"
28class Communication(models.Model):
29 loan = models.ForeignKey(
30 "core_los.Loan",
31 on_delete=models.SET_NULL,
32 null=True,
33 blank=True,
34 related_name="communications",
35 )
36 channel = models.CharField(max_length=20)
37 direction = models.CharField(max_length=20, default="outbound")
38 template = models.ForeignKey(
39 MessageTemplate, on_delete=models.SET_NULL, null=True, blank=True
40 )
41 to = models.CharField(max_length=255)
42 subject = models.CharField(max_length=255, blank=True, null=True)
43 body = models.TextField()
44 status = models.CharField(max_length=30, default="Sent")
45 provider = models.CharField(max_length=50, default="simulated")
46 provider_message_id = models.CharField(max_length=100, blank=True, null=True)
47 automated = models.BooleanField(default=False)
48 trigger = models.CharField(max_length=100, blank=True, null=True)
49 created_at = models.DateTimeField(auto_now_add=True)
50 updated_at = models.DateTimeField(auto_now=True)
52 class Meta:
53 db_table = "communications_messages"
54 ordering = ["-created_at"]
56 def __str__(self) -> str:
57 return f"{self.channel} to {self.to} ({self.status})"
60class CommunicationEvent(models.Model):
61 communication = models.ForeignKey(
62 Communication, on_delete=models.CASCADE, related_name="events"
63 )
64 event_type = models.CharField(max_length=30)
65 # Set for provider webhook events (add-sendgrid-email): SendGrid's ``sg_event_id`` makes a
66 # redelivered event a no-op; ``occurred_at`` is when the provider says it happened.
67 provider_event_id = models.CharField(max_length=100, unique=True, null=True, blank=True)
68 occurred_at = models.DateTimeField(null=True, blank=True)
69 created_at = models.DateTimeField(auto_now_add=True)
71 class Meta:
72 db_table = "communications_events"
73 ordering = ["created_at"]
75 def __str__(self) -> str:
76 return f"Event {self.event_type} on Comm {self.communication_id}"