From 63f3bd0eab89b234377fcfbc522b13ef77e56fe6 Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Sun, 19 Jan 2025 20:18:19 +0800 Subject: [PATCH] Implement major changes --- docmanager_backend/accounts/serializers.py | 29 +++- docmanager_backend/accounts/signals.py | 7 +- .../authorization_requests/admin.py | 8 +- ...authorizationrequest_documents_and_more.py | 63 +++++++++ .../0003_authorizationrequestunit_pages.py | 21 +++ .../0004_authorizationrequestunit_status.py | 22 +++ .../authorization_requests/models.py | 21 ++- .../authorization_requests/serializers.py | 130 ++++++++++++++++-- .../authorization_requests/urls.py | 3 + .../authorization_requests/views.py | 16 ++- .../management/commands/start_watcher.py | 12 +- .../0005_alter_documentrequest_status.py | 28 ++++ .../document_requests/models.py | 2 + .../document_requests/serializers.py | 26 ++-- docmanager_backend/emails/templates.py | 3 +- .../emails/templates/request_approved.html | 6 +- 16 files changed, 357 insertions(+), 40 deletions(-) create mode 100644 docmanager_backend/authorization_requests/migrations/0002_remove_authorizationrequest_documents_and_more.py create mode 100644 docmanager_backend/authorization_requests/migrations/0003_authorizationrequestunit_pages.py create mode 100644 docmanager_backend/authorization_requests/migrations/0004_authorizationrequestunit_status.py create mode 100644 docmanager_backend/document_requests/migrations/0005_alter_documentrequest_status.py diff --git a/docmanager_backend/accounts/serializers.py b/docmanager_backend/accounts/serializers.py index 2b809ee..2de062b 100644 --- a/docmanager_backend/accounts/serializers.py +++ b/docmanager_backend/accounts/serializers.py @@ -3,6 +3,7 @@ from rest_framework import serializers from django.contrib.auth.password_validation import validate_password from django.core import exceptions as django_exceptions from rest_framework.settings import api_settings +from django.utils.timezone import now, localdate class CustomUserUpdateSerializer(serializers.ModelSerializer): @@ -15,7 +16,7 @@ class CustomUserUpdateSerializer(serializers.ModelSerializer): class CustomUserSerializer(serializers.ModelSerializer): - birthday = serializers.DateField(format="%Y-%m-%d") + birthday = serializers.DateField(format="%m-%d-%Y") class Meta: model = CustomUser @@ -52,7 +53,7 @@ class CustomUserRegistrationSerializer(serializers.ModelSerializer): ) first_name = serializers.CharField(required=True) last_name = serializers.CharField(required=True) - birthday = serializers.DateField(format="%Y-%m-%d", required=True) + birthday = serializers.DateField(format="%m-%d-%Y", required=True) class Meta: model = CustomUser @@ -76,6 +77,30 @@ class CustomUserRegistrationSerializer(serializers.ModelSerializer): if self.Meta.model.objects.filter(username=attrs.get("email")).exists(): raise serializers.ValidationError( "A user with that email already exists.") + + # Only allow major email providers + email = attrs.get("email") + allowed_email_domains = ["gmail.com", "outlook.com", "ustp.edu.ph"] + + if not any(provider in email for provider in allowed_email_domains): + raise serializers.ValidationError( + "Non-major email providers are not supported") + + # Validate age based on birthday + birthday = attrs.get("birthday") + date_now = localdate(now()) + age = ( + date_now.year + - birthday.year + - ( + (date_now.month, date_now.day) + < (birthday.month, birthday.day) + ) + ) + + if age < 16: + raise serializers.ValidationError( + "You need to be at least 16 years old to avail of this USTP service") return super().validate(attrs) def create(self, validated_data): diff --git a/docmanager_backend/accounts/signals.py b/docmanager_backend/accounts/signals.py index 6baddc5..2e984ba 100644 --- a/docmanager_backend/accounts/signals.py +++ b/docmanager_backend/accounts/signals.py @@ -12,13 +12,18 @@ def create_admin_user(sender, **kwargs): if sender.name == "accounts": users = [{ "email": get_secret("ADMIN_EMAIL"), - "role": "head", + "role": "admin", "admin": True, }, { "email": "staff@test.com", "role": "staff", "admin": False, }, { + "email": "head@test.com", + "role": "head", + "admin": False, + }, + { "email": "planning@test.com", "role": "planning", "admin": False, diff --git a/docmanager_backend/authorization_requests/admin.py b/docmanager_backend/authorization_requests/admin.py index bee255a..3572496 100644 --- a/docmanager_backend/authorization_requests/admin.py +++ b/docmanager_backend/authorization_requests/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin from unfold.admin import ModelAdmin -from .models import AuthorizationRequest +from .models import AuthorizationRequest, AuthorizationRequestUnit # Register your models here. @@ -9,3 +9,9 @@ from .models import AuthorizationRequest class AuthorizationRequestAdmin(ModelAdmin): search_fields = ["id"] list_display = ["id", "date_requested", "status", "college"] + + +@admin.register(AuthorizationRequestUnit) +class AuthorizationRequestUnitAdmin(ModelAdmin): + search_fields = ["id"] + list_display = ["id", "status", "document", "pages", "copies"] diff --git a/docmanager_backend/authorization_requests/migrations/0002_remove_authorizationrequest_documents_and_more.py b/docmanager_backend/authorization_requests/migrations/0002_remove_authorizationrequest_documents_and_more.py new file mode 100644 index 0000000..16cc699 --- /dev/null +++ b/docmanager_backend/authorization_requests/migrations/0002_remove_authorizationrequest_documents_and_more.py @@ -0,0 +1,63 @@ +# Generated by Django 5.1.3 on 2025-01-17 15:41 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("authorization_requests", "0001_initial"), + ] + + operations = [ + migrations.RemoveField( + model_name="authorizationrequest", + name="documents", + ), + migrations.AlterField( + model_name="authorizationrequest", + name="status", + field=models.CharField( + choices=[ + ("pending", "Pending"), + ("approved", "Approved"), + ("denied", "Denied"), + ("claimed", "Claimed"), + ("unclaimed", "Unclaimed"), + ], + default="pending", + max_length=32, + ), + ), + migrations.CreateModel( + name="AuthorizationRequestUnit", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("document", models.TextField(max_length=256)), + ("copies", models.IntegerField(default=1)), + ( + "authorization_request", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="authorization_requests.authorizationrequest", + ), + ), + ], + ), + migrations.AddField( + model_name="authorizationrequest", + name="documents", + field=models.ManyToManyField( + to="authorization_requests.authorizationrequestunit" + ), + ), + ] diff --git a/docmanager_backend/authorization_requests/migrations/0003_authorizationrequestunit_pages.py b/docmanager_backend/authorization_requests/migrations/0003_authorizationrequestunit_pages.py new file mode 100644 index 0000000..b2e23e9 --- /dev/null +++ b/docmanager_backend/authorization_requests/migrations/0003_authorizationrequestunit_pages.py @@ -0,0 +1,21 @@ +# Generated by Django 5.1.3 on 2025-01-17 16:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ( + "authorization_requests", + "0002_remove_authorizationrequest_documents_and_more", + ), + ] + + operations = [ + migrations.AddField( + model_name="authorizationrequestunit", + name="pages", + field=models.IntegerField(default=1), + ), + ] diff --git a/docmanager_backend/authorization_requests/migrations/0004_authorizationrequestunit_status.py b/docmanager_backend/authorization_requests/migrations/0004_authorizationrequestunit_status.py new file mode 100644 index 0000000..cf108f4 --- /dev/null +++ b/docmanager_backend/authorization_requests/migrations/0004_authorizationrequestunit_status.py @@ -0,0 +1,22 @@ +# Generated by Django 5.1.3 on 2025-01-19 10:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("authorization_requests", "0003_authorizationrequestunit_pages"), + ] + + operations = [ + migrations.AddField( + model_name="authorizationrequestunit", + name="status", + field=models.CharField( + choices=[("pending", "Pending"), ("checked", "Checked")], + default="pending", + max_length=32, + ), + ), + ] diff --git a/docmanager_backend/authorization_requests/models.py b/docmanager_backend/authorization_requests/models.py index 9389641..ed2f962 100644 --- a/docmanager_backend/authorization_requests/models.py +++ b/docmanager_backend/authorization_requests/models.py @@ -2,10 +2,27 @@ from django.db import models from django.utils.timezone import now +class AuthorizationRequestUnit(models.Model): + authorization_request = models.ForeignKey( + "authorization_requests.AuthorizationRequest", on_delete=models.CASCADE + ) + document = models.TextField(max_length=256) + pages = models.IntegerField(default=1, null=False, blank=False) + copies = models.IntegerField(default=1, null=False, blank=False) + STATUS_CHOICES = ( + ("pending", "Pending"), + ("checked", "Checked"), + ) + + status = models.CharField( + max_length=32, choices=STATUS_CHOICES, default="pending") + + class AuthorizationRequest(models.Model): requester = models.ForeignKey( "accounts.CustomUser", on_delete=models.CASCADE) - documents = models.TextField(max_length=2048, blank=False, null=False) + documents = models.ManyToManyField( + "authorization_requests.AuthorizationRequestUnit") date_requested = models.DateTimeField(default=now, editable=False) college = models.CharField(max_length=64, blank=False, null=False) purpose = models.TextField(max_length=512, blank=False, null=False) @@ -14,6 +31,8 @@ class AuthorizationRequest(models.Model): ("pending", "Pending"), ("approved", "Approved"), ("denied", "Denied"), + ("claimed", "Claimed"), + ("unclaimed", "Unclaimed"), ) remarks = models.TextField(max_length=512, blank=True, null=True) diff --git a/docmanager_backend/authorization_requests/serializers.py b/docmanager_backend/authorization_requests/serializers.py index 521f5b3..c9eb909 100644 --- a/docmanager_backend/authorization_requests/serializers.py +++ b/docmanager_backend/authorization_requests/serializers.py @@ -1,14 +1,33 @@ from rest_framework import serializers from accounts.models import CustomUser from emails.templates import RequestUpdateEmail -from .models import AuthorizationRequest +from .models import AuthorizationRequest, AuthorizationRequestUnit + + +class AuthorizationRequestUnitCreationSerializer(serializers.ModelSerializer): + document = serializers.CharField() + copies = serializers.IntegerField(min_value=1) + pages = serializers.IntegerField(min_value=1) + + class Meta: + model = AuthorizationRequestUnit + fields = ["document", "copies", "pages", "status"] + + +class AuthorizationRequestUnitSerializer(serializers.ModelSerializer): + + class Meta: + model = AuthorizationRequestUnit + fields = ["id", "document", "status", "copies", "pages"] + read_only_fields = ["id", "document", "status," "copies", "pages"] class AuthorizationRequestCreationSerializer(serializers.ModelSerializer): requester = serializers.SlugRelatedField( many=False, slug_field="id", queryset=CustomUser.objects.all(), required=False ) - documents = serializers.CharField(max_length=2048, required=True) + documents = AuthorizationRequestUnitCreationSerializer( + many=True, required=True) college = serializers.CharField(max_length=64) purpose = serializers.CharField(max_length=512) @@ -18,11 +37,31 @@ class AuthorizationRequestCreationSerializer(serializers.ModelSerializer): def create(self, validated_data): user = self.context["request"].user - + documents_data = validated_data.pop("documents") + if not documents_data: + raise serializers.ValidationError( + {"error": "No documents provided"} + ) # Set requester to user who sent HTTP request to prevent spoofing validated_data["requester"] = user - return AuthorizationRequest.objects.create(**validated_data) + AUTHORIZATION_REQUEST = AuthorizationRequest.objects.create( + **validated_data) + + AUTHORIZATION_REQUEST_UNITS = [] + for AUTHORIZATION_REQUEST_UNIT in documents_data: + AUTHORIZATION_REQUEST_UNIT = AuthorizationRequestUnit.objects.create( + authorization_request=AUTHORIZATION_REQUEST, + document=AUTHORIZATION_REQUEST_UNIT["document"], + copies=AUTHORIZATION_REQUEST_UNIT["copies"], + pages=AUTHORIZATION_REQUEST_UNIT["pages"] + ) + AUTHORIZATION_REQUEST_UNITS.append(AUTHORIZATION_REQUEST_UNIT) + + AUTHORIZATION_REQUEST.documents.set(AUTHORIZATION_REQUEST_UNITS) + AUTHORIZATION_REQUEST.save() + + return AUTHORIZATION_REQUEST class AuthorizationRequestSerializer(serializers.ModelSerializer): @@ -34,6 +73,7 @@ class AuthorizationRequestSerializer(serializers.ModelSerializer): date_requested = serializers.DateTimeField( format="%m-%d-%Y %I:%M %p", read_only=True ) + documents = AuthorizationRequestUnitSerializer(many=True) class Meta: model = AuthorizationRequest @@ -59,6 +99,59 @@ class AuthorizationRequestSerializer(serializers.ModelSerializer): ] +class AuthorizationRequestUnitUpdateSerializer(serializers.ModelSerializer): + status = serializers.ChoiceField( + choices=AuthorizationRequestUnit.STATUS_CHOICES, required=True + ) + + class Meta: + model = AuthorizationRequestUnit + fields = ["id", "status"] + read_only_fields = ["id"] + + def update(self, instance, validated_data): + if instance.authorization_request.status != "pending": + raise serializers.ValidationError( + { + "error": "Already approved/denied requests cannot be updated. You should instead create a new request and approve it from there" + } + ) + if instance.status == "checked": + raise serializers.ValidationError( + { + "error": "Already approved/denied request units cannot be updated. You should instead create a new request and approve it from there" + } + ) + elif "status" not in validated_data: + raise serializers.ValidationError( + { + "error": "No status value update provided" + } + ) + elif validated_data["status"] == instance.status: + raise serializers.ValidationError( + {"error": "Request unit status provided is the same as current status"} + ) + representation = super().update(instance, validated_data) + + # Check if the parent Authorization Request has had all its documents approved + approved_all = True + for AUTHORIZATION_REQUEST_UNIT in instance.authorization_request.documents.all(): + if AUTHORIZATION_REQUEST_UNIT.status != "checked": + approved_all = False + + # If all documents have been checked + if approved_all: + # Set the parent request as approved + instance.authorization_request.status = "approved" + instance.authorization_request.save() + # And send an email notification + email = RequestUpdateEmail() + email.context = {"request_status": "approved"} + email.send(to=[instance.authorization_request.requester.email]) + return representation + + class AuthorizationRequestUpdateSerializer(serializers.ModelSerializer): status = serializers.ChoiceField( choices=AuthorizationRequest.STATUS_CHOICES, required=True @@ -70,23 +163,30 @@ class AuthorizationRequestUpdateSerializer(serializers.ModelSerializer): read_only_fields = ["id"] def update(self, instance, validated_data): - print(validated_data) - if instance.status == "denied" or instance.status == "approved": - raise serializers.ValidationError( - { - "error": "Already approved/denied requests cannot be updated. You should instead create a new request and approve it from there" - } - ) - elif "status" not in validated_data: + if "status" not in validated_data: raise serializers.ValidationError( { "error": "No status value update provided" } ) + elif instance.status == "denied" or instance.status == "claimed": + raise serializers.ValidationError( + { + "error": "Already claimed/denied requests cannot be updated. You should instead create a new request and approve it from there" + } + ) elif validated_data["status"] == instance.status: raise serializers.ValidationError( {"error": "Request form status provided is the same as current status"} ) + elif instance.status == "approved" and validated_data["status"] not in ["claimed", "unclaimed"]: + raise serializers.ValidationError( + {"error": "Approved request forms can only be marked as claimed or unclaimed"} + ) + elif instance.status == "unclaimed" and validated_data["status"] not in ["claimed"]: + raise serializers.ValidationError( + {"error": "Unclaimed request forms can only be marked as claimed"} + ) elif validated_data["status"] == "denied" and "remarks" not in validated_data: raise serializers.ValidationError( {"error": "Request denial requires remarks"} @@ -96,14 +196,16 @@ class AuthorizationRequestUpdateSerializer(serializers.ModelSerializer): # Send an email on request status update try: email = RequestUpdateEmail() - email.context = {"request_status": validated_data["status"]} if validated_data["status"] == "denied": + email.context = {"request_status": "denied"} email.context = {"remarks": validated_data["remarks"]} else: + email.context = {"request_status": "approved"} email.context = {"remarks": "N/A"} email.send(to=[instance.requester.email]) - except: + except Exception as e: # Silence out errors if email sending fails + print(e) pass return representation diff --git a/docmanager_backend/authorization_requests/urls.py b/docmanager_backend/authorization_requests/urls.py index 7691179..381082c 100644 --- a/docmanager_backend/authorization_requests/urls.py +++ b/docmanager_backend/authorization_requests/urls.py @@ -3,10 +3,13 @@ from .views import ( AuthorizationRequestCreateView, AuthorizationRequestUpdateView, AuthorizationRequestListView, + AuthorizationRequestUnitUpdateView ) urlpatterns = [ path("create/", AuthorizationRequestCreateView.as_view()), path("list/", AuthorizationRequestListView.as_view()), path("update//", AuthorizationRequestUpdateView.as_view()), + path("authorization_request_units/update//", + AuthorizationRequestUnitUpdateView.as_view()), ] diff --git a/docmanager_backend/authorization_requests/views.py b/docmanager_backend/authorization_requests/views.py index 8dc0573..205333a 100644 --- a/docmanager_backend/authorization_requests/views.py +++ b/docmanager_backend/authorization_requests/views.py @@ -6,10 +6,11 @@ from rest_framework.pagination import PageNumberPagination from .serializers import ( AuthorizationRequestCreationSerializer, AuthorizationRequestSerializer, - AuthorizationRequestUpdateSerializer + AuthorizationRequestUpdateSerializer, + AuthorizationRequestUnitUpdateSerializer ) -from .models import AuthorizationRequest +from .models import AuthorizationRequest, AuthorizationRequestUnit class AuthorizationRequestCreateView(generics.CreateAPIView): @@ -51,3 +52,14 @@ class AuthorizationRequestUpdateView(generics.UpdateAPIView): serializer_class = AuthorizationRequestUpdateSerializer permission_classes = [IsAuthenticated, IsHead] queryset = AuthorizationRequest.objects.all() + + +class AuthorizationRequestUnitUpdateView(generics.UpdateAPIView): + """ + Used by head approve or deny authorization request units. + """ + + http_method_names = ["patch"] + serializer_class = AuthorizationRequestUnitUpdateSerializer + permission_classes = [IsAuthenticated, IsHead] + queryset = AuthorizationRequestUnit.objects.all() diff --git a/docmanager_backend/config/management/commands/start_watcher.py b/docmanager_backend/config/management/commands/start_watcher.py index 25ac452..914b7ff 100644 --- a/docmanager_backend/config/management/commands/start_watcher.py +++ b/docmanager_backend/config/management/commands/start_watcher.py @@ -18,9 +18,8 @@ import logging import time from ollama import Client from pydantic import BaseModel -from datetime import date, datetime +from datetime import date from typing import Optional -import calendar class PDFHandler(FileSystemEventHandler): @@ -237,10 +236,10 @@ class PDFHandler(FileSystemEventHandler): # Open the file for instance creation DOCUMENT = Document.objects.filter( - name=filename.replace(".pdf", "")).first() + name=document_subject).first() if not DOCUMENT: DOCUMENT = Document.objects.create( - name=filename.replace(".pdf", ""), + name=document_subject, number_pages=num_pages, ocr_metadata=metadata, document_type=document_type, @@ -254,12 +253,13 @@ class PDFHandler(FileSystemEventHandler): name=filename, content=File(open(file_path, "rb"))) self.logger.info( - f"Document '{filename}' created successfully with type '{ + f"Document created successfully from '{filename}' with type '{ document_type}'. sent_from: {sent_from}, document_month: {document_month}, document_year: {document_year}" ) else: - self.logger.info(f"Document '{filename}' already exists.") + self.logger.info( + f"Document '{document_subject}' already exists.") os.remove(file_path) except Exception as e: diff --git a/docmanager_backend/document_requests/migrations/0005_alter_documentrequest_status.py b/docmanager_backend/document_requests/migrations/0005_alter_documentrequest_status.py new file mode 100644 index 0000000..fdc1e3c --- /dev/null +++ b/docmanager_backend/document_requests/migrations/0005_alter_documentrequest_status.py @@ -0,0 +1,28 @@ +# Generated by Django 5.1.3 on 2025-01-17 15:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("document_requests", "0004_rename_denied_remarks_documentrequest_remarks"), + ] + + operations = [ + migrations.AlterField( + model_name="documentrequest", + name="status", + field=models.CharField( + choices=[ + ("pending", "Pending"), + ("approved", "Approved"), + ("denied", "Denied"), + ("claimed", "Claimed"), + ("unclaimed", "Unclaimed"), + ], + default="pending", + max_length=32, + ), + ), + ] diff --git a/docmanager_backend/document_requests/models.py b/docmanager_backend/document_requests/models.py index 7c40f44..e6fb9cf 100644 --- a/docmanager_backend/document_requests/models.py +++ b/docmanager_backend/document_requests/models.py @@ -25,6 +25,8 @@ class DocumentRequest(models.Model): ("pending", "Pending"), ("approved", "Approved"), ("denied", "Denied"), + ("claimed", "Claimed"), + ("unclaimed", "Unclaimed"), ) remarks = models.TextField(max_length=512, blank=True, null=True) diff --git a/docmanager_backend/document_requests/serializers.py b/docmanager_backend/document_requests/serializers.py index 2472e16..18f4e70 100644 --- a/docmanager_backend/document_requests/serializers.py +++ b/docmanager_backend/document_requests/serializers.py @@ -182,23 +182,30 @@ class DocumentRequestUpdateSerializer(serializers.ModelSerializer): read_only_fields = ["id"] def update(self, instance, validated_data): - print(validated_data) - if instance.status == "denied" or instance.status == "approved": - raise serializers.ValidationError( - { - "error": "Already approved/denied requests cannot be updated. You should instead create a new request and approve it from there" - } - ) - elif "status" not in validated_data: + if "status" not in validated_data: raise serializers.ValidationError( { "error": "No status value update provided" } ) + elif instance.status == "denied" or instance.status == "claimed": + raise serializers.ValidationError( + { + "error": "Already claimed/denied requests cannot be updated. You should instead create a new request and approve it from there" + } + ) elif validated_data["status"] == instance.status: raise serializers.ValidationError( {"error": "Request form status provided is the same as current status"} ) + elif instance.status == "approved" and validated_data["status"] not in ["claimed", "unclaimed"]: + raise serializers.ValidationError( + {"error": "Approved request forms can only be marked as claimed or unclaimed"} + ) + elif instance.status == "unclaimed" and validated_data["status"] not in ["claimed"]: + raise serializers.ValidationError( + {"error": "Unclaimed request forms can only be marked as claimed"} + ) elif validated_data["status"] == "denied" and "remarks" not in validated_data: raise serializers.ValidationError( {"error": "Request denial requires remarks"} @@ -208,10 +215,11 @@ class DocumentRequestUpdateSerializer(serializers.ModelSerializer): # Send an email on request status update try: email = RequestUpdateEmail() - email.context = {"request_status": validated_data["status"]} if validated_data["status"] == "denied": + email.context = {"request_status": "denied"} email.context = {"remarks": validated_data["remarks"]} else: + email.context = {"request_status": "approved"} email.context = {"remarks": "N/A"} email.send(to=[instance.requester.email]) except: diff --git a/docmanager_backend/emails/templates.py b/docmanager_backend/emails/templates.py index 96f4699..17a37bb 100644 --- a/docmanager_backend/emails/templates.py +++ b/docmanager_backend/emails/templates.py @@ -7,7 +7,8 @@ class RequestUpdateEmail(email.BaseEmailMessage): def get_context_data(self): context = super().get_context_data() - context["request_status"] = context.get("request_status") + # Dirty fix since approved statuses don't seem to be read properly for some reason + context["request_status"] = context.get("request_status", "denied") context["remarks"] = context.get("remarks") context["url"] = FRONTEND_URL context.update(self.context) diff --git a/docmanager_backend/emails/templates/request_approved.html b/docmanager_backend/emails/templates/request_approved.html index 9244db5..b977b3b 100644 --- a/docmanager_backend/emails/templates/request_approved.html +++ b/docmanager_backend/emails/templates/request_approved.html @@ -1,11 +1,11 @@ {% load i18n %} {% block subject %} - {% blocktrans %}USTP - Document Request Form Update{% endblocktrans %} + {% blocktrans %}USTP - Request Form Update{% endblocktrans %} {% endblock %} {% block text_body %} - {% blocktrans %}You're receiving this email because your document request has been {{ request_status }}.{% endblocktrans %} + {% blocktrans %}You're receiving this email because your request form has been {{ request_status }}.{% endblocktrans %} {% blocktrans %}Remarks: {{ remarks }}{% endblocktrans %} @@ -17,7 +17,7 @@ {% block html_body %}

- {% blocktrans %}You're receiving this email because your document request has been {{ request_status }}.{% endblocktrans %} + {% blocktrans %}You're receiving this email because your request form has been {{ request_status }}.{% endblocktrans %}