Skip to content

Commit

Permalink
Add user interface for DBreceipts (#3521)
Browse files Browse the repository at this point in the history
* Fix default dbreceipts

* Add receipts form to settings page

* Clean up form handling, add help text, and fix text comparison

* lint fix

* Fix template rendering

* Fix fullwidth on fruitsalad

* Fix context for confirmation receipt

* Fix receipt handling and cancelreg button

* Add receipts to program management page info
  • Loading branch information
willgearty authored May 4, 2022
1 parent 816d26d commit 9fc5a3d
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 66 deletions.
8 changes: 5 additions & 3 deletions esp/esp/program/controllers/confirmation.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
from esp.users.models import ESPUser, Record
from esp.program.modules.module_ext import DBReceipt

from django.template import Template
from django.template import Template, Context
from django.template.loader import select_template
from esp.dbmail.models import send_mail

Expand All @@ -52,10 +52,12 @@ def send_confirmation_email(self, user, program, repeat=False, override=False):
if (created or repeat) and (options.send_confirmation or override):
try:
receipt_template = Template(DBReceipt.objects.get(program=program, action='confirmemail').receipt)
receipt_text = receipt_template.render(Context({'user': user, 'program': program}))
except:
receipt_template = select_template(['program/confemails/%s_confemail.txt' %(program.id),'program/confirm_email.txt'])
receipt_template = select_template(['program/confemails/%s_confemail.txt' %(program.id),'program/confemails/default.txt'])
receipt_text = receipt_template.render({'user': user, 'program': program})
send_mail("Thank you for registering for %s!" %(program.niceName()), \
receipt_template.render({'user': user, 'program': program}), \
receipt_text, \
(ESPUser.email_sendto_address(program.director_email, program.niceName() + " Directors")), \
[user.email], True)

59 changes: 58 additions & 1 deletion esp/esp/program/modules/forms/admincore.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from decimal import Decimal
from django import forms
from django.contrib import admin
from django.template.loader import select_template
from django.utils.safestring import mark_safe
from form_utils.forms import BetterForm, BetterModelForm

Expand All @@ -9,7 +10,7 @@
from esp.program.controllers.lunch_constraints import LunchConstraintGenerator
from esp.program.forms import ProgramCreationForm
from esp.program.models import RegistrationType, Program
from esp.program.modules.module_ext import ClassRegModuleInfo, StudentClassRegModuleInfo
from esp.program.modules.module_ext import ClassRegModuleInfo, StudentClassRegModuleInfo, DBReceipt
from esp.tagdict import all_program_tags, tag_categories
from esp.tagdict.models import Tag

Expand Down Expand Up @@ -111,6 +112,62 @@ class Meta:
]# Here you can also add description for each fieldset.
model = StudentClassRegModuleInfo

class ReceiptsForm(BetterForm):
confirm = forms.CharField(widget=forms.Textarea(attrs={'class': 'fullwidth'}),
help_text = "This receipt is shown on the website when a student clicks the 'confirm registration' button.\
If no text is supplied, the default text will be used.",
required = False)
confirmemail = forms.CharField(widget=forms.Textarea(attrs={'class': 'fullwidth'}),
help_text = "This receipt is sent via email when a student clicks the 'confirm registration' button.\
If no text is supplied, the default text will be used.",
required = False)
cancel = forms.CharField(widget=forms.Textarea(attrs={'class': 'fullwidth'}),
help_text = "This receipt is shown on the website when a student clicks the 'cancel registration' button.\
If no text is supplied, the student will be redirected to the main student registration page instead.",
required = False)

def __init__(self, *args, **kwargs):
self.program = kwargs.pop('program')
super(ReceiptsForm, self).__init__(*args, **kwargs)
for action in ['confirm', 'confirmemail', 'cancel']:
receipts = DBReceipt.objects.filter(program=self.program, action=action)
if receipts.count() > 0:
receipt_text = receipts.latest('id').receipt
elif action == "confirm":
template = select_template(['program/receipts/%s_custom_receipt.html' %(self.program.id), 'program/receipts/default.html'])
receipt_text = open(template.origin.name, 'r').read().encode('UTF-8')
elif action == "confirmemail":
template = select_template(['program/confemails/%s_confemail.txt' %(self.program.id),'program/confemails/default.txt'])
receipt_text = open(template.origin.name, 'r').read().encode('UTF-8')
else:
receipt_text = "".encode('UTF-8')
self.fields[action].initial = receipt_text

