Skip to content

Commit

Permalink
Attributs structures
Browse files Browse the repository at this point in the history
  • Loading branch information
chloend committed Nov 4, 2024
1 parent 57817e1 commit bca81a2
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 5 deletions.
22 changes: 20 additions & 2 deletions lemarche/crm/management/commands/crm_brevo_sync_companies.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from lemarche.utils.commands import BaseCommand


ten_days_ago = timezone.now() - timedelta(days=10)
two_weeks_ago = timezone.now() - timedelta(weeks=2)


class Command(BaseCommand):
Expand All @@ -34,11 +34,29 @@ def handle(self, recently_updated: bool, **options):
self.stdout.write(f"Sync Siae > Brevo: we have {Siae.objects.count()} siaes")
# Update only the recently updated siaes
if recently_updated:
siaes_qs = siaes_qs.filter(updated_at__gte=ten_days_ago)
siaes_qs = siaes_qs.filter(updated_at__gte=two_weeks_ago)
self.stdout.write(f"Sync Siae > Brevo: {siaes_qs.count()} recently updated")

# Step 2: loop on the siaes
for index, siae in enumerate(siaes_qs):
recent_tender_detail_click_count = siae.tendersiae_set.filter(
detail_contact_click_date__gte=timezone.now() - timedelta(days=90)
).count()

print("HANDLE : old siae.extra_data", siae.extra_data)

new_extra_data = {
"completion_rate": siae.completion_rate,
"tender_email_send_count": siae.tender_email_send_count,
"recent_tender_detail_click_count": recent_tender_detail_click_count,
}

print("HANDLE : new siae.extra_data", new_extra_data)

if siae.extra_data != new_extra_data:
siae.extra_data = new_extra_data
siae.save(update_fields=["extra_data"])

api_brevo.create_or_update_company(siae)
if (index % 10) == 0: # avoid API rate-limiting
time.sleep(1)
Expand Down
94 changes: 94 additions & 0 deletions lemarche/crm/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
from datetime import timedelta

from django.core.management import call_command
from django.test import TestCase
from django.utils import timezone

from lemarche.siaes.factories import SiaeFactory
from lemarche.users.factories import UserFactory
from lemarche.utils.apis.api_brevo import create_or_update_company
from lemarche.utils.urls import get_object_admin_url, get_object_share_url

from unittest.mock import patch, MagicMock


class CrmBrevoSyncCompaniesCommandTest(TestCase):
@patch("lemarche.utils.apis.api_brevo.sib_api_v3_sdk.Body")
def test_create_or_update_company_with_mocked_body(self, mock_body):
# Créer un mock pour `Body`
mock_body_instance = MagicMock()
mock_body.return_value = mock_body_instance

# Créer un objet `Siae` de test
siae = SiaeFactory(name="Test Company", completion_rate=0.5)

# Appeler la fonction que l'on souhaite tester
create_or_update_company(siae)

expected_attributes = {
"domain": siae.website,
"phone_number": siae.contact_phone_display,
"app_id": siae.id,
"siae": True,
"active": siae.is_active,
"description": siae.description,
"kind": siae.kind,
"address_street": siae.address,
"address_post_code": siae.post_code,
"address_city": siae.city,
"contact_email": siae.contact_email,
"logo_url": siae.logo_url,
"geo_range": siae.geo_range,
"app_url": get_object_share_url(siae),
"app_admin_url": get_object_admin_url(siae),
**siae.extra_data, # includes completion_rate, tender_email_send_count, etc.
}

mock_body.assert_called_once_with(name="Test Company", attributes=expected_attributes)

@patch('lemarche.utils.apis.api_brevo.create_or_update_company')
def test_new_siaes_are_synced_in_brevo(self, mock_create_or_update_company):
""" Test new siaes are synced in brevo """
siae1 = SiaeFactory()
siae2 = SiaeFactory()

call_command('crm_brevo_sync_companies')

mock_create_or_update_company.assert_any_call(siae1)
mock_create_or_update_company.assert_any_call(siae2)
self.assertEqual(mock_create_or_update_company.call_count, 2)

