Skip to content

Commit

Permalink
Orphan URNs if they still have associated content
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanseymour committed Feb 24, 2025
1 parent f2d7922 commit 432668c
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 40 deletions.
37 changes: 11 additions & 26 deletions temba/contacts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1122,31 +1122,21 @@ def _full_release(self):
break
Msg.bulk_delete(msg_batch)

for run in self.runs.all():
run.delete()

for session in self.sessions.all():
session.delete()

# any urns currently owned by us
for urn in self.urns.all():
# release any messages attached with each urn, these could include messages that began life
# on a different contact
for msg in urn.msgs.all():
msg.delete()

# same thing goes for calls
for call in urn.calls.all():
if call.session:
call.session.delete()
call.delete()

urn.release()

delete_in_batches(self.runs.all())
delete_in_batches(self.sessions.all())
delete_in_batches(self.channel_events.all())
delete_in_batches(self.calls.all())
delete_in_batches(self.fires.all())

for urn in self.urns.all():
# delete the urn if it has no associated content.. which should be the case if it wasn't
# stolen from another contact
if not urn.msgs.all() and not urn.channel_events.all() and not urn.calls.all():
urn.delete()
else:
urn.contact = None
urn.save(update_fields=("contact",))

# take us out of broadcast addressed contacts
for broadcast in self.addressed_broadcasts.all():
broadcast.contacts.remove(self)
Expand Down Expand Up @@ -1320,11 +1310,6 @@ class ContactURN(models.Model):
# auth tokens - usage is channel specific, e.g. every FCM URN has its own token, FB channels have per opt-in tokens
auth_tokens = models.JSONField(null=True)

def release(self):
delete_in_batches(self.channel_events.all())

self.delete()

def ensure_number_normalization(self, country_code):
"""
Tries to normalize our phone number from a possible 10 digit (0788 383 383) to a 12 digit number
Expand Down
6 changes: 3 additions & 3 deletions temba/contacts/tests/test_contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,9 @@ def test_release(self, mr_mocks):
self.assertEqual(1, Ticket.get_status_count(self.org, self.org.topics.all(), Ticket.STATUS_OPEN))
self.assertEqual(0, Ticket.get_status_count(self.org, self.org.topics.all(), Ticket.STATUS_CLOSED))

# contact who used to own our urn had theirs released too
self.assertEqual(0, old_contact.calls.all().count())
self.assertEqual(0, old_contact.msgs.all().count())
# contact who used to own our urn still has their content
self.assertEqual(1, old_contact.calls.all().count())
self.assertEqual(2, old_contact.msgs.all().count())

self.assertIsNone(contact.fields)
self.assertIsNone(contact.name)
Expand Down
11 changes: 0 additions & 11 deletions temba/ivr/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from datetime import timedelta

from django.contrib.postgres.fields import ArrayField
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.db.models import Q
from django.utils import timezone
Expand Down Expand Up @@ -94,16 +93,6 @@ def status_display(self) -> str:
status += f" ({self.get_error_reason_display()})"
return status

def get_session(self):
"""
There is a one-to-one relationship between flow sessions and call, but as call can be null
it can throw an exception
"""
try:
return self.session
except ObjectDoesNotExist: # pragma: no cover
return None

def get_logs(self) -> list:
return ChannelLog.get_by_uuid(self.channel, self.log_uuids or [])

Expand Down

0 comments on commit 432668c

Please sign in to comment.