def save(self):
for action in ['confirm', 'confirmemail', 'cancel']:
receipts = DBReceipt.objects.filter(program=self.program, action=action)
cleaned_text = self.cleaned_data[action].replace('\r\n', '\n').strip() # Use unix line endings and strip whitespace just in case
if cleaned_text == "":
receipts.delete()
else:
if action == "confirm":
template = select_template(['program/receipts/%s_custom_receipt.html' %(self.program.id), 'program/receipts/default.html'])
default_text = open(template.origin.name, 'r').read().strip()
elif action == "confirmemail":
template = select_template(['program/confemails/%s_confemail.txt' %(self.program.id),'program/confemails/default.txt'])
default_text = open(template.origin.name, 'r').read().strip()
elif action == "cancel":
default_text = ""
if cleaned_text == default_text:
receipts.delete()
else:
receipt, created = DBReceipt.objects.get_or_create(program=self.program, action=action)
receipt.receipt = cleaned_text
receipt.save()

class Meta:
fieldsets = [('Student Registration Receipts', {'fields': ['confirm', 'confirmemail', 'cancel']})]

class ProgramTagSettingsForm(BetterForm):
""" Form for changing tags associated with a program. """
def __init__(self, *args, **kwargs):
Expand Down
48 changes: 29 additions & 19 deletions esp/esp/program/modules/handlers/admincore.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,14 @@ def main(self, request, tl, one, two, module, extra, prog):
@aux_call
@needs_admin
def settings(self, request, tl, one, two, module, extra, prog):
from esp.program.modules.forms.admincore import ProgramSettingsForm, TeacherRegSettingsForm, StudentRegSettingsForm
from esp.program.modules.forms.admincore import ProgramSettingsForm, TeacherRegSettingsForm, StudentRegSettingsForm, ReceiptsForm
context = {}
submitted_form = ""
crmi = ClassRegModuleInfo.objects.get(program=prog)
scrmi = StudentClassRegModuleInfo.objects.get(program=prog)
old_url = prog.url
context['open_section'] = extra
forms = {}

#If one of the forms was submitted, process it and save if valid
if request.method == 'POST':
Expand All @@ -143,29 +144,34 @@ def settings(self, request, tl, one, two, module, extra, prog):
form.save()
#If the url for the program is now different, redirect to the new settings page
if prog.url is not old_url:
return HttpResponseRedirect( '/manage/%s/settings' % (prog.url))
prog_form = form
return HttpResponseRedirect( '/manage/%s/settings/program' % (prog.url))
else:
forms['program'] = form
context['open_section'] = "program"
elif submitted_form == "crmi":
form = TeacherRegSettingsForm(request.POST, instance = crmi)
if form.is_valid():
form.save()
crmi_form = form
else:
forms['crmi'] = form
context['open_section'] = "crmi"
elif submitted_form == "scrmi":
form = StudentRegSettingsForm(request.POST, instance = scrmi)
if form.is_valid():
form.save()
scrmi_form = form
else:
forms['scrmi'] = form
context['open_section'] = "scrmi"
if form.is_valid():
form.save()
#If the url for the program is now different, redirect to the new settings page
if prog.url is not old_url:
return HttpResponseRedirect( '/manage/%s/settings/%s' % (prog.url, context['open_section']))
elif submitted_form == "receipts":
form = ReceiptsForm(request.POST, program = prog)
if form.is_valid():
form.save()
else:
forms['receipts'] = form
context['open_section'] = "receipts"

