Compare commits

...

4 Commits

9 changed files with 95 additions and 31 deletions

View File

@@ -321,45 +321,60 @@ class OEmbedView(generic.View):
return JsonResponse(data)
def get_info_string(user):
user_str = f"by {user.name} " if user else ""
time = timezone.now().strftime('%d/%m/%Y %H:%I')
return f"[Paperwork generated {user_str}on {time}"
def render_pdf_response(template, context, append_terms):
merger = PdfFileMerger()
rml = template.render(context)
buffer = rml2pdf.parseString(rml)
merger.append(PdfFileReader(buffer))
buffer.close()
if append_terms:
terms = urllib.request.urlopen(settings.TERMS_OF_HIRE_URL)
merger.append(BytesIO(terms.read()))
merged = BytesIO()
merger.write(merged)
response = HttpResponse(content_type='application/pdf')
f = context['filename']
response['Content-Disposition'] = f'filename="{f}"'
response.write(merged.getvalue())
return response
class PrintView(generic.View):
append_terms = False
def get_context_data(self, **kwargs):
obj = get_object_or_404(self.model, pk=self.kwargs['pk'])
user_str = f"by {self.request.user.name} " if self.request.user is not None else ""
time = timezone.now().strftime('%d/%m/%Y %H:%I')
object_name = re.sub(r'[^a-zA-Z0-9 \n\.]', '', obj.name)
context = {
'object': obj,
'current_user': self.request.user,
'object_name': object_name,
'info_string': f"[Paperwork generated {user_str}on {time} - {obj.current_version_id}]",
'info_string': get_info_string(self.request.user) + "- {obj.current_version_id}]",
}
return context
def get(self, request, pk):
template = get_template(self.template_name)
return render_pdf_response(get_template(self.template_name), self.get_context_data(), self.append_terms)
merger = PdfFileMerger()
context = self.get_context_data()
class PrintListView(generic.ListView):
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['current_user'] = self.request.user,
context['info_string'] = get_info_string(self.request.user) + "]"
return context
rml = template.render(context)
buffer = rml2pdf.parseString(rml)
merger.append(PdfFileReader(buffer))
buffer.close()
if self.append_terms:
terms = urllib.request.urlopen(settings.TERMS_OF_HIRE_URL)
merger.append(BytesIO(terms.read()))
merged = BytesIO()
merger.write(merged)
response = HttpResponse(content_type='application/pdf')
f = context['filename']
response['Content-Disposition'] = f'filename="{f}"'
response.write(merged.getvalue())
return response
def get(self, request):
self.object_list = self.get_queryset()
return render_pdf_response(get_template(self.template_name), self.get_context_data(), False)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 63 KiB

View File

@@ -11,6 +11,7 @@
<initialize>
<color id="LightGray" RGB="#D3D3D3"/>
<color id="DarkGray" RGB="#707070"/>
<color id="Brand" RGB="#3853a4"/>
</initialize>
<paraStyle name="style.para" fontName="OpenSans" />
@@ -27,6 +28,8 @@
<paraStyle name="style.times" fontName="OpenSans" fontSize="10" />
<paraStyle name="style.head_titles" fontName="OpenSans-Bold" fontSize="10" />
<paraStyle name="style.head_numbers" fontName="OpenSans" fontSize="10" />
<paraStyle name="style.emheader" fontName="OpenSans" textColor="White" fontSize="12" backColor="Brand" leading="20"/>
<paraStyle name="style.breakbefore" parent="emheader" pageBreakBefore="1"/>
<blockTableStyle id="eventSpecifics">
<blockValign value="top"/>

View File

