| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- 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 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
- logger = logging.getLogger('django')
- class ProgrammedReport(models.Model):
- REPORT_FORMATS = [
- ("excel", "Excel"),
- ("csv", "CSV")
- ]
- name = models.CharField(max_length=100)
- user_id = models.CharField(max_length=2048)
- frequency = models.CharField(max_length=20, default="monthly", validators=[valid_frequency_format])
- start_report_date = models.DateTimeField(
- default=timezone.now)
- due_date = models.DateTimeField(blank=True, null=True, default=None)
- # Valores que configuran al reporte:
- format = models.CharField(
- max_length=5, choices=REPORT_FORMATS)
- option = models.CharField(max_length=50, default="all")
- stations = models.JSONField(validators=[json_not_empty_string_array])
- modules = models.JSONField(validators=[json_not_empty_string_array])
- notified_emails = models.JSONField(
- validators=[json_not_empty_string_array, json_email_array])
- # Calculamos el rango del reporte y lo guardamos en UTC en la base de datos.
- def save(self, *args, **kwargs):
- 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,
- "name": self.name,
- "user_id": self.user_id,
- "format": self.format,
- "stations": self.stations,
- "modules": self.modules,
- "option": self.option,
- "start_date": start_date,
- "end_date": end_date,
- "notified_emails": self.notified_emails
- }, headers={"AUTHORIZATION": settings.PROGRAMMED_REPORTS_SERVICE_AUTH_TOKEN})
- if response.status_code != 200:
- logger.critical(
- "No se pudo enviar el reporte asincrono: %s\n Reason: %s", self, response.reason)
- # TODO! Seria ideal enviar un email al administrador para ver que paso.
- return False
- self.start_report_date = self.due_date + delta(seconds=1) # Pass to next cycle
- self.save()
- return True
- def send_report_now(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 = timezone.datetime.now().strftime("%d/%m/%Y %H:%M")
- # Enviamos la request:
- response = requests.post(settings.CLIMA_URL + "/async_report_handler", {
- "id": self.id,
- "name": self.name,
- "user_id": self.user_id,
- "format": self.format,
- "stations": self.stations,
- "modules": self.modules,
- "option": self.option,
- "start_date": start_date,
- "end_date": end_date,
- "notified_emails": self.notified_emails
- }, headers={"AUTHORIZATION": settings.PROGRAMMED_REPORTS_SERVICE_AUTH_TOKEN})
- if response.status_code != 200:
- logger.critical(
- "No se pudo enviar el reporte asincrono: %s\n Reason: %s", self, response.reason)
- # TODO! Seria ideal enviar un email al administrador para ver que paso.
- return False
- return True
|