Add API route to generate member's application PDF forms
This commit is contained in:
parent
e24de87557
commit
0c1f82a3c7
|
@ -1,9 +1,13 @@
|
||||||
from rest_framework.exceptions import ValidationError
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import io
|
||||||
|
from rest_framework.exceptions import ValidationError
|
||||||
from dateutil import relativedelta
|
from dateutil import relativedelta
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from bleach.sanitizer import Cleaner
|
from bleach.sanitizer import Cleaner
|
||||||
|
from PyPDF2 import PdfFileWriter, PdfFileReader
|
||||||
|
from reportlab.pdfgen import canvas
|
||||||
|
from reportlab.lib.pagesizes import letter
|
||||||
|
|
||||||
from django.db.models import Sum
|
from django.db.models import Sum
|
||||||
|
|
||||||
|
@ -239,3 +243,42 @@ def link_old_member(data, user):
|
||||||
for t in training:
|
for t in training:
|
||||||
t.user = user
|
t.user = user
|
||||||
t.save()
|
t.save()
|
||||||
|
|
||||||
|
|
||||||
|
BLANK_FORM = 'misc/blank_member_form.pdf'
|
||||||
|
def generate_application_pdf(member):
|
||||||
|
packet = io.BytesIO()
|
||||||
|
|
||||||
|
can = canvas.Canvas(packet, pagesize=letter)
|
||||||
|
can.drawRightString(580, 770, '{} {} ({})'.format(
|
||||||
|
member['first_name'],
|
||||||
|
member['last_name'],
|
||||||
|
member['id'],
|
||||||
|
))
|
||||||
|
can.drawString(34, 683, member['first_name'])
|
||||||
|
can.drawString(218, 683, member['last_name'])
|
||||||
|
can.drawString(403, 683, member['preferred_name'])
|
||||||
|
can.drawString(34, 654, member['street_address'])
|
||||||
|
can.drawString(275, 654, member['city'])
|
||||||
|
can.drawString(459, 654, member['postal_code'])
|
||||||
|
can.drawString(34, 626, member['email'])
|
||||||
|
can.drawString(332, 626, member['phone'])
|
||||||
|
can.drawString(34, 570, member['emergency_contact_name'])
|
||||||
|
can.drawString(332, 570, member['emergency_contact_phone'])
|
||||||
|
can.save()
|
||||||
|
|
||||||
|
packet.seek(0)
|
||||||
|
new_pdf = PdfFileReader(packet)
|
||||||
|
existing_pdf = PdfFileReader(open(BLANK_FORM, 'rb'))
|
||||||
|
output = PdfFileWriter()
|
||||||
|
page = existing_pdf.getPage(0)
|
||||||
|
page.mergePage(new_pdf.getPage(0))
|
||||||
|
output.addPage(page)
|
||||||
|
page = existing_pdf.getPage(1)
|
||||||
|
output.addPage(page)
|
||||||
|
page = existing_pdf.getPage(2)
|
||||||
|
output.addPage(page)
|
||||||
|
|
||||||
|
outputStream = io.BytesIO()
|
||||||
|
output.write(outputStream)
|
||||||
|
return outputStream
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
from django.contrib.auth.models import User, Group
|
from django.contrib.auth.models import User, Group
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.db.models import Max
|
from django.db.models import Max
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.core.files.base import File
|
||||||
from rest_framework import viewsets, views, mixins, generics, exceptions
|
from rest_framework import viewsets, views, mixins, generics, exceptions
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.permissions import BasePermission, IsAuthenticated, SAFE_METHODS
|
from rest_framework.permissions import BasePermission, IsAuthenticated, SAFE_METHODS
|
||||||
|
@ -110,7 +112,7 @@ class MemberViewSet(Base, Retrieve, Update):
|
||||||
def pause(self, request, pk=None):
|
def pause(self, request, pk=None):
|
||||||
if not is_admin_director(self.request.user):
|
if not is_admin_director(self.request.user):
|
||||||
raise exceptions.PermissionDenied()
|
raise exceptions.PermissionDenied()
|
||||||
member = get_object_or_404(self.queryset, pk=pk)
|
member = self.get_object()
|
||||||
member.paused_date = datetime.date.today()
|
member.paused_date = datetime.date.today()
|
||||||
member.save()
|
member.save()
|
||||||
return Response(200)
|
return Response(200)
|
||||||
|
@ -119,13 +121,20 @@ class MemberViewSet(Base, Retrieve, Update):
|
||||||
def unpause(self, request, pk=None):
|
def unpause(self, request, pk=None):
|
||||||
if not is_admin_director(self.request.user):
|
if not is_admin_director(self.request.user):
|
||||||
raise exceptions.PermissionDenied()
|
raise exceptions.PermissionDenied()
|
||||||
member = get_object_or_404(self.queryset, pk=pk)
|
member = self.get_object()
|
||||||
member.current_start_date = datetime.date.today()
|
member.current_start_date = datetime.date.today()
|
||||||
member.paused_date = None
|
member.paused_date = None
|
||||||
member.save()
|
member.save()
|
||||||
utils.tally_membership_months(member)
|
utils.tally_membership_months(member)
|
||||||
return Response(200)
|
return Response(200)
|
||||||
|
|
||||||
|
@action(detail=True)
|
||||||
|
def forms(self, request, pk=None):
|
||||||
|
member = self.get_object()
|
||||||
|
serializer = self.get_serializer(member)
|
||||||
|
form = utils.generate_application_pdf(serializer.data)
|
||||||
|
return HttpResponse(File(form), content_type='application/pdf')
|
||||||
|
|
||||||
|
|
||||||
class CardViewSet(Base, Create, Retrieve, Update, Destroy):
|
class CardViewSet(Base, Create, Retrieve, Update, Destroy):
|
||||||
permission_classes = [AllowMetadata | IsAuthenticated, IsObjOwnerOrAdmin]
|
permission_classes = [AllowMetadata | IsAuthenticated, IsObjOwnerOrAdmin]
|
||||||
|
|
|
@ -343,6 +343,18 @@ Pausing / Unpausing Member
|
||||||
|
|
||||||
:status 200:
|
:status 200:
|
||||||
|
|
||||||
|
Member PDF Forms
|
||||||
|
++++++++++++++++
|
||||||
|
|
||||||
|
.. http:get:: /members/(id)/forms/
|
||||||
|
|
||||||
|
Generate member's application PDF forms. Users can only view their own,
|
||||||
|
admins can view anyone's.
|
||||||
|
|
||||||
|
:param id:
|
||||||
|
|
||||||
|
:requestheader Authorization: ``Token <token>``
|
||||||
|
|
||||||
|
|
||||||
Search
|
Search
|
||||||
------
|
------
|
||||||
|
|
BIN
apiserver/misc/blank_member_form.pdf
Normal file
BIN
apiserver/misc/blank_member_form.pdf
Normal file
Binary file not shown.
|
@ -23,10 +23,12 @@ Pillow==7.0.0
|
||||||
pycparser==2.19
|
pycparser==2.19
|
||||||
Pygments==2.5.2
|
Pygments==2.5.2
|
||||||
pyparsing==2.4.6
|
pyparsing==2.4.6
|
||||||
|
PyPDF2==1.26.0
|
||||||
python-dateutil==2.8.1
|
python-dateutil==2.8.1
|
||||||
python-Levenshtein==0.12.0
|
python-Levenshtein==0.12.0
|
||||||
python3-openid==3.1.0
|
python3-openid==3.1.0
|
||||||
pytz==2019.3
|
pytz==2019.3
|
||||||
|
reportlab==3.5.34
|
||||||
requests==2.22.0
|
requests==2.22.0
|
||||||
requests-oauthlib==1.3.0
|
requests-oauthlib==1.3.0
|
||||||
six==1.13.0
|
six==1.13.0
|
||||||
|
|
Loading…
Reference in New Issue
Block a user