Selaa lähdekoodia

Refactor del calculo del rango del reporte, calculo del rango agnostico a la timezone

Tomás Ponce Gessi 3 vuotta sitten
vanhempi
commit
05fb4dd441
2 muutettua tiedostoa jossa 23 lisäystä ja 35 poistoa
  1. 1 30
      app/api/config.py
  2. 22 5
      app/api/models.py

+ 1 - 30
app/api/config.py

@@ -1,4 +1,3 @@
-from datetime import datetime
 from dateutil.relativedelta import relativedelta as reldelta
 from django.utils.timezone import timedelta as delta
 
@@ -7,32 +6,4 @@ CALENDAR_FREQUENCIES = {
     "weekly": reldelta(weeks=1),
     "monthly": reldelta(months=1),
     "yearly": reldelta(years=1)
-}
-
-# Espera date en UTC
-def get_next_calendar_date(date: datetime, frequency: str):
-    base_date: datetime = date.replace(hour=2, minute=59, second=59, microsecond=0) + delta(days=1)
-    if frequency == "daily":
-        return base_date
-    if frequency == "weekly":
-        days_ahead = -date.weekday() + 6 # Lunes
-        return base_date + delta(days=days_ahead)
-    if frequency == "monthly":
-        return (base_date.replace(day=1) + reldelta(months=1))
-    if frequency == "yearly":
-        return (base_date.replace(day=1, month=1) + reldelta(years=1))
-    return None
-
-# Espera date en UTC
-def get_previous_calendar_date(date: datetime, frequency: str):
-    base_date: datetime = date.replace(hour=2, minute=59, second=59, microsecond=0)
-    if frequency == "daily":
-        return base_date
-    if frequency == "weekly":
-        days_ahead = date.weekday()
-        return base_date - delta(days=days_ahead)
-    if frequency == "monthly":
-        return base_date.replace(day=1)
-    if frequency == "yearly":
-        return base_date.replace(day=1, month=1)
-    return None
+}

+ 22 - 5
app/api/models.py

@@ -1,9 +1,9 @@
 from django.db import models
 from .validators import json_email_array, json_not_empty_string_array, valid_frequency_format
 from django.utils import timezone
-from api.config import get_next_calendar_date, get_previous_calendar_date
 from django.conf import settings
 from django.utils.timezone import timedelta as delta
+from dateutil.relativedelta import relativedelta as reldelta
 from pytz import timezone as tz
 import requests
 import logging
@@ -32,19 +32,36 @@ class ProgrammedReport(models.Model):
     notified_emails = models.JSONField(
         validators=[json_not_empty_string_array, json_email_array])
 
-    # Actualiza la due_date en cada save del modelo:
+    # Calculamos el rango del reporte y lo guardamos en UTC en la base de datos.
     def save(self, *args, **kwargs):
-        self.start_report_date = get_previous_calendar_date(self.start_report_date.replace(tzinfo=tz('UTC')), self.frequency) + delta(seconds=1)
-        self.due_date = get_next_calendar_date(self.start_report_date, self.frequency)
+        range = self.get_report_range()
+        self.start_report_date = range[0].astimezone(tz('UTC'))
+        self.due_date = range[1].astimezone(tz('UTC'))
         super().save(*args, **kwargs)
 
+    def get_report_range(self):
+        # Por defecto frequencia Diaria:
+        start_date = self.start_report_date.astimezone(tz('America/Argentina/Cordoba')).replace(hour=0, minute=0, second=0, microsecond=0)
+        end_date = self.start_report_date.astimezone(tz('America/Argentina/Cordoba')).replace(hour=23, minute=59, second=59, microsecond=0)
+        if self.frequency == "weekly":
+            start_date -= delta(days=start_date.weekday())
+            end_date += delta(days=(6 - end_date.weekday())) # Lunes de la siguiente semana
+        elif self.frequency == "monthly":
+            start_date = start_date.replace(day=1)
+            end_date = (end_date.replace(day=1) + reldelta(months=1)).replace(day=1) - delta(days=1)
+        elif self.frequency == "yearly":
+            start_date = start_date.replace(day=1, month=1)
+            end_date = (end_date.replace(day=1, month=1) + reldelta(years=1)) - delta(days=1)
+        elif self.frequency != 'daily':
+            return None
+        return start_date, end_date
+
     # Metodo que envía la petición a Clima para enviar el reporte.
     def send_report(self):
         # Calculamos el formato en el que Clima requiere recibir los rangos.
         start_date = self.start_report_date.astimezone(tz('America/Argentina/Cordoba')).strftime("%d/%m/%Y %H:%M")
         end_date = self.due_date.astimezone(tz('America/Argentina/Cordoba')).strftime("%d/%m/%Y %H:%M")
         
-        
         # Enviamos la request:
         response = requests.post(settings.CLIMA_URL + "/async_report_handler", {
             "id": self.id,