mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-02-24 07:08:23 +00:00
Merge branch 'master' into feature/online-auth
# Conflicts: # RIGS/rigboard.py # RIGS/test_functional.py # RIGS/urls.py # requirements.txt
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -53,6 +53,7 @@ coverage.xml
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
db.sqlite3
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||
from django.shortcuts import render_to_response
|
||||
from django.shortcuts import render
|
||||
from django.template import RequestContext
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.core.urlresolvers import reverse
|
||||
@@ -26,15 +26,15 @@ def user_passes_test_with_403(test_func, login_url=None, oembed_view=None):
|
||||
return view_func(request, *args, **kwargs)
|
||||
elif not request.user.is_authenticated():
|
||||
if oembed_view is not None:
|
||||
extra_context = {}
|
||||
extra_context['oembed_url'] = "{0}://{1}{2}".format(request.scheme, request.META['HTTP_HOST'], reverse(oembed_view, kwargs=kwargs))
|
||||
extra_context['login_url'] = "{0}?{1}={2}".format(login_url, REDIRECT_FIELD_NAME, request.get_full_path())
|
||||
resp = render_to_response('login_redirect.html', extra_context, context_instance=RequestContext(request))
|
||||
context = {}
|
||||
context['oembed_url'] = "{0}://{1}{2}".format(request.scheme, request.META['HTTP_HOST'], reverse(oembed_view, kwargs=kwargs))
|
||||
context['login_url'] = "{0}?{1}={2}".format(login_url, REDIRECT_FIELD_NAME, request.get_full_path())
|
||||
resp = render(request, 'login_redirect.html', context=context)
|
||||
return resp
|
||||
else:
|
||||
return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, request.get_full_path()))
|
||||
else:
|
||||
resp = render_to_response('403.html', context_instance=RequestContext(request))
|
||||
resp = render(request, '403.html')
|
||||
resp.status_code = 403
|
||||
return resp
|
||||
_checklogin.__doc__ = view_func.__doc__
|
||||
@@ -62,7 +62,7 @@ def api_key_required(function):
|
||||
userid = kwargs.get('api_pk')
|
||||
key = kwargs.get('api_key')
|
||||
|
||||
error_resp = render_to_response('403.html', context_instance=RequestContext(request))
|
||||
error_resp = render(request, '403.html')
|
||||
error_resp.status_code = 403
|
||||
|
||||
if key is None:
|
||||
|
||||
@@ -10,26 +10,31 @@ https://docs.djangoproject.com/en/1.7/ref/settings/
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
import os
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = os.environ.get('SECRET_KEY') if os.environ.get('SECRET_KEY') else 'gxhy(a#5mhp289_=6xx$7jh=eh$ymxg^ymc+di*0c*geiu3p_e'
|
||||
SECRET_KEY = os.environ.get('SECRET_KEY') if os.environ.get(
|
||||
'SECRET_KEY') else 'gxhy(a#5mhp289_=6xx$7jh=eh$ymxg^ymc+di*0c*geiu3p_e'
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = bool(int(os.environ.get('DEBUG'))) if os.environ.get('DEBUG') else True
|
||||
|
||||
STAGING = bool(int(os.environ.get('STAGING'))) if os.environ.get('STAGING') else False
|
||||
|
||||
TEMPLATE_DEBUG = True
|
||||
STAGING = bool(int(os.environ.get('STAGING'))) if os.environ.get('STAGING') else False
|
||||
|
||||
ALLOWED_HOSTS = ['pyrigs.nottinghamtec.co.uk', 'rigs.nottinghamtec.co.uk', 'pyrigs.herokuapp.com']
|
||||
|
||||
if STAGING:
|
||||
ALLOWED_HOSTS.append('.herokuapp.com')
|
||||
|
||||
if DEBUG:
|
||||
ALLOWED_HOSTS.append('localhost')
|
||||
ALLOWED_HOSTS.append('example.com')
|
||||
|
||||
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
||||
if not DEBUG:
|
||||
SECURE_SSL_REDIRECT = True # Redirect all http requests to https
|
||||
@@ -40,7 +45,6 @@ ADMINS = (
|
||||
('Tom Price', 'tomtom5152@gmail.com')
|
||||
)
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = (
|
||||
@@ -63,6 +67,7 @@ INSTALLED_APPS = (
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'raven.contrib.django.raven_compat.middleware.SentryResponseErrorIdMiddleware',
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'debug_toolbar.middleware.DebugToolbarMiddleware',
|
||||
'reversion.middleware.RevisionMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
@@ -77,7 +82,6 @@ ROOT_URLCONF = 'PyRIGS.urls'
|
||||
|
||||
WSGI_APPLICATION = 'PyRIGS.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases
|
||||
DATABASES = {
|
||||
@@ -89,6 +93,7 @@ DATABASES = {
|
||||
|
||||
if not DEBUG:
|
||||
import dj_database_url
|
||||
|
||||
DATABASES['default'] = dj_database_url.config()
|
||||
|
||||
# Logging
|
||||
@@ -152,8 +157,8 @@ RAVEN_CONFIG = {
|
||||
AUTH_USER_MODEL = 'RIGS.Profile'
|
||||
|
||||
LOGIN_REDIRECT_URL = '/'
|
||||
LOGIN_URL = '/user/login'
|
||||
LOGOUT_URL = '/user/logout'
|
||||
LOGIN_URL = '/user/login/'
|
||||
LOGOUT_URL = '/user/logout/'
|
||||
|
||||
ACCOUNT_ACTIVATION_DAYS = 7
|
||||
|
||||
@@ -167,7 +172,7 @@ EMAILER_TEST = False
|
||||
if not DEBUG or EMAILER_TEST:
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
EMAIL_HOST = os.environ.get('EMAIL_HOST')
|
||||
EMAIL_PORT = int(os.environ.get('EMAIL_PORT'))
|
||||
EMAIL_PORT = int(os.environ.get('EMAIL_PORT', 25))
|
||||
EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER')
|
||||
EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD')
|
||||
EMAIL_USE_TLS = bool(int(os.environ.get('EMAIL_USE_TLS', 0)))
|
||||
@@ -193,18 +198,6 @@ USE_TZ = True
|
||||
|
||||
DATETIME_INPUT_FORMATS = ('%Y-%m-%dT%H:%M', '%Y-%m-%dT%H:%M:%S')
|
||||
|
||||
TEMPLATE_CONTEXT_PROCESSORS = (
|
||||
"django.contrib.auth.context_processors.auth",
|
||||
"django.core.context_processors.debug",
|
||||
"django.core.context_processors.i18n",
|
||||
"django.core.context_processors.media",
|
||||
"django.core.context_processors.static",
|
||||
"django.core.context_processors.tz",
|
||||
"django.core.context_processors.request",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
)
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/1.7/howto/static-files/
|
||||
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
|
||||
@@ -214,9 +207,28 @@ STATIC_DIRS = (
|
||||
os.path.join(BASE_DIR, 'static/')
|
||||
)
|
||||
|
||||
TEMPLATE_DIRS = (
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [
|
||||
os.path.join(BASE_DIR, 'templates'),
|
||||
)
|
||||
],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
"django.contrib.auth.context_processors.auth",
|
||||
"django.template.context_processors.debug",
|
||||
"django.template.context_processors.i18n",
|
||||
"django.template.context_processors.media",
|
||||
"django.template.context_processors.static",
|
||||
"django.template.context_processors.tz",
|
||||
"django.template.context_processors.request",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
],
|
||||
'debug': DEBUG
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
USE_GRAVATAR = True
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from django.conf.urls import patterns, include, url
|
||||
from django.conf.urls import include, url
|
||||
from django.contrib import admin
|
||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||
from django.conf import settings
|
||||
@@ -6,7 +6,7 @@ from registration.backends.default.views import RegistrationView
|
||||
import RIGS
|
||||
from RIGS import regbackend
|
||||
|
||||
urlpatterns = patterns('',
|
||||
urlpatterns = [
|
||||
# Examples:
|
||||
# url(r'^$', 'PyRIGS.views.home', name='home'),
|
||||
# url(r'^blog/', include('blog.urls')),
|
||||
@@ -18,7 +18,12 @@ urlpatterns = patterns('',
|
||||
url('^user/', include('registration.backends.default.urls')),
|
||||
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
)
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
urlpatterns += staticfiles_urlpatterns()
|
||||
|
||||
import debug_toolbar
|
||||
urlpatterns = [
|
||||
url(r'^__debug__/', include(debug_toolbar.urls)),
|
||||
] + urlpatterns
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# TEC PA & Lighting - PyRIGS #
|
||||
[](https://travis-ci.org/nottinghamtec/PyRIGS)
|
||||
[](https://coveralls.io/github/nottinghamtec/PyRIGS?branch=develop)
|
||||
[](https://gemnasium.com/github.com/nottinghamtec/PyRIGS)
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ from django.contrib import admin
|
||||
from RIGS import models, forms
|
||||
from django.contrib.auth.admin import UserAdmin
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
import reversion
|
||||
from reversion.admin import VersionAdmin
|
||||
|
||||
from django.contrib.admin import helpers
|
||||
from django.template.response import TemplateResponse
|
||||
@@ -12,10 +12,12 @@ from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import Count
|
||||
from django.forms import ModelForm
|
||||
|
||||
from reversion import revisions as reversion
|
||||
|
||||
# Register your models here.
|
||||
admin.site.register(models.VatRate, reversion.VersionAdmin)
|
||||
admin.site.register(models.Event, reversion.VersionAdmin)
|
||||
admin.site.register(models.EventItem, reversion.VersionAdmin)
|
||||
admin.site.register(models.VatRate, VersionAdmin)
|
||||
admin.site.register(models.Event, VersionAdmin)
|
||||
admin.site.register(models.EventItem, VersionAdmin)
|
||||
admin.site.register(models.Invoice)
|
||||
admin.site.register(models.Payment)
|
||||
|
||||
@@ -41,7 +43,7 @@ class ProfileAdmin(UserAdmin):
|
||||
add_form = forms.ProfileCreationForm
|
||||
|
||||
|
||||
class AssociateAdmin(reversion.VersionAdmin):
|
||||
class AssociateAdmin(VersionAdmin):
|
||||
list_display = ('id', 'name', 'number_of_events')
|
||||
search_fields = ['id', 'name']
|
||||
list_display_links = ['id', 'name']
|
||||
@@ -93,8 +95,7 @@ class AssociateAdmin(reversion.VersionAdmin):
|
||||
'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
|
||||
'forms': forms
|
||||
}
|
||||
return TemplateResponse(request, 'RIGS/admin_associate_merge.html', context,
|
||||
current_app=self.admin_site.name)
|
||||
return TemplateResponse(request, 'RIGS/admin_associate_merge.html', context)
|
||||
|
||||
|
||||
@admin.register(models.Person)
|
||||
|
||||
@@ -15,6 +15,9 @@ from z3c.rml import rml2pdf
|
||||
|
||||
from RIGS import models
|
||||
|
||||
from django import forms
|
||||
forms.DateField.widget = forms.DateInput(attrs={'type': 'date'})
|
||||
|
||||
|
||||
class InvoiceIndex(generic.ListView):
|
||||
model = models.Invoice
|
||||
@@ -55,8 +58,8 @@ class InvoicePrint(generic.View):
|
||||
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, {
|
||||
|
||||
context = {
|
||||
'object': object,
|
||||
'fonts': {
|
||||
'opensans': {
|
||||
@@ -66,7 +69,7 @@ class InvoicePrint(generic.View):
|
||||
},
|
||||
'invoice': invoice,
|
||||
'current_user': request.user,
|
||||
})
|
||||
}
|
||||
|
||||
rml = template.render(context)
|
||||
buffer = StringIO.StringIO()
|
||||
@@ -78,7 +81,7 @@ class InvoicePrint(generic.View):
|
||||
escapedEventName = re.sub('[^a-zA-Z0-9 \n\.]', '', object.name)
|
||||
|
||||
response = HttpResponse(content_type='application/pdf')
|
||||
response['Content-Disposition'] = "filename=Invoice %05d | %s.pdf" % (invoice.pk, escapedEventName)
|
||||
response['Content-Disposition'] = "filename=Invoice %05d - N%05d | %s.pdf" % (invoice.pk, invoice.event.pk, escapedEventName)
|
||||
response.write(pdfData)
|
||||
return response
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@ import simplejson
|
||||
|
||||
from RIGS import models
|
||||
|
||||
# Override the django form defaults to use the HTML date/time/datetime UI elements
|
||||
forms.DateField.widget = forms.DateInput(attrs={'type': 'date'})
|
||||
forms.TimeField.widget = forms.DateInput(attrs={'type': 'time'})
|
||||
forms.DateTimeField.widget = forms.DateInput(attrs={'type': 'datetime-local'})
|
||||
|
||||
# Registration
|
||||
class ProfileRegistrationFormUniqueEmail(RegistrationFormUniqueEmail):
|
||||
@@ -45,7 +49,7 @@ class ProfileChangeForm(UserChangeForm):
|
||||
|
||||
# Events Shit
|
||||
class EventForm(forms.ModelForm):
|
||||
datetime_input_formats = formats.get_format_lazy("DATETIME_INPUT_FORMATS") + settings.DATETIME_INPUT_FORMATS
|
||||
datetime_input_formats = formats.get_format_lazy("DATETIME_INPUT_FORMATS") + list(settings.DATETIME_INPUT_FORMATS)
|
||||
meet_at = forms.DateTimeField(input_formats=datetime_input_formats, required=False)
|
||||
access_at = forms.DateTimeField(input_formats=datetime_input_formats, required=False)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.contrib.auth.models import Group, Permission
|
||||
from django.db import transaction
|
||||
import reversion
|
||||
from reversion import revisions as reversion
|
||||
|
||||
import datetime
|
||||
import random
|
||||
|
||||
26
RIGS/migrations/0025_auto_20160331_1302.py
Normal file
26
RIGS/migrations/0025_auto_20160331_1302.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.4 on 2016-03-31 12:02
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('RIGS', '0024_auto_20160229_2042'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='profile',
|
||||
name='username',
|
||||
field=models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=30, unique=True, validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.')], verbose_name='username'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vatrate',
|
||||
name='start_at',
|
||||
field=models.DateField(),
|
||||
),
|
||||
]
|
||||
21
RIGS/migrations/0026_auto_20170510_1846.py
Normal file
21
RIGS/migrations/0026_auto_20170510_1846.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.1 on 2017-05-10 17:46
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import django.contrib.auth.validators
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('RIGS', '0025_auto_20160331_1302'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='profile',
|
||||
name='username',
|
||||
field=models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.ASCIIUsernameValidator()], verbose_name='username'),
|
||||
),
|
||||
]
|
||||
@@ -1,19 +1,22 @@
|
||||
import datetime
|
||||
import hashlib
|
||||
import pytz
|
||||
import random
|
||||
import datetime, pytz
|
||||
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from reversion import revisions as reversion
|
||||
import string
|
||||
|
||||
import random
|
||||
from collections import Counter
|
||||
from decimal import Decimal
|
||||
|
||||
import reversion
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django.db import models
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
|
||||
# Create your models here.
|
||||
@@ -175,7 +178,7 @@ class Organisation(models.Model, RevisionMixin):
|
||||
|
||||
class VatManager(models.Manager):
|
||||
def current_rate(self):
|
||||
return self.find_rate(datetime.datetime.now())
|
||||
return self.find_rate(timezone.now())
|
||||
|
||||
def find_rate(self, date):
|
||||
# return self.filter(startAt__lte=date).latest()
|
||||
@@ -190,7 +193,7 @@ class VatManager(models.Manager):
|
||||
@reversion.register
|
||||
@python_2_unicode_compatible
|
||||
class VatRate(models.Model, RevisionMixin):
|
||||
start_at = models.DateTimeField()
|
||||
start_at = models.DateField()
|
||||
rate = models.DecimalField(max_digits=6, decimal_places=6)
|
||||
comment = models.CharField(max_length=255)
|
||||
|
||||
@@ -241,18 +244,12 @@ class Venue(models.Model, RevisionMixin):
|
||||
class EventManager(models.Manager):
|
||||
def current_events(self):
|
||||
events = self.filter(
|
||||
(models.Q(start_date__gte=datetime.date.today(), end_date__isnull=True, dry_hire=False) & ~models.Q(
|
||||
status=Event.CANCELLED)) | # Starts after with no end
|
||||
(models.Q(end_date__gte=datetime.date.today(), dry_hire=False) & ~models.Q(
|
||||
status=Event.CANCELLED)) | # Ends after
|
||||
(models.Q(dry_hire=True, start_date__gte=datetime.date.today()) & ~models.Q(
|
||||
status=Event.CANCELLED)) | # Active dry hire
|
||||
(models.Q(dry_hire=True, checked_in_by__isnull=True) & (
|
||||
models.Q(status=Event.BOOKED) | models.Q(status=Event.CONFIRMED))) | # Active dry hire GT
|
||||
models.Q(status=Event.CANCELLED, start_date__gte=datetime.date.today()) # Canceled but not started
|
||||
).order_by('start_date', 'end_date', 'start_time', 'end_time', 'meet_at').select_related('person',
|
||||
'organisation',
|
||||
'venue', 'mic')
|
||||
(models.Q(start_date__gte=timezone.now().date(), end_date__isnull=True, dry_hire=False) & ~models.Q(status=Event.CANCELLED)) | # Starts after with no end
|
||||
(models.Q(end_date__gte=timezone.now().date(), dry_hire=False) & ~models.Q(status=Event.CANCELLED)) | # Ends after
|
||||
(models.Q(dry_hire=True, start_date__gte=timezone.now().date()) & ~models.Q(status=Event.CANCELLED)) | # Active dry hire
|
||||
(models.Q(dry_hire=True, checked_in_by__isnull=True) & (models.Q(status=Event.BOOKED) | models.Q(status=Event.CONFIRMED))) | # Active dry hire GT
|
||||
models.Q(status=Event.CANCELLED, start_date__gte=timezone.now().date()) # Canceled but not started
|
||||
).order_by('start_date', 'end_date', 'start_time', 'end_time', 'meet_at').select_related('person', 'organisation', 'venue', 'mic')
|
||||
return events
|
||||
|
||||
def events_in_bounds(self, start, end):
|
||||
@@ -275,12 +272,12 @@ class EventManager(models.Manager):
|
||||
|
||||
def rig_count(self):
|
||||
event_count = self.filter(
|
||||
(models.Q(start_date__gte=datetime.date.today(), end_date__isnull=True, dry_hire=False,
|
||||
(models.Q(start_date__gte=timezone.now().date(), end_date__isnull=True, dry_hire=False,
|
||||
is_rig=True) & ~models.Q(
|
||||
status=Event.CANCELLED)) | # Starts after with no end
|
||||
(models.Q(end_date__gte=datetime.date.today(), dry_hire=False, is_rig=True) & ~models.Q(
|
||||
(models.Q(end_date__gte=timezone.now().date(), dry_hire=False, is_rig=True) & ~models.Q(
|
||||
status=Event.CANCELLED)) | # Ends after
|
||||
(models.Q(dry_hire=True, start_date__gte=datetime.date.today(), is_rig=True) & ~models.Q(
|
||||
(models.Q(dry_hire=True, start_date__gte=timezone.now().date(), is_rig=True) & ~models.Q(
|
||||
status=Event.CANCELLED)) | # Active dry hire
|
||||
(models.Q(dry_hire=True, checked_in_by__isnull=True, is_rig=True) & (
|
||||
models.Q(status=Event.BOOKED) | models.Q(status=Event.CONFIRMED))) # Active dry hire GT
|
||||
|
||||
@@ -151,7 +151,7 @@ class EventPrint(generic.View):
|
||||
|
||||
merger = PdfFileMerger()
|
||||
|
||||
context = RequestContext(request, {
|
||||
context = {
|
||||
'object': object,
|
||||
'fonts': {
|
||||
'opensans': {
|
||||
@@ -161,7 +161,7 @@ class EventPrint(generic.View):
|
||||
},
|
||||
'quote': True,
|
||||
'current_user': request.user,
|
||||
})
|
||||
}
|
||||
|
||||
rml = template.render(context)
|
||||
|
||||
|
||||
@@ -289,10 +289,10 @@
|
||||
<div class="col-sm-8">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-md-7" data-toggle="tooltip" title="Start date for event, required">
|
||||
{% render_field form.start_date type="date" class+="form-control" %}
|
||||
{% render_field form.start_date class+="form-control" %}
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-5" data-toggle="tooltip" title="Start time of event, can be left blank">
|
||||
{% render_field form.start_time type="time" class+="form-control" %}
|
||||
{% render_field form.start_time class+="form-control" %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -304,10 +304,10 @@
|
||||
<div class="col-sm-8">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-md-7" data-toggle="tooltip" title="End date of event, leave blank if unknown or same as start date">
|
||||
{% render_field form.end_date type="date" class+="form-control" %}
|
||||
{% render_field form.end_date class+="form-control" %}
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-5" data-toggle="tooltip" title="End time of event, leave blank if unknown">
|
||||
{% render_field form.end_time type="time" class+="form-control" %}
|
||||
{% render_field form.end_time class+="form-control" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -329,7 +329,7 @@
|
||||
class="col-sm-4 control-label">{{ form.access_at.label }}</label>
|
||||
|
||||
<div class="col-sm-8">
|
||||
{% render_field form.access_at type="datetime-local" class+="form-control" %}
|
||||
{% render_field form.access_at class+="form-control" %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" data-toggle="tooltip" title="The date/time at which crew should meet for this event">
|
||||
@@ -337,7 +337,7 @@
|
||||
class="col-sm-4 control-label">{{ form.meet_at.label }}</label>
|
||||
|
||||
<div class="col-sm-8">
|
||||
{% render_field form.meet_at type="datetime-local" class+="form-control" %}
|
||||
{% render_field form.meet_at class+="form-control" %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
for="{{ form.date.id_for_label }}">{{ form.date.label }}</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
{% render_field form.date type="date" class+="form-control" %}
|
||||
{% render_field form.date class+="form-control" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -18,6 +18,14 @@ from selenium.webdriver.support.ui import WebDriverWait
|
||||
|
||||
from RIGS import models
|
||||
|
||||
import re
|
||||
import os
|
||||
from datetime import date, timedelta
|
||||
from django.db import transaction
|
||||
from reversion import revisions as reversion
|
||||
import json
|
||||
|
||||
|
||||
|
||||
class UserRegistrationTest(LiveServerTestCase):
|
||||
def setUp(self):
|
||||
@@ -434,7 +442,8 @@ class EventTest(LiveServerTestCase):
|
||||
# See redirected to success page
|
||||
successTitle = self.browser.find_element_by_xpath('//h1').text
|
||||
event = models.Event.objects.get(name='Test Event Name')
|
||||
self.assertIn("N0000%d | Test Event Name" % event.pk, successTitle)
|
||||
|
||||
self.assertIn("N%05d | Test Event Name"%event.pk, successTitle)
|
||||
except WebDriverException:
|
||||
# This is a dirty workaround for wercker being a bit funny and not running it correctly.
|
||||
# Waiting for wercker to get back to me about this
|
||||
@@ -496,9 +505,9 @@ class EventTest(LiveServerTestCase):
|
||||
# Attempt to save
|
||||
save.click()
|
||||
|
||||
self.assertNotIn("N0000%d" % testEvent.pk, self.browser.find_element_by_xpath('//h1').text)
|
||||
self.assertNotIn("Event data duplicated but not yet saved",
|
||||
self.browser.find_element_by_id('content').text) # Check info message not visible
|
||||
|
||||
self.assertNotIn("N%05d"%testEvent.pk, self.browser.find_element_by_xpath('//h1').text)
|
||||
self.assertNotIn("Event data duplicated but not yet saved", self.browser.find_element_by_id('content').text) # Check info message not visible
|
||||
|
||||
# Check the new items are visible
|
||||
table = self.browser.find_element_by_id('item-table') # ID number is known, see above
|
||||
@@ -507,15 +516,22 @@ class EventTest(LiveServerTestCase):
|
||||
self.assertIn("Test Item 3", table.text)
|
||||
|
||||
infoPanel = self.browser.find_element_by_xpath('//div[contains(text(), "Event Info")]/..')
|
||||
self.assertIn("N0000%d" % testEvent.pk,
|
||||
infoPanel.find_element_by_xpath('//dt[text()="Based On"]/following-sibling::dd[1]').text)
|
||||
|
||||
|
||||
self.assertIn("N%05d"%testEvent.pk, infoPanel.find_element_by_xpath('//dt[text()="Based On"]/following-sibling::dd[1]').text)
|
||||
|
||||
# Check the PO hasn't carried through
|
||||
self.assertNotIn("TESTPO", infoPanel.find_element_by_xpath('//dt[text()="PO"]/following-sibling::dd[1]').text)
|
||||
|
||||
self.browser.get(self.live_server_url + '/event/' + str(testEvent.pk)) #Go back to the old event
|
||||
|
||||
#Check that based-on hasn't crept into the old event
|
||||
infoPanel = self.browser.find_element_by_xpath('//div[contains(text(), "Event Info")]/..')
|
||||
self.assertNotIn("N0000%d" % testEvent.pk,
|
||||
infoPanel.find_element_by_xpath('//dt[text()="Based On"]/following-sibling::dd[1]').text)
|
||||
|
||||
self.assertNotIn("N%05d"%testEvent.pk, infoPanel.find_element_by_xpath('//dt[text()="Based On"]/following-sibling::dd[1]').text)
|
||||
|
||||
# Check the PO remains on the old event
|
||||
self.assertIn("TESTPO", infoPanel.find_element_by_xpath('//dt[text()="PO"]/following-sibling::dd[1]').text)
|
||||
|
||||
# Check the items are as they were
|
||||
table = self.browser.find_element_by_id('item-table') # ID number is known, see above
|
||||
@@ -630,7 +646,8 @@ class EventTest(LiveServerTestCase):
|
||||
# See redirected to success page
|
||||
successTitle = self.browser.find_element_by_xpath('//h1').text
|
||||
event = models.Event.objects.get(name='Test Event Name')
|
||||
self.assertIn("N0000%d | Test Event Name" % event.pk, successTitle)
|
||||
|
||||
self.assertIn("N%05d | Test Event Name"%event.pk, successTitle)
|
||||
|
||||
def testRigNonRig(self):
|
||||
self.browser.get(self.live_server_url + '/event/create/')
|
||||
|
||||
@@ -17,71 +17,82 @@ class ProfileTestCase(TestCase):
|
||||
|
||||
|
||||
class VatRateTestCase(TestCase):
|
||||
def setUp(self):
|
||||
models.VatRate.objects.create(start_at='2014-03-01', rate=0.20, comment='test1')
|
||||
models.VatRate.objects.create(start_at='2016-03-01', rate=0.15, comment='test2')
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.rates = {
|
||||
0: models.VatRate.objects.create(start_at='2014-03-01', rate=0.20, comment='test1'),
|
||||
1: models.VatRate.objects.create(start_at='2016-03-01', rate=0.15, comment='test2'),
|
||||
}
|
||||
|
||||
def test_find_correct(self):
|
||||
r = models.VatRate.objects.find_rate('2015-03-01')
|
||||
self.assertEqual(r.comment, 'test1')
|
||||
self.assertEqual(r, self.rates[0])
|
||||
r = models.VatRate.objects.find_rate('2016-03-01')
|
||||
self.assertEqual(r.comment, 'test2')
|
||||
self.assertEqual(r, self.rates[1])
|
||||
|
||||
def test_percent_correct(self):
|
||||
r = models.VatRate.objects.get(rate=0.20)
|
||||
self.assertEqual(r.as_percent, 20)
|
||||
self.assertEqual(self.rates[0].as_percent, 20)
|
||||
|
||||
|
||||
class EventTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.all_events = set(range(1, 18))
|
||||
self.current_events = (1, 2, 3, 6, 7, 8, 10, 11, 12, 14, 15, 16, 18)
|
||||
self.not_current_events = set(self.all_events) - set(self.current_events)
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.all_events = set(range(1, 18))
|
||||
cls.current_events = (1, 2, 3, 6, 7, 8, 10, 11, 12, 14, 15, 16, 18)
|
||||
cls.not_current_events = set(cls.all_events) - set(cls.current_events)
|
||||
|
||||
self.vatrate = models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1')
|
||||
self.profile = models.Profile.objects.create(username="testuser1", email="1@test.com")
|
||||
cls.vatrate = models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1')
|
||||
cls.profile = models.Profile.objects.create(username="testuser1", email="1@test.com")
|
||||
|
||||
cls.events = {
|
||||
# produce 7 normal events - 5 current
|
||||
models.Event.objects.create(name="TE E1", start_date=date.today() + timedelta(days=6),
|
||||
description="start future no end")
|
||||
models.Event.objects.create(name="TE E2", start_date=date.today(), description="start today no end")
|
||||
models.Event.objects.create(name="TE E3", start_date=date.today(), end_date=date.today(),
|
||||
description="start today with end today")
|
||||
models.Event.objects.create(name="TE E4", start_date='2014-03-20', description="start past no end")
|
||||
models.Event.objects.create(name="TE E5", start_date='2014-03-20', end_date='2014-03-21',
|
||||
description="start past with end past")
|
||||
models.Event.objects.create(name="TE E6", start_date=date.today() - timedelta(days=2),
|
||||
end_date=date.today() + timedelta(days=2), description="start past, end future")
|
||||
models.Event.objects.create(name="TE E7", start_date=date.today() + timedelta(days=2),
|
||||
end_date=date.today() + timedelta(days=2), description="start + end in future")
|
||||
1: models.Event.objects.create(name="TE E1", start_date=date.today() + timedelta(days=6),
|
||||
description="start future no end"),
|
||||
2: models.Event.objects.create(name="TE E2", start_date=date.today(), description="start today no end"),
|
||||
3: models.Event.objects.create(name="TE E3", start_date=date.today(), end_date=date.today(),
|
||||
description="start today with end today"),
|
||||
4: models.Event.objects.create(name="TE E4", start_date='2014-03-20', description="start past no end"),
|
||||
5: models.Event.objects.create(name="TE E5", start_date='2014-03-20', end_date='2014-03-21',
|
||||
description="start past with end past"),
|
||||
6: models.Event.objects.create(name="TE E6", start_date=date.today() - timedelta(days=2),
|
||||
end_date=date.today() + timedelta(days=2),
|
||||
description="start past, end future"),
|
||||
7: models.Event.objects.create(name="TE E7", start_date=date.today() + timedelta(days=2),
|
||||
end_date=date.today() + timedelta(days=2),
|
||||
description="start + end in future"),
|
||||
|
||||
# 2 cancelled - 1 current
|
||||
models.Event.objects.create(name="TE E8", start_date=date.today() + timedelta(days=2),
|
||||
8: models.Event.objects.create(name="TE E8", start_date=date.today() + timedelta(days=2),
|
||||
end_date=date.today() + timedelta(days=2), status=models.Event.CANCELLED,
|
||||
description="cancelled in future")
|
||||
models.Event.objects.create(name="TE E9", start_date=date.today() - timedelta(days=1),
|
||||
description="cancelled in future"),
|
||||
9: models.Event.objects.create(name="TE E9", start_date=date.today() - timedelta(days=1),
|
||||
end_date=date.today() + timedelta(days=2), status=models.Event.CANCELLED,
|
||||
description="cancelled and started")
|
||||
description="cancelled and started"),
|
||||
|
||||
# 5 dry hire - 3 current
|
||||
models.Event.objects.create(name="TE E10", start_date=date.today(), dry_hire=True, description="dryhire today")
|
||||
models.Event.objects.create(name="TE E11", start_date=date.today(), dry_hire=True, checked_in_by=self.profile,
|
||||
description="dryhire today, checked in")
|
||||
models.Event.objects.create(name="TE E12", start_date=date.today() - timedelta(days=1), dry_hire=True,
|
||||
status=models.Event.BOOKED, description="dryhire past")
|
||||
models.Event.objects.create(name="TE E13", start_date=date.today() - timedelta(days=2), dry_hire=True,
|
||||
checked_in_by=self.profile, description="dryhire past checked in")
|
||||
models.Event.objects.create(name="TE E14", start_date=date.today(), dry_hire=True,
|
||||
status=models.Event.CANCELLED, description="dryhire today cancelled")
|
||||
10: models.Event.objects.create(name="TE E10", start_date=date.today(), dry_hire=True,
|
||||
description="dryhire today"),
|
||||
11: models.Event.objects.create(name="TE E11", start_date=date.today(), dry_hire=True,
|
||||
checked_in_by=cls.profile,
|
||||
description="dryhire today, checked in"),
|
||||
12: models.Event.objects.create(name="TE E12", start_date=date.today() - timedelta(days=1), dry_hire=True,
|
||||
status=models.Event.BOOKED, description="dryhire past"),
|
||||
13: models.Event.objects.create(name="TE E13", start_date=date.today() - timedelta(days=2), dry_hire=True,
|
||||
checked_in_by=cls.profile, description="dryhire past checked in"),
|
||||
14: models.Event.objects.create(name="TE E14", start_date=date.today(), dry_hire=True,
|
||||
status=models.Event.CANCELLED, description="dryhire today cancelled"),
|
||||
|
||||
# 4 non rig - 3 current
|
||||
models.Event.objects.create(name="TE E15", start_date=date.today(), is_rig=False, description="non rig today")
|
||||
models.Event.objects.create(name="TE E16", start_date=date.today() + timedelta(days=1), is_rig=False,
|
||||
description="non rig tomorrow")
|
||||
models.Event.objects.create(name="TE E17", start_date=date.today() - timedelta(days=1), is_rig=False,
|
||||
description="non rig yesterday")
|
||||
models.Event.objects.create(name="TE E18", start_date=date.today(), is_rig=False, status=models.Event.CANCELLED,
|
||||
description="non rig today cancelled")
|
||||
15: models.Event.objects.create(name="TE E15", start_date=date.today(), is_rig=False,
|
||||
description="non rig today"),
|
||||
16: models.Event.objects.create(name="TE E16", start_date=date.today() + timedelta(days=1), is_rig=False,
|
||||
description="non rig tomorrow"),
|
||||
17: models.Event.objects.create(name="TE E17", start_date=date.today() - timedelta(days=1), is_rig=False,
|
||||
description="non rig yesterday"),
|
||||
18: models.Event.objects.create(name="TE E18", start_date=date.today(), is_rig=False,
|
||||
status=models.Event.CANCELLED,
|
||||
description="non rig today cancelled"),
|
||||
}
|
||||
|
||||
def test_count(self):
|
||||
# Santiy check we have the expected events created
|
||||
@@ -103,17 +114,23 @@ class EventTestCase(TestCase):
|
||||
def test_related_venue(self):
|
||||
v1 = models.Venue.objects.create(name="TE V1")
|
||||
v2 = models.Venue.objects.create(name="TE V2")
|
||||
events = models.Event.objects.all()
|
||||
for event in events[:2]:
|
||||
|
||||
e1 = []
|
||||
e2 = []
|
||||
for (key, event) in self.events.iteritems():
|
||||
if event.pk % 2:
|
||||
event.venue = v1
|
||||
event.save()
|
||||
for event in events[3:4]:
|
||||
e1.append(event)
|
||||
else:
|
||||
event.venue = v2
|
||||
e2.append(event)
|
||||
event.save()
|
||||
|
||||
events = models.Event.objects.all()
|
||||
self.assertItemsEqual(events[:2], v1.latest_events)
|
||||
self.assertItemsEqual(events[3:4], v2.latest_events)
|
||||
self.assertItemsEqual(e1, v1.latest_events)
|
||||
self.assertItemsEqual(e2, v2.latest_events)
|
||||
|
||||
for (key, event) in self.events.iteritems():
|
||||
event.venue = None
|
||||
|
||||
def test_related_vatrate(self):
|
||||
self.assertEqual(self.vatrate, models.Event.objects.all()[0].vat_rate)
|
||||
@@ -122,33 +139,43 @@ class EventTestCase(TestCase):
|
||||
p1 = models.Person.objects.create(name="TE P1")
|
||||
p2 = models.Person.objects.create(name="TE P2")
|
||||
|
||||
events = models.Event.objects.all()
|
||||
for event in events[:2]:
|
||||
e1 = []
|
||||
e2 = []
|
||||
for (key, event) in self.events.iteritems():
|
||||
if event.pk % 2:
|
||||
event.person = p1
|
||||
event.save()
|
||||
for event in events[3:4]:
|
||||
e1.append(event)
|
||||
else:
|
||||
event.person = p2
|
||||
e2.append(event)
|
||||
event.save()
|
||||
|
||||
events = models.Event.objects.all()
|
||||
self.assertItemsEqual(events[:2], p1.latest_events)
|
||||
self.assertItemsEqual(events[3:4], p2.latest_events)
|
||||
self.assertItemsEqual(e1, p1.latest_events)
|
||||
self.assertItemsEqual(e2, p2.latest_events)
|
||||
|
||||
for (key, event) in self.events.iteritems():
|
||||
event.person = None
|
||||
|
||||
def test_related_organisation(self):
|
||||
o1 = models.Organisation.objects.create(name="TE O1")
|
||||
o2 = models.Organisation.objects.create(name="TE O2")
|
||||
|
||||
events = models.Event.objects.all()
|
||||
for event in events[:2]:
|
||||
e1 = []
|
||||
e2 = []
|
||||
for (key, event) in self.events.iteritems():
|
||||
if event.pk % 2:
|
||||
event.organisation = o1
|
||||
event.save()
|
||||
for event in events[3:4]:
|
||||
e1.append(event)
|
||||
else:
|
||||
event.organisation = o2
|
||||
e2.append(event)
|
||||
event.save()
|
||||
|
||||
events = models.Event.objects.all()
|
||||
self.assertItemsEqual(events[:2], o1.latest_events)
|
||||
self.assertItemsEqual(events[3:4], o2.latest_events)
|
||||
self.assertItemsEqual(e1, o1.latest_events)
|
||||
self.assertItemsEqual(e2, o2.latest_events)
|
||||
|
||||
for (key, event) in self.events.iteritems():
|
||||
event.organisation = None
|
||||
|
||||
def test_organisation_person_join(self):
|
||||
p1 = models.Person.objects.create(name="TE P1")
|
||||
@@ -186,20 +213,20 @@ class EventTestCase(TestCase):
|
||||
self.assertEqual(len(o2.persons), 1)
|
||||
|
||||
def test_cancelled_property(self):
|
||||
event = models.Event.objects.all()[0]
|
||||
event.status = models.Event.CANCELLED
|
||||
event.save()
|
||||
event = models.Event.objects.all()[0]
|
||||
edit = self.events[1]
|
||||
edit.status = models.Event.CANCELLED
|
||||
edit.save()
|
||||
event = models.Event.objects.get(pk=edit.pk)
|
||||
self.assertEqual(event.status, models.Event.CANCELLED)
|
||||
self.assertTrue(event.cancelled)
|
||||
event.status = models.Event.PROVISIONAL
|
||||
event.save()
|
||||
|
||||
def test_confirmed_property(self):
|
||||
event = models.Event.objects.all()[0]
|
||||
event.status = models.Event.CONFIRMED
|
||||
event.save()
|
||||
event = models.Event.objects.all()[0]
|
||||
edit = self.events[1]
|
||||
edit.status = models.Event.CONFIRMED
|
||||
edit.save()
|
||||
event = models.Event.objects.get(pk=edit.pk)
|
||||
self.assertEqual(event.status, models.Event.CONFIRMED)
|
||||
self.assertTrue(event.confirmed)
|
||||
event.status = models.Event.PROVISIONAL
|
||||
@@ -250,14 +277,14 @@ class EventTestCase(TestCase):
|
||||
# basic checks
|
||||
manager.create(name='TE IB2', start_date='2016-01-02', end_date='2016-01-04'),
|
||||
manager.create(name='TE IB3', start_date='2015-12-31', end_date='2016-01-03'),
|
||||
manager.create(name='TE IB4', start_date='2016-01-04', access_at='2016-01-03'),
|
||||
manager.create(name='TE IB5', start_date='2016-01-04', meet_at='2016-01-02'),
|
||||
manager.create(name='TE IB4', start_date='2016-01-04', access_at=self.create_datetime(2016, 01, 03, 00, 00)),
|
||||
manager.create(name='TE IB5', start_date='2016-01-04', meet_at=self.create_datetime(2016, 01, 02, 00, 00)),
|
||||
|
||||
# negative check
|
||||
manager.create(name='TE IB6', start_date='2015-12-31', end_date='2016-01-01'),
|
||||
]
|
||||
|
||||
in_bounds = manager.events_in_bounds(datetime(2016, 1, 2), datetime(2016, 1, 3))
|
||||
in_bounds = manager.events_in_bounds(self.create_datetime(2016, 1, 2, 0, 0), self.create_datetime(2016, 1, 3, 0, 0))
|
||||
self.assertIn(events[0], in_bounds)
|
||||
self.assertIn(events[1], in_bounds)
|
||||
self.assertIn(events[2], in_bounds)
|
||||
|
||||
@@ -164,6 +164,8 @@ class TestInvoiceDelete(TestCase):
|
||||
def setUpTestData(cls):
|
||||
cls.profile = models.Profile.objects.create(username="testuser1", email="1@test.com", is_superuser=True, is_active=True, is_staff=True)
|
||||
|
||||
cls.vatrate = models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1')
|
||||
|
||||
cls.events = {
|
||||
1: models.Event.objects.create(name="TE E1", start_date=date.today()),
|
||||
2: models.Event.objects.create(name="TE E2", start_date=date.today())
|
||||
@@ -214,6 +216,39 @@ class TestInvoiceDelete(TestCase):
|
||||
self.assertTrue(models.Invoice.objects.get(pk=self.invoices[1].pk))
|
||||
|
||||
|
||||
class TestPrintPaperwork(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.profile = models.Profile.objects.create(username="testuser1", email="1@test.com", is_superuser=True, is_active=True, is_staff=True)
|
||||
|
||||
cls.vatrate = models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1')
|
||||
|
||||
cls.events = {
|
||||
1: models.Event.objects.create(name="TE E1", start_date=date.today()),
|
||||
}
|
||||
|
||||
cls.invoices = {
|
||||
1: models.Invoice.objects.create(event=cls.events[1]),
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
self.profile.set_password('testuser')
|
||||
self.profile.save()
|
||||
self.assertTrue(self.client.login(username=self.profile.username, password='testuser'))
|
||||
|
||||
def test_print_paperwork_success(self):
|
||||
request_url = reverse('event_print', kwargs={'pk': self.events[1].pk})
|
||||
|
||||
response = self.client.get(request_url, follow=True)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_print_invoice_success(self):
|
||||
request_url = reverse('invoice_print', kwargs={'pk': self.invoices[1].pk})
|
||||
|
||||
response = self.client.get(request_url, follow=True)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
||||
class TestEmbeddedViews(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
|
||||
14
RIGS/urls.py
14
RIGS/urls.py
@@ -1,4 +1,6 @@
|
||||
from django.conf.urls import patterns, url
|
||||
from django.conf.urls import url
|
||||
from django.contrib.auth.views import password_reset
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from RIGS import models, views, rigboard, finance, ical, versioning, forms
|
||||
from django.views.generic import RedirectView
|
||||
@@ -7,17 +9,17 @@ from django.views.decorators.clickjacking import xframe_options_exempt
|
||||
from PyRIGS.decorators import permission_required_with_403
|
||||
from PyRIGS.decorators import api_key_required
|
||||
|
||||
urlpatterns = patterns('',
|
||||
urlpatterns = [
|
||||
# Examples:
|
||||
# url(r'^$', 'PyRIGS.views.home', name='home'),
|
||||
# url(r'^blog/', include('blog.urls')),
|
||||
url('^$', login_required(views.Index.as_view()), name='index'),
|
||||
url(r'^closemodal/$', views.CloseModal.as_view(), name='closemodal'),
|
||||
|
||||
url('^user/login/$', 'RIGS.views.login', name='login'),
|
||||
url('^user/login/$', views.login, name='login'),
|
||||
url('^user/login/embed/$', xframe_options_exempt(views.login_embed), name='login_embed'),
|
||||
url(r'^user/password_reset/$', 'django.contrib.auth.views.password_reset',
|
||||
{'password_reset_form': forms.PasswordReset}),
|
||||
|
||||
url(r'^user/password_reset/$', password_reset, {'password_reset_form': forms.PasswordReset}),
|
||||
|
||||
# People
|
||||
url(r'^people/$', permission_required_with_403('RIGS.view_person')(views.PersonList.as_view()),
|
||||
@@ -188,4 +190,4 @@ urlpatterns = patterns('',
|
||||
RedirectView.as_view(permanent=True, pattern_name='event_detail')),
|
||||
url(r'^bookings/$', RedirectView.as_view(permanent=True, pattern_name='rigboard')),
|
||||
url(r'^bookings/past/$', RedirectView.as_view(permanent=True, pattern_name='event_archive')),
|
||||
)
|
||||
]
|
||||
|
||||
@@ -158,7 +158,7 @@ def get_previous_version(version):
|
||||
thisId = version.object_id
|
||||
thisVersionId = version.pk
|
||||
|
||||
versions = reversion.get_for_object_reference(version.content_type.model_class(), thisId)
|
||||
versions = reversion.revisions.get_for_object_reference(version.content_type.model_class(), thisId)
|
||||
|
||||
try:
|
||||
previousVersions = versions.filter(revision_id__lt=version.revision_id).latest(
|
||||
@@ -199,7 +199,7 @@ def get_changes_for_version(newVersion, oldVersion=None):
|
||||
|
||||
|
||||
class VersionHistory(generic.ListView):
|
||||
model = reversion.revisions.Version
|
||||
model = Version
|
||||
template_name = "RIGS/version_history.html"
|
||||
paginate_by = 25
|
||||
|
||||
@@ -207,7 +207,7 @@ class VersionHistory(generic.ListView):
|
||||
thisModel = self.kwargs['model']
|
||||
|
||||
# thisObject = get_object_or_404(thisModel, pk=self.kwargs['pk'])
|
||||
versions = reversion.get_for_object_reference(thisModel, self.kwargs['pk'])
|
||||
versions = reversion.revisions.get_for_object_reference(thisModel, self.kwargs['pk'])
|
||||
|
||||
return versions
|
||||
|
||||
@@ -236,7 +236,7 @@ class VersionHistory(generic.ListView):
|
||||
|
||||
|
||||
class ActivityTable(generic.ListView):
|
||||
model = reversion.revisions.Version
|
||||
model = Version
|
||||
template_name = "RIGS/activity_table.html"
|
||||
paginate_by = 25
|
||||
|
||||
@@ -260,7 +260,7 @@ class ActivityTable(generic.ListView):
|
||||
|
||||
|
||||
class ActivityFeed(generic.ListView):
|
||||
model = reversion.revisions.Version
|
||||
model = Version
|
||||
template_name = "RIGS/activity_feed_data.html"
|
||||
paginate_by = 25
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class Index(generic.TemplateView):
|
||||
|
||||
def login(request, **kwargs):
|
||||
if request.user.is_authenticated():
|
||||
next = request.REQUEST.get('next', '/')
|
||||
next = request.GET.get('next', '/')
|
||||
return HttpResponseRedirect(next)
|
||||
else:
|
||||
from django.contrib.auth.views import login
|
||||
@@ -44,9 +44,8 @@ def login(request, **kwargs):
|
||||
# check for it before logging the user in
|
||||
@csrf_exempt
|
||||
def login_embed(request, **kwargs):
|
||||
print("Running LOGIN")
|
||||
if request.user.is_authenticated():
|
||||
next = request.REQUEST.get('next', '/')
|
||||
next = request.GET.get('next', '/')
|
||||
return HttpResponseRedirect(next)
|
||||
else:
|
||||
from django.contrib.auth.views import login
|
||||
|
||||
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
@@ -1,34 +1,37 @@
|
||||
beautifulsoup4==4.6.0
|
||||
contextlib2==0.5.5
|
||||
diff-match-patch==20121119
|
||||
dj-database-url==0.3.0
|
||||
dj-database-url==0.4.2
|
||||
dj-static==0.0.6
|
||||
Django==1.8.2
|
||||
django-debug-toolbar==1.3.0
|
||||
django-ical==1.3
|
||||
django-recaptcha==1.0.4
|
||||
django-registration-redux==1.2
|
||||
django-reversion==1.8.7
|
||||
Django==1.11.1
|
||||
django-debug-toolbar==1.8
|
||||
django-ical==1.4
|
||||
django-recaptcha==1.3.0
|
||||
django-registration-redux==1.6
|
||||
django-reversion==1.10.2
|
||||
django-toolbelt==0.0.1
|
||||
django-widget-tweaks==1.3
|
||||
gunicorn==19.3.0
|
||||
icalendar==3.9.0
|
||||
lxml==3.4.4
|
||||
Pillow==2.8.1
|
||||
premailer==3.0.1
|
||||
psycopg2==2.6
|
||||
Pygments==2.0.2
|
||||
PyPDF2==1.24
|
||||
python-dateutil==2.4.2
|
||||
pytz==2015.4
|
||||
raven==5.8.1
|
||||
reportlab==3.1.44
|
||||
selenium==2.53.6
|
||||
simplejson==3.7.2
|
||||
six==1.9.0
|
||||
sqlparse==0.1.15
|
||||
static3==0.6.1
|
||||
django-widget-tweaks==1.4.1
|
||||
gunicorn==19.7.1
|
||||
icalendar==3.11.4
|
||||
lxml==3.7.3
|
||||
Markdown==2.6.8
|
||||
Pillow==4.1.1
|
||||
psycopg2==2.7.1
|
||||
Pygments==2.2.0
|
||||
PyPDF2==1.26.0
|
||||
python-dateutil==2.6.0
|
||||
pytz==2017.2
|
||||
raven==6.0.0
|
||||
reportlab==3.4.0
|
||||
selenium==2.53.1
|
||||
simplejson==3.10.0
|
||||
six==1.10.0
|
||||
sqlparse==0.2.3
|
||||
static3==0.7.0
|
||||
svg2rlg==0.3
|
||||
yolk==0.4.3
|
||||
z3c.rml==2.8.1
|
||||
zope.event==4.0.3
|
||||
zope.interface==4.1.2
|
||||
z3c.rml==3.2.0
|
||||
zope.event==4.2.0
|
||||
zope.interface==4.4.0
|
||||
zope.schema==4.4.2
|
||||
|
||||
Reference in New Issue
Block a user