Skip to content
Snippets Groups Projects
Commit 8207c5c6 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

Merge branch 'hotfix/voucher_templates' into 'master'

Hotfix/voucher templates

Closes #266 and #267

See merge request NCER-PD/scheduling-system!185
parents 6a3aeac5 e86ee025
No related branches found
No related tags found
1 merge request!185Hotfix/voucher templates
Pipeline #7348 passed
......@@ -460,7 +460,7 @@ class smashProvider(BaseProvider):
phone_number = self.fake.phone_number()
if social_security_number is None:
social_security_number = self.fake.ean(length=8)
social_security_number = ''
if sex is None:
sex = self.fake.word(
......@@ -534,7 +534,7 @@ class smashProvider(BaseProvider):
def createSmashWorker(self, first_name=None, last_name=None, username=None, email=None,
specialization=None, unit=None, phone_number=None, password='password1234', role=None,
locations=None, languages=None):
locations=None, languages=None, is_super=False):
'''
first_name: string: Sets the first_name. By default None. Random values are generated. Provide a value to overwrite random generation
last_name: string: Sets the last_name. By default None. Random values are generated. Provide a value to overwrite random generation
......@@ -578,6 +578,12 @@ class smashProvider(BaseProvider):
user = self.createSmashUser(
username=username, email=email, password=password)
if is_super:
user.is_superuser = True
user.is_staff = True
user.is_admin = True
user.save()
# create worker
defaults = {'first_name': first_name, 'last_name': last_name,
'email': email, 'unit': unit, 'specialization': specialization,
......@@ -712,4 +718,4 @@ if __name__ == "__main__":
fake.createSmashAppointments()
fake.createSmashWorker(first_name=u'System', last_name=u'Admin',
email=u'carlos.vega@uni.lu', role=ROLE_CHOICES_TECHNICIAN, password='smashtest007',
locations=fake.getAllCreatedLocations(), languages=fake.getAllCreatedLanguages())
locations=fake.getAllCreatedLocations(), languages=fake.getAllCreatedLanguages(), is_super=True)
......@@ -5,10 +5,13 @@ import django
from django.conf import settings
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "smash.settings")
django.setup()
from smash.local_settings import MEDIA_ROOT
from shutil import copyfile
import pandas as pd
import numpy as np
import logging
import datetime
from dateutil.relativedelta import relativedelta
import re
from operator import itemgetter
from collections import OrderedDict, defaultdict
......@@ -28,6 +31,19 @@ DEFAULT_LOCATION = 'CHL'
DEFAULT_LOCATION_PREFIX = 'P'
date_regex = re.compile(r'\d{1,2}\.\d{1,2}\.\d{4}')
language_base_dir = 'web/static/flags/'
language_flags = {
'French': 'FR.png',
'English': 'GB.png',
'Finnish': 'FI.png',
'Italian': 'IT.png',
'Spanish': 'ES.png',
'Portuguese': 'PT.png',
'Luxembourgish': 'LU.png',
'German': 'DE.png',
'Dutch': 'NL.png'
}
def get_new_screening_number(screening_number_prefix):
result_number = 0
subjects = StudySubject.objects.filter(screening_number__contains=screening_number_prefix)
......@@ -266,9 +282,9 @@ def add_subject_vouchers(voucher_reference, referral, voucher_types):
nd_number, date, voucher_partner, voucher_type, num = voucher_reference.split('-')
nd_number = nd_number.upper().replace('ND', 'PDP')
issue_date = datetime.datetime.strptime(date, '%Y%m%d')
expiry_date = issue_date + datetime.timedelta(days=365)
expiry_date = issue_date + relativedelta(months=+6)
usage_partner, created = Worker.objects.update_or_create(
name=voucher_partners.get(voucher_partner, voucher_partner))
name=voucher_partners.get(voucher_partner, voucher_partner), last_name=voucher_partners.get(voucher_partner, voucher_partner), voucher_partner_code=voucher_partner[0].upper())
usage_partner.roles.update(role=ROLE_CHOICES_VOUCHER_PARTNER)
# create workerStudyRole
workerStudyRole, _ = WorkerStudyRole.objects.update_or_create(worker=usage_partner,
......@@ -326,8 +342,19 @@ def parse_row(index, row, visit_columns, appointmentTypes, voucher_types):
languages.append(lang)
if created:
logging.warn('New Language added: {}'.format(language))
lang.save()
if language in language_flags:
src = os.path.join(language_base_dir,
language_flags[language])
basename = os.path.basename(src)
dst = os.path.join(MEDIA_ROOT, basename)
copyfile(src, dst)
# .save(basename, File(open(dst, 'rb'))) #SimpleUploadedFile(name=path, content=open(path, 'rb').read(), content_type='image/png')
lang.image = basename
lang.save()
for language in row['PREFERED WRITEN LANGUAGE'][:1]:
pref_lang, created = Language.objects.get_or_create(name=language
,locale=locale_table.get(language,(None, None))[0])
......
from django import forms
from django.forms import ModelForm
from web.models import MailTemplate
import logging
logger = logging.getLogger(__name__)
class MailTemplateForm(ModelForm):
class Meta:
model = MailTemplate
fields = '__all__'
def __init__(self, *args, **kwargs):
super(MailTemplateForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
self.fields['Multilingual'] = forms.BooleanField(label='Multilingual', disabled=True, required=False,
help_text='Only for voucher context. Check this option if the voucher template is multilingual.',
widget=forms.CheckboxInput(attrs={'class': 'hidden_form_field', 'id': 'multilingual_checkbox'}))
def clean(self):
cleaned_data = super(MailTemplateForm, self).clean()
return cleaned_data
\ No newline at end of file
import datetime
from dateutil.relativedelta import relativedelta
import logging
from django import forms
......@@ -68,7 +69,7 @@ class VoucherForm(ModelForm):
instance = super(VoucherForm, self).save(commit=False)
if not instance.id:
instance.issue_date = timezone.now()
instance.expiry_date = instance.issue_date + datetime.timedelta(days=90)
instance.expiry_date = instance.issue_date + relativedelta(months=+instance.study_subject.study.default_voucher_expiration_in_months)
max_id = str(1).zfill(5)
if Voucher.objects.all().count() > 0:
max_id = str(Voucher.objects.latest('id').id + 1).zfill(4)
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2018-11-09 15:47
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('web', '0130_study_visits_to_show_in_subject_list'),
]
operations = [
migrations.AddField(
model_name='study',
name='default_voucher_expiration_in_months',
field=models.IntegerField(default=3, validators=[django.core.validators.MinValueValidator(1)], verbose_name=b'Default duration of the vouchers in months'),
),
]
......@@ -38,6 +38,12 @@ class Study(models.Model):
validators=[MaxValueValidator(100), MinValueValidator(1)]
)
default_voucher_expiration_in_months = models.IntegerField(
verbose_name='Default duration of the vouchers in months',
default=3,
validators=[MinValueValidator(1)]
)
def check_nd_number(self, nd_number):
regex = re.compile(self.nd_number_study_subject_regex)
return regex.match(nd_number) is not None
......
......@@ -19,7 +19,7 @@ class VoucherType(models.Model):
)
def __str__(self):
return "%s" % self.code
return "%s (%s)" % (self.code, self.description)
def __unicode__(self):
return "%s" % self.code
return u'{} ({})'.format(self.code, self.description)
\ No newline at end of file
......@@ -9,7 +9,7 @@
><i class="fa fa-plus-circle text-success"></i></a></h3>
</div>
<div class="box-body">
<table class="table table-bordered table-striped">
<table class="table table-bordered table-striped voucher_table">
<thead>
<tr>
......@@ -42,8 +42,18 @@
</tbody>
</table>
{% if subject.vouchers.all.count > 0 %}
<a href="#" data-url="{% url "web.views.mail_template_generate_for_vouchers" %}" onclick='
<a id="print_vouchers_button" href="#" data-url="{% url "web.views.mail_template_generate_for_vouchers" %}" onclick='
var checkboxes = $(".voucher_checkbox");
if($(".voucher_checkbox:checked").length == 0){
$("#print_vouchers_button").tooltip({title: "Please, select at least one voucher to print.", placement: "right", trigger: "manual"});
$("#print_vouchers_button").tooltip("show");
setTimeout(function() {
$("#print_vouchers_button").tooltip("destroy");
}, 2000);
return false;
}
var url = $(this).data("url")+"?voucher_id=";
for (var i=0;i<checkboxes.length;i++){
......@@ -59,4 +69,4 @@
</div>
</div>
</div>
</div>
\ No newline at end of file
......@@ -5,7 +5,11 @@
{% block styles %}
{{ block.super }}
<link rel="stylesheet" href="{% static 'AdminLTE/plugins/awesomplete/awesomplete.css' %}"/>
<style type="text/css">
.help_text{
margin-left: 5px;
}
</style>
{% endblock styles %}
{% block ui_active_tab %}'subjects'{% endblock ui_active_tab %}
......@@ -34,6 +38,9 @@
<div class="form-group {% if field.errors %}has-error{% endif %}">
<label class="col-sm-4 col-lg-offset-1 col-lg-2 control-label">
{{ field.label }}
{% if field.help_text %}
<i class="fa fa-info-circle help_text" aria-hidden="true" data-toggle="tooltip" data-placement="top" title="{{field.help_text}}"></i>
{% endif %}
</label>
<div class="col-sm-8 col-lg-4">
......@@ -72,5 +79,54 @@
{{ block.super }}
<script src="{% static 'AdminLTE/plugins/awesomplete/awesomplete.min.js' %}"></script>
<script type="text/javascript">
function should_be_checked(){
var ischecked = $('#multilingual_checkbox').is(":checked");
var hasnolang = $('#id_language').prop("selectedIndex") == 0;
var isvoucher = $('#id_context').find(":selected").text().toLowerCase() == 'voucher';
if(hasnolang && isvoucher && !ischecked){ //if has no language and is voucher, then is multilingual
$('#multilingual_checkbox').attr('checked', true);
$('#multilingual_checkbox').prop('checked', true);
$('#multilingual_checkbox').attr('disabled', true);
}
}
function on_context_or_language_change(){
var hasnoleng = $('#id_language').prop("selectedIndex") == 0;
var isvoucher = $('#id_context').find(":selected").text().toLowerCase() == 'voucher';
if(isvoucher && hasnoleng){
$('#multilingual_checkbox').attr('disabled', true);
$('#multilingual_checkbox').attr('checked', true);
$('#multilingual_checkbox').prop('checked', true);
}else if(isvoucher && !hasnoleng){
$('#multilingual_checkbox').attr('disabled', false);
$('#multilingual_checkbox').attr('checked', false);
$('#multilingual_checkbox').prop('checked', false);
}else{
$('#multilingual_checkbox').attr('disabled', true);
$('#multilingual_checkbox').attr('checked', false);
$('#multilingual_checkbox').prop('checked', false);
}
}
function on_checkbox_change(){
var ischecked = $('#multilingual_checkbox').is(":checked");
if(ischecked){ //is because has no leng and is voucher
$('#id_language').prop("selectedIndex", 0);
$('#multilingual_checkbox').attr('disabled', true);
}
}
$('#id_language').on('change', on_context_or_language_change);
$('#id_context').on('change', on_context_or_language_change);
$('#multilingual_checkbox').on('change', on_checkbox_change);
$(document).ready(should_be_checked);
</script>
{% endblock scripts %}
\ No newline at end of file
File added
......@@ -158,11 +158,11 @@ urlpatterns = [
####################
url(r'^mail_templates$', views.mails.MailTemplatesListView.as_view(), name='web.views.mail_templates'),
url(r'^mail_templates/add$', views.mails.MailTemplatesCreateView.as_view(), name='web.views.mail_template_add'),
url(r'^mail_templates/(?P<pk>\d+)/delete$', views.mails.MailTemplatesDeleteView.as_view(),
name='web.views.mail_template_delete'),
url(r'^mail_templates/(?P<pk>\d+)/edit$', views.mails.MailTemplatesEditView.as_view(),
name='web.views.mail_template_edit'),
url(r'^mail_templates/add$', views.mails.mail_template_add, name='web.views.mail_template_add'),
url(r'^mail_templates/(?P<pk>\d+)/edit$', views.mails.mail_template_edit, name='web.views.mail_template_edit'),
url(r'^mail_templates/(?P<pk>\d+)/delete$', views.mails.MailTemplatesDeleteView.as_view(), name='web.views.mail_template_delete'),
url(r'^mail_templates/(?P<mail_template_id>\d+)/generate/(?P<instance_id>\d+)$', views.mails.generate,
name="web.views.mail_template_generate"),
url(r'^mail_templates/print_vouchers$', views.mails.generate_for_vouchers,
......
......@@ -17,6 +17,10 @@ from ..models import StudySubject, Visit, Appointment, MailTemplate, Voucher
from ..models.constants import MAIL_TEMPLATE_CONTEXT_SUBJECT, MAIL_TEMPLATE_CONTEXT_VISIT, \
MAIL_TEMPLATE_CONTEXT_APPOINTMENT, MAIL_TEMPLATE_CONTEXT_VOUCHER
from ..forms.mail_template import MailTemplateForm
from . import wrap_response
from django.shortcuts import redirect, get_object_or_404
MIMETYPE_DOCX = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
CONTEXT_TYPES_MAPPING = {
......@@ -42,14 +46,28 @@ class MailTemplatesListView(ListView, WrappedView):
}
return context
class MailTemplatesCreateView(CreateView, WrappedView):
model = MailTemplate
template_name = "mail_templates/add.html"
fields = '__all__'
success_url = reverse_lazy('web.views.mail_templates')
success_message = "Template created"
def mail_template_add(request):
if request.method == 'POST':
form = MailTemplateForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('web.views.mail_templates')
else:
form = MailTemplateForm()
return wrap_response(request, 'mail_templates/add.html', {'form': form})
def mail_template_edit(request, pk):
template = get_object_or_404(MailTemplate, pk=pk)
if request.method == 'POST':
form = MailTemplateForm(request.POST, request.FILES, instance=template)
if form.is_valid():
form.save()
return redirect('web.views.mail_templates')
else:
form = MailTemplateForm(instance=template)
return wrap_response(request, 'mail_templates/edit.html', {'form': form, 'mail_template': template})
class MailTemplatesDeleteView(DeleteView, WrappedView):
model = MailTemplate
......@@ -60,16 +78,6 @@ class MailTemplatesDeleteView(DeleteView, WrappedView):
messages.success(request, "Template deleted")
return super(MailTemplatesDeleteView, self).delete(request, *args, **kwargs)
class MailTemplatesEditView(UpdateView, WrappedView):
model = MailTemplate
success_url = reverse_lazy('web.views.mail_templates')
fields = '__all__'
success_message = "Template edited"
template_name = "mail_templates/edit.html"
context_object_name = "mail_template"
def generate(request, mail_template_id, instance_id):
mail_template = get_object_or_404(MailTemplate, id=mail_template_id)
instance = get_object_or_404(CONTEXT_TYPES_MAPPING[mail_template.context], id=instance_id)
......@@ -82,7 +90,6 @@ def generate(request, mail_template_id, instance_id):
response['Content-Disposition'] = 'attachment; filename={}.docx'.format(mail_template.name)
return response
def generate_for_vouchers(request):
ids = request.GET.get('voucher_id', '').split(',')
vouchers = []
......@@ -101,6 +108,9 @@ def generate_for_vouchers(request):
input_stream.seek(0)
inputs.append(input_stream)
if len(inputs) == 0:
return redirect(request.META.get('HTTP_REFERER', 'web.views.subjects'))
merge_files(inputs, output_stream)
file_size = output_stream.tell()
output_stream.seek(0)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment