diff --git a/requirements.txt b/requirements.txt index 80815ea..2eccc25 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,36 +1,54 @@ +amqp==5.2.0 asgiref==3.7.2 +billiard==4.2.0 +celery==5.3.6 certifi==2023.7.22 charset-normalizer==3.3.2 +click==8.1.7 +click-didyoumean==0.3.0 +click-plugins==1.1.1 +click-repl==0.3.0 distlib==0.3.7 Django==4.2.7 django-cors-headers==4.3.0 django-filter==23.3 +django-guardian==2.4.0 djangorestframework==3.14.0 +djangorestframework-guardian==0.3.0 exceptiongroup==1.1.3 filelock==3.13.1 greenlet==3.0.0 idna==3.4 iniconfig==2.0.0 +kombu==5.3.4 +numpy==1.26.1 packaging==23.2 +pandas==2.1.2 Pillow==10.1.0 pipenv==2023.10.24 platformdirs==3.11.0 playwright==1.39.0 -djangorestframework-guardian==0.3.0 pluggy==1.3.0 +prompt-toolkit==3.0.41 psycopg2-binary==2.9.9 pyee==11.0.1 pytest==7.4.3 pytest-base-url==2.0.0 pytest-playwright==0.4.3 +python-dateutil==2.8.2 python-dotenv==1.0.0 python-slugify==8.0.1 pytz==2023.3.post1 requests==2.31.0 +scipy==1.11.3 +six==1.16.0 sqlparse==0.4.4 text-unidecode==1.3 tomli==2.0.1 typing_extensions==4.8.0 +tzdata==2023.3 urllib3==2.0.7 +vine==5.1.0 virtualenv==20.24.6 -whitenoise==6.6.0 \ No newline at end of file +wcwidth==0.2.12 +whitenoise==6.6.0 diff --git a/smartreport/settings.py b/smartreport/settings.py index f51a072..44c4113 100644 --- a/smartreport/settings.py +++ b/smartreport/settings.py @@ -171,7 +171,7 @@ USE_I18N = True -USE_TZ = True +USE_TZ = False # Static files (CSS, JavaScript, Images) @@ -186,3 +186,12 @@ DEBUG = True + +DEFAULT_FROM_EMAIL = 'smartreports@example.com' + +EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +EMAIL_HOST = 'smtp.mailtrap.io' +EMAIL_PORT = 2525 +EMAIL_HOST_USER = 'fa29b0a6d18965' +EMAIL_HOST_PASSWORD = '84f5260599344e' +EMAIL_USE_TLS = True diff --git a/smartreport_app/email.py b/smartreport_app/email.py new file mode 100644 index 0000000..72dd007 --- /dev/null +++ b/smartreport_app/email.py @@ -0,0 +1,56 @@ +from django.core.mail import EmailMessage +from django.conf import settings +from django.forms import ValidationError +from .models import UserType, ArchivedReport, Email + +def send_emails_for_unsent_reports(): + # Get distinct user types from UserType enumeration + user_types = [user_type[0] for user_type in UserType.choices] + + for user_type in user_types: + try: + # Get the unsent ArchivedReport instances for the user type + unsent_reports = ArchivedReport.objects.filter( + user_type=user_type, sent=False + ) + + # Get the corresponding Email instance for the user type + email_instance = Email.objects.get(user_type=user_type) + + # Validate that emails field is a list + if not isinstance(email_instance.emails, list): + raise ValidationError("Emails must be a list") + + # Iterate over each unsent report and send an email for each file + for report in unsent_reports: + # Check if the report template matches the user's template + if report.template.user_type == user_type: + # Create an EmailMessage object + subject = 'Subject of your email' + message = 'Body of your email' + email = EmailMessage( + subject, + message, + settings.DEFAULT_FROM_EMAIL, + email_instance.emails, + reply_to=[settings.DEFAULT_FROM_EMAIL], + ) + + # Get the file content from the ArchivedReport + file_content = report.file.read() + + # Attach the file to the email + email.attach(report.file.name, file_content, 'application/octet-stream') + + # Send the email + email.send() + + # Update the sent status of the ArchivedReport + report.sent = True + report.save() + + except Email.DoesNotExist: + print(f"Email with user_type {user_type} does not exist.") + except Exception as e: + print(f"An error occurred: {e}") + diff --git a/smartreport_app/models.py b/smartreport_app/models.py index f7d762e..8f9ae19 100644 --- a/smartreport_app/models.py +++ b/smartreport_app/models.py @@ -193,4 +193,4 @@ class Email(models.Model): def clean(self): if not isinstance(self.emails, list): - raise ValidationError("Emails must be a list") \ No newline at end of file + raise ValidationError("Emails must be a list") diff --git a/smartreport_app/urls.py b/smartreport_app/urls.py index 0c4b2c4..680e653 100644 --- a/smartreport_app/urls.py +++ b/smartreport_app/urls.py @@ -12,6 +12,8 @@ router.register(r"report-img", views.ReportTemplateImageViewSet) router.register(r"dashboard-layout", views.DashboardLayoutViewSet) router.register(r"kpi-data", views.KpiDataViewSet, basename="kpi-data") +router.register(r'sync-kb', views.SyncKBViewSet, basename='sync-kb') +router.register(r'send-emails', views.SendEmailsViewSet, basename='send-emails') # The API URLs are now determined automatically by the router. urlpatterns = [path("", include(router.urls))] diff --git a/smartreport_app/views.py b/smartreport_app/views.py index 7b1316d..902ce32 100644 --- a/smartreport_app/views.py +++ b/smartreport_app/views.py @@ -2,6 +2,7 @@ from typing import Any import django_filters from .sync_db_kb import sync_kpi_lits +from .email import send_emails_for_unsent_reports from .models import ( KpiReportElement, @@ -139,4 +140,26 @@ def list(self, request): class ArchiveViewSet(viewsets.ModelViewSet): queryset = ArchivedReport.objects.all() serializer_class = ArchivedReportSerializer - filterset_fields = ["user_type"] \ No newline at end of file + filterset_fields = ["user_type"] + + +class SyncKBViewSet(viewsets.GenericViewSet): + def __init__(self, **kwargs: Any) -> None: + if (os.environ.get("DEBUG").lower() == "false"): + self.permission_classes = [IsAuthenticated] + super().__init__(**kwargs) + + def list(self, request): + sync_kpi_lits() + return Response({"message": "Syncing KB"}) + + +class SendEmailsViewSet(viewsets.GenericViewSet): + def __init__(self, **kwargs: Any) -> None: + if (os.environ.get("DEBUG").lower() == "false"): + self.permission_classes = [IsAuthenticated] + super().__init__(**kwargs) + + def list(self, request): + send_emails_for_unsent_reports() + return Response({"message": "Sending emails"}) \ No newline at end of file