@@ -196,8 +196,8 @@ def button(type, url=None, pk=None, clazz="", icon=None, text="", id=None, style
text = "Edit"
elif type == 'print':
clazz += " btn-primary "
icon = "fa-print"
text = "Print"
icon = "fa-download"
text = "Export"
elif type == 'duplicate':
clazz += " btn-info "
icon = "fa-copy"

View File

@@ -143,10 +143,14 @@ class Command(BaseCommand):
"Bin Diving",
"Wiki Editing"]
descriptions = ["Physical training concentrates on mechanistic goals: training programs in this area develop specific motor skills, agility, strength or physical fitness, often with an intention of peaking at a particular time.",
"In military use, training means gaining the physical ability to perform and survive in combat, and learn the many skills needed in a time of war. These include how to use a variety of weapons, outdoor survival skills, and how to survive being captured by the enemy, among many others. See military education and training.",
"For psychological or physiological reasons, people who believe it may be beneficial to them can choose to practice relaxation training, or autogenic training, in an attempt to increase their ability to relax or deal with stress. While some studies have indicated relaxation training is useful for some medical conditions, autogenic training has limited results or has been the result of few studies.",
"Some occupations are inherently hazardous, and require a minimum level of competence before the practitioners can perform the work at an acceptable level of safety to themselves or others in the vicinity. Occupational diving, rescue, firefighting and operation of certain types of machinery and vehicles may require assessment and certification of a minimum acceptable competence before the person is allowed to practice as a licensed instructor."]
descriptions = [
"Physical training concentrates on mechanistic goals: training programs in this area develop specific motor skills, agility, strength or physical fitness, often with an intention of peaking at a particular time.",
"In military use, training means gaining the physical ability to perform and survive in combat, and learn the many skills needed in a time of war.",
"These include how to use a variety of weapons, outdoor survival skills, and how to survive being captured by the enemy, among many others. See military education and training.",
"While some studies have indicated relaxation training is useful for some medical conditions, autogenic training has limited results or has been the result of few studies.",
"Some occupations are inherently hazardous, and require a minimum level of competence before the practitioners can perform the work at an acceptable level of safety to themselves or others in the vicinity.",
"Occupational diving, rescue, firefighting and operation of certain types of machinery and vehicles may require assessment and certification of a minimum acceptable competence before the person is allowed to practice as a licensed instructor."
]
for i, name in enumerate(names):
category = random.choice(self.categories)
@@ -155,7 +159,7 @@ class Command(BaseCommand):
number = previous_item.reference_number + 1
else:
number = 0
item = models.TrainingItem.objects.create(category=category, reference_number=number, name=name, description=random.choice(descriptions))
item = models.TrainingItem.objects.create(category=category, reference_number=number, name=name, description=random.choice(descriptions) + random.choice(descriptions) + random.choice(descriptions))
self.items.append(item)
def setup_levels(self):

View File

@@ -1,6 +1,11 @@
{% extends 'base_training.html' %}
{% load button from filters %}
{% block content %}
<div class="col-12 text-right py-2 pr-0">
{% button 'print' 'item_list_export' %}
</div>
<div id="accordion">
{% for category in categories %}
<div class="card">

View File

@@ -0,0 +1,25 @@
{% extends 'base_print.xml' %}
{% block content %}
<h1 style="page-head">TEC Training Item List</h1>
<spacer length="15" />
{% for category in categories %}
<h2 {% if not forloop.first %}style="breakbefore"{%else%}style="emheader"{%endif%}>{{category}}</h2>
<spacer length="10" />
{% for item in category.items.all %}
<h3>{{ item }}</h3>
<spacer length="4" />
<para>{{ item.description }}</para>
{% if item.prerequisites.exists %}
<h4>Prerequisites:</h4>
<ul bulletFontSize="5">
{% for p in item.prerequisites.all %}
<li><para>{{p}}</para></li>
{% endfor %}
</ul>
{% endif %}
<spacer length="8" />
{% endfor %}
{% endfor %}
{% endblock %}

View File

@@ -8,6 +8,7 @@ from versioning.views import VersionHistory
urlpatterns = [
path('items/', login_required(views.ItemList.as_view()), name='item_list'),
path('items/export/', login_required(views.ItemListExport.as_view()), name='item_list_export'),
path('item/<int:pk>/qualified_users/', login_required(views.ItemQualifications.as_view()), name='item_qualification'),
path('trainee/list/', login_required(views.TraineeList.as_view()), name='trainee_list'),

View File

@@ -7,7 +7,7 @@ from django.db import transaction
from django.db.models import Q, Count
from django.db.utils import IntegrityError
from PyRIGS.views import is_ajax, ModalURLMixin, get_related
from PyRIGS.views import is_ajax, ModalURLMixin, get_related, PrintListView
from training import models, forms
from users import views
from reversion.views import RevisionMixin
@@ -24,6 +24,17 @@ class ItemList(generic.ListView):
return context
class ItemListExport(PrintListView):
model = models.TrainingItem
template_name = 'item_list.xml'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['filename'] = f"TrainingItemList.pdf"
context["categories"] = models.TrainingCategory.objects.all()
return context
class TraineeDetail(views.ProfileDetail):
template_name = "trainee_detail.html"
model = models.Trainee