#Set up any other forms on the page
if submitted_form != "program":
if "program" not in forms:
prog_dict = {}
prog_dict.update(model_to_dict(prog))
#We need to populate all of these manually
Expand All @@ -176,21 +182,25 @@ def settings(self, request, tl, one, two, module, extra, prog):
line_items = pac.get_lineitemtypes(required_only=True).filter(text="Program admission").values('amount_dec')
prog_dict['base_cost'] = int(sum(x["amount_dec"] for x in line_items))
prog_dict["sibling_discount"] = prog.sibling_discount
prog_form = ProgramSettingsForm(prog_dict, instance = prog)
forms['program'] = ProgramSettingsForm(prog_dict, instance = prog)

if "crmi" not in forms:
forms['crmi'] = TeacherRegSettingsForm(instance = crmi)

if submitted_form != "crmi":
crmi_form = TeacherRegSettingsForm(instance = crmi)
if "scrmi" not in forms:
forms['scrmi'] = StudentRegSettingsForm(instance = scrmi)

if submitted_form != "scrmi":
scrmi_form = StudentRegSettingsForm(instance = scrmi)
if "receipts" not in forms:
forms['receipts'] = ReceiptsForm(program = prog)

context['one'] = one
context['two'] = two
context['program'] = prog
context['forms'] = [
("Program Settings", "program", prog_form),
("Teacher Registration Settings", "crmi", crmi_form),
("Student Registration Settings", "scrmi", scrmi_form),
("Program Settings", "program", forms['program']),
("Teacher Registration Settings", "crmi", forms['crmi']),
("Student Registration Settings", "scrmi", forms['scrmi']),
("Registration Receipts", "receipts", forms['receipts'])
]

return render_to_response(self.baseDir()+'settings.html', request, context)
Expand Down
21 changes: 9 additions & 12 deletions esp/esp/program/modules/handlers/studentregcore.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
from datetime import datetime
from django.db import models
from django.contrib import admin
from django.template import Template
from esp.middleware.threadlocalrequest import AutoRequestContext as Context
from django.template import Template, Context
from esp.middleware.threadlocalrequest import AutoRequestContext
from django.http import HttpResponse
from django.template.loader import render_to_string, get_template, select_template
import operator
Expand Down Expand Up @@ -207,18 +207,15 @@ def confirmreg_forreal(self, request, tl, one, two, module, extra, prog, new_reg
cfe = ConfirmationEmailController()
cfe.send_confirmation_email(request.user, self.program)

context["request"] = request
context["program"] = prog

try:
receipt_text = DBReceipt.objects.get(program=self.program, action='confirm').receipt
context["request"] = request
context["program"] = prog
return HttpResponse( Template(receipt_text).render( Context(context, autoescape=False) ) )
return HttpResponse( Template(receipt_text).render( Context(context) ) )
except DBReceipt.DoesNotExist:
try:
receipt = 'program/receipts/'+str(prog.id)+'_custom_receipt.html'
return render_to_response(receipt, request, context)
except:
receipt = 'program/receipts/default.html'
return render_to_response(receipt, request, context)
receipt = select_template(['program/receipts/%s_custom_receipt.html' %(prog.id), 'program/receipts/default.html'])
return HttpResponse( receipt.render( AutoRequestContext(context, autoescape=False) ) )

@aux_call
@needs_student
Expand Down Expand Up @@ -252,7 +249,7 @@ def cancelreg(self, request, tl, one, two, module, extra, prog):
context = {}
context["request"] = request
context["program"] = prog
return HttpResponse( Template(receipt_text).render( Context(context, autoescape=False) ) )
return HttpResponse( Template(receipt_text).render( Context(context) ) )
except:
return self.goToCore(tl)

Expand Down
4 changes: 0 additions & 4 deletions esp/esp/themes/theme_data/fruitsalad/less/main.less
Original file line number Diff line number Diff line change
Expand Up @@ -649,10 +649,6 @@ color: #fff;
font-size: 12pt;
text-decoration: none;
}
.fullwidth {
width: 560px;
margin: auto;
}

/*
* Admin Toolbar
Expand Down
20 changes: 0 additions & 20 deletions esp/templates/program/confemails/41_confemail.txt

This file was deleted.

7 changes: 7 additions & 0 deletions esp/templates/program/confemails/default.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Dear {{ user.first_name }},

Thank you for registering for {{ program.niceName }}! This is a preliminary confirmation email for your {{ program.program_type }} registration; you can come back and change your classes until registration closes. We will contact you via email with further information.

{{ program.niceName }} Directors


2 changes: 1 addition & 1 deletion esp/templates/program/modules/admincore/directory.html
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ <h1>Admin Portal for {{ program.niceName }} (ID: {{ program.id }})</h1>
{% if manage_lunch_constraints %}<li><a href="/manage/{{ program.getUrlBase }}/lunch_constraints">Lunch Constraints</a>: Rules for your students' schedules</li>{% endif %}
{% if manage_registrationtype_management %}<li><a href="/manage/{{ program.getUrlBase }}/registrationtype_management">Student Registration Types</a>: What students see on their schedule after a lottery</li>{% endif %}
{% if manage_surveys %}<li><a href="/manage/{{ program.getUrlBase }}/surveys">View and Manage Surveys</a>: Create new surveys, edit existing surveys, and review survey results</li>{% endif %}
{% if manage_settings %}<li><a href="/manage/{{ program.getUrlBase }}/settings/">Modify Settings for This Program</a>: Emails, program caps and modules, class categories, and flag types</li>{% endif %}
{% if manage_settings %}<li><a href="/manage/{{ program.getUrlBase }}/settings/">Modify Settings for This Program</a>: Emails, program caps and modules, class categories, flag types, and registration receipts</li>{% endif %}
{% if manage_tags %}<li><a href="/manage/{{ program.getUrlBase }}/tags">Modify Tag Settings for This Program</a>: Generic miscellaneous settings, for experts only</li>{% endif %}
</ul>
</div>
Expand Down
4 changes: 2 additions & 2 deletions esp/templates/program/modules/admincore/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ <h1>Program Settings for {{ program.niceName }} (ID: {{ program.id }})</h1>
{% if fieldset.description %}
<p class="description">{{ fieldset.description }}</p>
{% endif %}
<table class="contact">
<table class="contact fullwidth">
{% for field in fieldset %}

<tr>
Expand Down Expand Up @@ -74,7 +74,7 @@ <h1>Program Settings for {{ program.niceName }} (ID: {{ program.id }})</h1>
<table align="center">
<tr>
<td colspan="2" class="submit">
<br /><br /><br />
<br />
<center><input class="fancybutton" type="submit" value="Save {{ title }}" onclick="questionsToModules();" /></center>
</td>
</tr>
Expand Down
6 changes: 2 additions & 4 deletions esp/templates/program/modules/studentregcore/mainpage.html
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@ <h1>Student registration for {{program.niceName}} </h1>
{% load render_qsd %}
{% render_inline_program_qsd program "learn:studentreg" %}

<form action="/learn/{{one}}/{{two}}/confirmreg" method="post">

{% for module in modules %}
{% if module.useTemplate %}
<a name="module-{{module.id}}"></a>
Expand Down Expand Up @@ -115,12 +113,12 @@ <h1>Student registration for {{program.niceName}} </h1>
<center>
<a name="confirmreg"></a>
{% if program.isFull and program.program_allow_waitlist and not isConfirmed %}
</form>
<form action="/learn/{{one}}/{{two}}/waitlist_subscribe" method="post">
<input class="button" type="submit" value="Join Waiting List"/>
</form>
{% else %}
{% if can_confirm %}
<form action="/learn/{{one}}/{{two}}/confirmreg" method="post">
{# disable if (you haven't completed all requirements) OR (you can't register for the program because it's full) #}
{% if not completedAll or program.isFull and not canRegToFullProgram and not isConfirmed %}
<button id="confirmbutton" type="submit"
Expand All @@ -141,7 +139,7 @@ <h1>Student registration for {{program.niceName}} </h1>
{% endif %}
</button>
{% endif %}
</form>
</form>
{% if isConfirmed or scrmi.cancel_button_dereg %}{% if not have_paid %}
<form action="/learn/{{one}}/{{two}}/cancelreg" method="get" onsubmit="return submit_cancel();" >
<button type="submit" id="cancelbutton" class="btn btn-danger btn-large">
Expand Down

0 comments on commit 9fc5a3d

Please sign in to comment.