@patch('lemarche.utils.apis.api_brevo.create_or_update_company')
def test_siae_sync_even_if_extra_data_unchanged(self, mock_create_or_update_company):
"""Test siae is not updated if extra_data is unchanged."""
siae = SiaeFactory(brevo_company_id="12345")

call_command('crm_brevo_sync_companies', recently_updated=True)

mock_create_or_update_company.assert_called_once_with(siae)

@patch('lemarche.utils.apis.api_brevo.create_or_update_company')
def test_extra_data_is_updated(self, mock_create_or_update_company):
"""Test siae is updated if extra_data is changed."""
siae = SiaeFactory(brevo_company_id="12345")
siae.save()
print("old siae.extra_data", siae.extra_data)

siae.completion_rate = 75
siae.tender_email_send_count = 20
siae.save()

print("TEST : new siae.extra_data", siae.extra_data)

call_command('crm_brevo_sync_companies', recently_updated=True)

self.assertTrue(mock_create_or_update_company.called)

new_extra_data = {
"completion_rate": 75,
"tender_email_send_count": 20,
"recent_tender_detail_click_count": 0,
}
print("TEST : new_extra_data", new_extra_data)
siae.refresh_from_db()
self.assertEqual(siae.extra_data, new_extra_data)
35 changes: 34 additions & 1 deletion lemarche/siaes/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from datetime import timedelta

from uuid import uuid4

from django.conf import settings
Expand Down Expand Up @@ -1348,7 +1350,38 @@ def set_super_badge(self):


@receiver(post_save, sender=Siae)
def siae_post_save(sender, instance, **kwargs):
def siae_post_save(sender, instance, created, **kwargs):
if created:
instance.extra_data = {
"completion_rate": instance.completion_rate,
"tender_email_send_count": instance.tender_email_send_count,
"recent_tender_detail_click_count": instance.tendersiae_set.filter(
detail_contact_click_date__gte=timezone.now() - timedelta(days=90)
).count(), # Calculer le nombre de clics récents
}
instance.save(update_fields=["extra_data"]) # Sauvegarder pour initialiser extra_data
else:
# Récupérer l'instance précédente pour comparer les valeurs
previous_instance = Siae.objects.get(pk=instance.pk)

# Compter le nombre de clics récents pour l'instance actuelle
new_recent_tender_detail_click_count = instance.tendersiae_set.filter(
detail_contact_click_date__gte=timezone.now() - timedelta(days=90)
).count()

# Comparer les valeurs pour voir si l'un des attributs a changé
if (instance.completion_rate != previous_instance.completion_rate or
instance.tender_email_send_count != previous_instance.tender_email_send_count or
new_recent_tender_detail_click_count != previous_instance.extra_data.get('recent_tender_detail_click_count', 0)):

# Mettre à jour extra_data
instance.extra_data = {
"completion_rate": instance.completion_rate,
"tender_email_send_count": instance.tender_email_send_count,
"recent_tender_detail_click_count": new_recent_tender_detail_click_count,
}
instance.save(update_fields=["extra_data"])

field_name = "address"
previous_field_name = f"__previous_{field_name}"
if getattr(instance, field_name) and getattr(instance, field_name) != getattr(instance, previous_field_name):
Expand Down
7 changes: 5 additions & 2 deletions lemarche/utils/apis/api_brevo.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import json
import logging
import time

import sib_api_v3_sdk

from datetime import timedelta
from django.conf import settings
from django.utils import timezone
from huey.contrib.djhuey import task
from sib_api_v3_sdk.rest import ApiException

Expand Down Expand Up @@ -118,7 +120,7 @@ def create_or_update_company(siae):

siae_brevo_company_body = sib_api_v3_sdk.Body(
name=siae.name,
attributes={
attributes = {
# default attributes
# name, owner, linked_contacts, revenue, number_of_employees, created_at, last_updated_at, next_activity_date, owner_assign_date, number_of_contacts, number_of_activities, industry # noqa
"domain": siae.website,
Expand All @@ -137,6 +139,7 @@ def create_or_update_company(siae):
"geo_range": siae.geo_range,
"app_url": get_object_share_url(siae),
"app_admin_url": get_object_admin_url(siae),
**siae.extra_data, # includes completion_rate, tender_email_send_count, etc.
},
)

Expand Down

0 comments on commit bca81a2

Please sign in to comment.