Merge branch 'master' into revision-view

This commit is contained in:
David Taylor
2015-05-24 12:24:21 +01:00
10 changed files with 234 additions and 96 deletions

View File

@@ -4,6 +4,7 @@ from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf import settings
from registration.backends.default.views import RegistrationView
import RIGS
from RIGS import regbackend
urlpatterns = patterns('',
# Examples:
@@ -12,7 +13,7 @@ urlpatterns = patterns('',
url(r'^', include('RIGS.urls')),
url('^user/register/$', RegistrationView.as_view(form_class=RIGS.forms.ProfileRegistrationFormUniqueEmail),
name="registration_register"),
name="registration_register"),
url('^user/', include('django.contrib.auth.urls')),
url('^user/', include('registration.backends.default.urls')),

View File

@@ -1,5 +1,5 @@
# TEC PA & Lighting - PyRIGS #
Welcome to TEC PA & Lightings PyRIGS program. This is a reiplmentation of the exisiting Rig Information Gathering System (RIGS) that was developed using Ruby on Rails.
Welcome to TEC PA & Lightings PyRIGS program. This is a reimplementation of the existing Rig Information Gathering System (RIGS) that was developed using Ruby on Rails.
The purpose of this project is to make the system more compatible and easier to understand such that should future changes be needed they can be made without having to understand the intricacies of Rails.
@@ -16,7 +16,7 @@ Most of the documents here assume a basic knowledge of how Python and Django wor
### Editing ###
It is recommended that you use the PyCharm IDE by JetBrains. Whilst other editors are available, this is the best for integration with Django as it can automatically manage all the pesky admin commands that frequently need running, as well as nice integration with git.
For the more experienced developer/somebody who doesn't want a full IDE and wants it to open in less than the age of the universe, I can strongly recommend [Sublime Text](http://www.sublimetext.com/). It has a bit of a steaper learning curve, and won't manage anything Django/git related out of the box, but once you get the hang of it is by far the fastest and most powerful editor I have used (for any type of project).
For the more experienced developer/somebody who doesn't want a full IDE and wants it to open in less than the age of the universe, I can strongly recommend [Sublime Text](http://www.sublimetext.com/). It has a bit of a steeper learning curve, and won't manage anything Django/git related out of the box, but once you get the hang of it is by far the fastest and most powerful editor I have used (for any type of project).
Please contact TJP for details on how to acquire these.

View File

@@ -1,10 +1,16 @@
import cStringIO as StringIO
from django.core.urlresolvers import reverse_lazy
from django.db import connection
from django.http import Http404, HttpResponseRedirect
from django.views import generic
from django.template import RequestContext
from django.template.loader import get_template
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.contrib import messages
import datetime
from z3c.rml import rml2pdf
from RIGS import models
@@ -33,6 +39,34 @@ class InvoiceIndex(generic.ListView):
class InvoiceDetail(generic.DetailView):
model = models.Invoice
class InvoicePrint(generic.View):
def get(self, request, pk):
invoice = get_object_or_404(models.Invoice, pk=pk)
object = invoice.event
template = get_template('RIGS/event_print.xml')
copies = ('TEC', 'Client')
context = RequestContext(request, {
'object': object,
'fonts': {
'opensans': {
'regular': 'RIGS/static/fonts/OPENSANS-REGULAR.TTF',
'bold': 'RIGS/static/fonts/OPENSANS-BOLD.TTF',
}
},
'invoice':invoice,
})
rml = template.render(context)
buffer = StringIO.StringIO()
buffer = rml2pdf.parseString(rml)
pdfData = buffer.read()
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = "filename=Invoice %05d | %s.pdf" % (invoice.pk, object.name)
response.write(pdfData)
return response
class InvoiceVoid(generic.View):
def get(self, *args, **kwargs):

View File

@@ -18,6 +18,10 @@ class ProfileRegistrationFormUniqueEmail(RegistrationFormUniqueEmail):
phone = forms.CharField(required=False, max_length=13)
captcha = ReCaptchaField()
class Meta:
model = models.Profile
fields = ('first_name','last_name','initials','phone')
def clean_initials(self):
"""
Validate that the supplied initials are unique.

13
RIGS/regbackend.py Normal file
View File

@@ -0,0 +1,13 @@
from RIGS.models import Profile
from RIGS.forms import ProfileRegistrationFormUniqueEmail
def user_created(sender, user, request, **kwargs):
form = ProfileRegistrationFormUniqueEmail(request.POST)
user.first_name = form.data['first_name']
user.last_name = form.data['last_name']
user.initials = form.data['initials']
user.phone = form.data['phone']
user.save()
from registration.signals import user_registered
user_registered.connect(user_created)

View File

@@ -22,17 +22,25 @@
<paraStyle name="style.Heading2" fontName="OpenSans-Bold" fontSize="10" spaceAfter="2"/>
<paraStyle name="style.Heading3" fontName="OpenSans" fontSize="10" spaceAfter="0"/>
<paraStyle name="center" alignment="center"/>
<paraStyle name="invoice-head" alignment="center" fontName="OpenSans-Bold" fontSize="16" leading="18" spaceAfter="0"/>
<paraStyle name="style.event_description" fontName="OpenSans" textColor="DarkGray" />
<paraStyle name="style.item_description" fontName="OpenSans" textColor="DarkGray" leftIndent="10" />
<paraStyle name="style.specific_description" fontName="OpenSans" textColor="DarkGray" fontSize="10" />
<paraStyle name="style.times" fontName="OpenSans" fontSize="10" />
<paraStyle name="style.invoice_titles" fontName="OpenSans-Bold" fontSize="10" />
<paraStyle name="style.invoice_numbers" fontName="OpenSans" fontSize="10" />
<blockTableStyle id="eventSpecifics">
<blockValign value="top"/>
<lineStyle kind="LINEAFTER" colorName="LightGrey" start="0,0" stop="1,0" thickness="1"/>
</blockTableStyle>
<blockTableStyle id="invoiceLayout">
<blockValign value="top"/>
</blockTableStyle>
<blockTableStyle id="eventDetails">
<blockValign value="top"/>
<blockTopPadding start="0,0" stop="-1,0" length="0"/>
@@ -91,7 +99,7 @@
<setFont name="OpenSans" size="10" />
<drawCenteredString x="302.5" y="50">[{{ copy }} Copy]</drawCenteredString>
{% if not invoice %}<drawCenteredString x="302.5" y="50">[{{ copy }} Copy]</drawCenteredString>{% endif %}
<drawCenteredString x="302.5" y="38">[Page <pageNumber/> of <getName id="lastPage" default="0" />]</drawCenteredString>
</pageGraphics>
@@ -101,7 +109,7 @@
<pageTemplate id="Main">
<pageGraphics>
<setFont name="OpenSans" size="10"/>
<drawCenteredString x="302.5" y="50">[{{ copy }} Copy]</drawCenteredString>
{% if not invoice %}<drawCenteredString x="302.5" y="50">[{{ copy }} Copy]</drawCenteredString>{% endif %}
<drawCenteredString x="302.5" y="38">[Page <pageNumber/> of <getName id="lastPage" default="0" />]</drawCenteredString>
</pageGraphics>
<frame id="main" x1="50" y1="65" width="495" height="727"/>

View File

@@ -1,16 +1,59 @@
<setNextFrame name="main"/>
<nextFrame/>
{% if invoice %}
<blockTable style="invoiceLayout" colWidths="330,165">
<tr>
<td>
{% endif %}
<h1><b>N{{ object.pk|stringformat:"05d" }}:</b> '{{ object.name }}'<small></small></h1>
<para style="style.event_description">
<b>{{object.start_date|date:"D jS N Y"}}</b>
</para>
<keepInFrame maxHeight="30">
<para style="style.event_description">
{{ object.description|default_if_none:""|linebreaks }}
</para>
<para style="style.event_description">
{{ object.description|default_if_none:""|linebreaksbr }}
</para>
</keepInFrame>
{% if invoice %}
</td>
<td>
<para style="invoice-head">INVOICE</para>
<spacer length="10"/>
<blockTable style="eventDetails" colWidths="100,175">
<tr>
<td><para style="invoice_titles">Invoice Number</para></td>
<td>
<para style="invoice_numbers">{{ invoice.pk|stringformat:"05d" }}</para>
</td>
</tr>
<tr>
<td><para style="invoice_titles">Invoice Date</para></td>
<td>
<para style="invoice_numbers">{{ invoice.invoice_date|date:"d/m/Y" }}</para>
</td>
</tr>
<tr>
<td><para style="invoice_titles">PO Number</para></td>
<td>
<para style="invoice_numbers">{{ object.purchase_order|default_if_none:"" }}</para>
</td>
</tr>
</blockTable>
</td>
</tr>
</blockTable>
{% endif %}
<spacer length="15"/>
<blockTable style="eventSpecifics" colWidths="165,165,165">
<tr>
@@ -18,7 +61,15 @@
<h2>Hirer</h2>
<h3>{{ object.person.name }}</h3>
<h3>{{ object.organisation.name|default_if_none:"" }}</h3>
{% if invoice %}
<keepInFrame>
{% if object.organisation.address %}
<para style="specific_description">{{ object.organisation.address|default_if_none:""|linebreaksbr }}</para>
{% elif object.person.address %}
<para style="specific_description">{{ object.person.address|default_if_none:""|linebreaksbr }}</para>
{% endif %}
</keepInFrame>
{% endif %}
<keepInFrame>
{% if object.person.phone %}
<para style="specific_description">{{ object.person.phone }}</para>
@@ -27,19 +78,29 @@
{% endif %}
</keepInFrame>
<keepInFrame>
{% if object.person.email %}
<para style="specific_description">{{ object.person.email }}</para>
{% elif object.organisation.email %}
<para style="specific_description">{{ object.organisation.email }}</para>
{% if invoice %}
{% if object.organisation.email %}
<para style="specific_description">{{ object.organisation.email }}</para>
{% elif object.person.email %}
<para style="specific_description">{{ object.person.email }}</para>
{% endif %}
{% else %}
{% if object.person.email %}
<para style="specific_description">{{ object.person.email }}</para>
{% elif object.organisation.email %}
<para style="specific_description">{{ object.organisation.email }}</para>
{% endif %}
{% endif %}
</keepInFrame>
</td>
<td>
<h2>Venue</h2>
<h3>{{ object.venue.name }}</h3>
{% if not invoice %}
<keepInFrame>
<para style="specific_description">{{ object.venue.address|default_if_none:""|linebreaks }}</para>
<para style="specific_description">{{ object.venue.address|default_if_none:""|linebreaksbr }}</para>
</keepInFrame>
{% endif %}
</td>
<td rightPadding="0">
@@ -61,7 +122,7 @@
</para>
</td>
</tr>
{% if object.access_at %}
{% if object.access_at and not invoice%}
<tr>
<td leftPadding="0"><h3>Access</h3></td>
<td>
@@ -113,7 +174,7 @@
{% if item.description %}
</para>
<para style="item_description">
<em>{{ item.description|linebreaks }}</em>
<em>{{ item.description|linebreaksbr }}</em>
</para>
<para>
{% endif %}
@@ -133,15 +194,21 @@
<td>£ {{ object.sum_total|floatformat:2 }}</td>
</tr>
<tr>
<td>VAT Registration Number: 116252989</td>
<td>{% if not invoice %}VAT Registration Number: 116252989{% endif %}</td>
<td>VAT @ {{ object.vat_rate.as_percent|floatformat:2 }}%</td>
<td>£ {{ object.vat|floatformat:2 }}</td>
</tr>
<tr>
<td>
<para>
<b>The full hire fee is payable at least 10 days before the event.</b>
{% if invoice %}
VAT Registration Number: 116252989
{% else %}
<b>The full hire fee is payable at least 10 days before the event.</b>
{% endif %}
</para>
</td>
<td>
<para>
@@ -156,88 +223,90 @@
</tr>
</blockTable>
</keepTogether>
<keepTogether>
<blockTable style="infoTable">
<tr>
<td>
<para>Bookings will
<b>not</b>
be confirmed until payment is received and the contract is signed.
</para>
</td>
</tr>
<tr>
<td>24 Hour Emergency Contacts: 07825 065681 or 07825 065678</td>
</tr>
</blockTable>
</keepTogether>
<spacer length="15"/>
<keepTogether>
<para style="blockPara">
<b>To be signed on booking:</b>
</para>
{% if object.organisation.union_account %}
<para style="blockPara">
<i>
I agree that am authorised to sign this invoice. I agree that I am the President/Treasurer of the hirer, or
that I have provided written permission from either the President or Treasurer of the hirer stating that I can
sign for this invoice.
</i>
</para>
<para style="blockPara">
<i>
I have read, understood and fully accepted the current conditions of hire. I agree to return any dry hire
items to TEC PA &amp; Lighting in the same condition at the end of the hire period.
</i>
</para>
<para style="blockPara">
<b>
Conditions of hire available on request or on the TEC PA &amp; Lighting website. E&amp;OE
</b>
</para>
<para style="blockPara">
Please return this form directly to TEC PA &amp; Lighting and not the Students' Union Finance Department.
</para>
<blockTable style="signatureTable" colWidths="70,100,325">
{% if not invoice %}
<keepTogether>
<blockTable style="infoTable">
<tr>
<td>Account Code</td>
<td></td>
<td></td>
<td>
<para>Bookings will
<b>not</b>
be confirmed until payment is received and the contract is signed.
</para>
</td>
</tr>
<tr>
<td>24 Hour Emergency Contacts: 07825 065681 or 07825 065678</td>
</tr>
</blockTable>
{% else %}
<para style="blockPara">
<i>
I, the hirer, have read, understand and fully accept the current conditions of hire. This document forms a
binding contract between TEC PA &amp; Lighting and the hirer, the aforementioned conditions of hire forming
an integral part of it.
</i>
</para>
</keepTogether>
<spacer length="15"/>
<keepTogether>
<para style="blockPara">
<b>
Conditions of hire available on request or on the TEC PA &amp; Lighting website. E&amp;OE
</b>
<b>To be signed on booking:</b>
</para>
{% if object.organisation.union_account %}
<para style="blockPara">
<i>
I agree that am authorised to sign this invoice. I agree that I am the President/Treasurer of the hirer, or
that I have provided written permission from either the President or Treasurer of the hirer stating that I can
sign for this invoice.
</i>
</para>
<para style="blockPara">
<i>
I have read, understood and fully accepted the current conditions of hire. I agree to return any dry hire
items to TEC PA &amp; Lighting in the same condition at the end of the hire period.
</i>
</para>
<para style="blockPara">
<b>
Conditions of hire available on request or on the TEC PA &amp; Lighting website. E&amp;OE
</b>
</para>
<para style="blockPara">
Please return this form directly to TEC PA &amp; Lighting and not the Students' Union Finance Department.
</para>
<blockTable style="signatureTable" colWidths="70,100,325">
<tr>
<td>Account Code</td>
<td></td>
<td></td>
</tr>
</blockTable>
{% else %}
<para style="blockPara">
<i>
I, the hirer, have read, understand and fully accept the current conditions of hire. This document forms a
binding contract between TEC PA &amp; Lighting and the hirer, the aforementioned conditions of hire forming
an integral part of it.
</i>
</para>
<para style="blockPara">
<b>
Conditions of hire available on request or on the TEC PA &amp; Lighting website. E&amp;OE
</b>
</para>
{% include "RIGS/event_print_signature.xml" %}
<spacer length="10"/>
<para style="blockPara">
<b>To be signed on the day of the event/hire:</b>
</para>
<para style="blockPara">
<i>
I, the hirer, have received the goods/services as requested and in good order. I agree to return any dry hire
items to TEC PA &amp; Lighting in a similar condition at the end of the hire period.
</i>
</para>
{% endif %}
{% include "RIGS/event_print_signature.xml" %}
<spacer length="10"/>
<para style="blockPara">
<b>To be signed on the day of the event/hire:</b>
</para>
<para style="blockPara">
<i>
I, the hirer, have received the goods/services as requested and in good order. I agree to return any dry hire
items to TEC PA &amp; Lighting in a similar condition at the end of the hire period.
</i>
</para>
{% endif %}
{% include "RIGS/event_print_signature.xml" %}
</keepTogether>
</keepTogether>
{% endif %}
<namedString id="lastPage"><pageNumber/></namedString>

View File

@@ -10,9 +10,15 @@
</div>
<div class="col-sm-4 text-right">
<div class="btn-group btn-page">
<a href="{% url 'invoice_void' object.pk %}" class="btn btn-default" title="Void Invoice">
<span class="glyphicon glyphicon-ban-circle"></span>
<span class="glyphicon glyphicon-ban-circle"></span> <span
class="hidden-xs">Void</span>
</a>
<a href="{% url 'invoice_print' object.pk %}" target="_blank" class="btn btn-default"><span
class="glyphicon glyphicon-print"></span> <span
class="hidden-xs">Print</span></a>
</div>
</div>
</div>

View File

@@ -119,6 +119,9 @@ urlpatterns = patterns('',
url(r'^invoice/(?P<pk>\d+)/$',
permission_required_with_403('RIGS.view_invoice')(finance.InvoiceDetail.as_view()),
name='invoice_detail'),
url(r'^invoice/(?P<pk>\d+)/print/$',
permission_required_with_403('RIGS.view_invoice')(finance.InvoicePrint.as_view()),
name='invoice_print'),
url(r'^invoice/(?P<pk>\d+)/void/$',
permission_required_with_403('RIGS.change_invoice')(finance.InvoiceVoid.as_view()),
name='invoice_void'),

View File

@@ -10,6 +10,7 @@ import simplejson
from django.contrib import messages
import datetime
import operator
from registration.views import RegistrationView
from RIGS import models, forms
@@ -33,7 +34,6 @@ def login(request, **kwargs):
return login(request, authentication_form=forms.LoginForm)
"""
Called from a modal window (e.g. when an item is submitted to an event/invoice).
May optionally also include some javascript in a success message to cause a load of