mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-02-17 12:09:41 +00:00
Compare commits
5 Commits
dependabot
...
55f45963a0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55f45963a0 | ||
|
|
54e0c9ff9d | ||
|
|
6bb69ec8a1 | ||
|
|
c18d7a75b8 | ||
|
|
2d83dad44c |
29
.github/workflows/django.yml
vendored
29
.github/workflows/django.yml
vendored
@@ -18,37 +18,34 @@ jobs:
|
|||||||
- name: Install build dependencies
|
- name: Install build dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install libcairo2-dev
|
sudo apt-get install libcairo2-dev
|
||||||
|
- name: Set up Python
|
||||||
- name: "Set up Python"
|
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version-file: ".python-version"
|
python-version: "3.10"
|
||||||
|
cache: 'pipenv'
|
||||||
- name: Install uv
|
|
||||||
uses: astral-sh/setup-uv@v6
|
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: uv sync --locked --all-extras --dev
|
run: |
|
||||||
|
python3 -m pip install --upgrade pip pipenv
|
||||||
|
pipenv install -d
|
||||||
|
# if: steps.pcache.outputs.cache-hit != 'true'
|
||||||
- name: Cache Static Files
|
- name: Cache Static Files
|
||||||
id: static-cache
|
id: static-cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: 'pipeline/built_assets'
|
path: 'pipeline/built_assets'
|
||||||
key: ${{ hashFiles('package-lock.json') }}-${{ hashFiles('pipeline/source_assets') }}
|
key: ${{ hashFiles('package-lock.json') }}-${{ hashFiles('pipeline/source_assets') }}
|
||||||
|
|
||||||
- uses: bahmutov/npm-install@v1
|
- uses: bahmutov/npm-install@v1
|
||||||
if: steps.static-cache.outputs.cache-hit != 'true'
|
if: steps.static-cache.outputs.cache-hit != 'true'
|
||||||
- run: node node_modules/gulp/bin/gulp build
|
- run: node node_modules/gulp/bin/gulp build
|
||||||
if: steps.static-cache.outputs.cache-hit != 'true'
|
if: steps.static-cache.outputs.cache-hit != 'true'
|
||||||
- name: Basic Checks
|
- name: Basic Checks
|
||||||
run: |
|
run: |
|
||||||
uv run pycodestyle . --exclude=.venv,migrations,node_modules
|
pipenv run pycodestyle . --exclude=migrations,node_modules
|
||||||
uv run python3 manage.py check
|
pipenv run python3 manage.py check
|
||||||
uv run python3 manage.py makemigrations --check --dry-run
|
pipenv run python3 manage.py makemigrations --check --dry-run
|
||||||
uv run python3 manage.py collectstatic --noinput
|
pipenv run python3 manage.py collectstatic --noinput
|
||||||
- name: Run Tests
|
- name: Run Tests
|
||||||
run: uv run pytest -n auto --cov
|
run: pipenv run pytest -n auto --cov
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
@@ -56,4 +53,4 @@ jobs:
|
|||||||
path: screenshots/
|
path: screenshots/
|
||||||
retention-days: 5
|
retention-days: 5
|
||||||
- name: Coveralls
|
- name: Coveralls
|
||||||
run: uv run coveralls --service=github
|
run: pipenv run coveralls --service=github
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -101,6 +101,3 @@ crashlytics.properties
|
|||||||
crashlytics-build.properties
|
crashlytics-build.properties
|
||||||
.vscode/
|
.vscode/
|
||||||
screenshots/
|
screenshots/
|
||||||
|
|
||||||
# Virutal Environments
|
|
||||||
.venv/
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
3.10
|
|
||||||
104
Pipfile
Normal file
104
Pipfile
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
[[source]]
|
||||||
|
url = "https://pypi.python.org/simple"
|
||||||
|
verify_ssl = true
|
||||||
|
name = "pypi"
|
||||||
|
|
||||||
|
[packages]
|
||||||
|
ansicolors = "~=1.1.8"
|
||||||
|
asgiref = "~=3.3.1"
|
||||||
|
"backports.tempfile" = "~=1.0"
|
||||||
|
"backports.weakref" = "~=1.0.post1"
|
||||||
|
beautifulsoup4 = "~=4.9.3"
|
||||||
|
Brotli = "~=1.0.9"
|
||||||
|
cachetools = "~=4.2.1"
|
||||||
|
chardet = "~=4.0.0"
|
||||||
|
configparser = "~=5.0.1"
|
||||||
|
contextlib2 = "~=0.6.0.post1"
|
||||||
|
cssselect = "~=1.1.0"
|
||||||
|
cssutils = "~=1.0.2"
|
||||||
|
dj-database-url = "~=0.5.0"
|
||||||
|
dj-static = "~=0.0.6"
|
||||||
|
Django = "~=3.2"
|
||||||
|
django-debug-toolbar = "~=4.0.0"
|
||||||
|
django-filter = "~=2.4.0"
|
||||||
|
django-ical = "~=1.7.1"
|
||||||
|
django-recurrence = "~=1.10.3"
|
||||||
|
django-registration-redux = "~=2.9"
|
||||||
|
django-reversion = "~=3.0.9"
|
||||||
|
django-widget-tweaks = "~=1.4.8"
|
||||||
|
django-htmlmin = "~=0.11.0"
|
||||||
|
envparse = "*"
|
||||||
|
gunicorn = "~=22.0.0"
|
||||||
|
icalendar = "~=4.0.7"
|
||||||
|
idna = "~=3.7"
|
||||||
|
Markdown = "~=3.3.3"
|
||||||
|
msgpack = "~=1.0.2"
|
||||||
|
pep517 = "~=0.9.1"
|
||||||
|
Pillow = "~=10.0.1"
|
||||||
|
premailer = "~=3.7.0"
|
||||||
|
progress = "~=1.5"
|
||||||
|
psutil = "~=5.8.0"
|
||||||
|
psycopg2 = "~=2.8.6"
|
||||||
|
Pygments = "~=2.15.0"
|
||||||
|
pyparsing = "~=2.4.7"
|
||||||
|
PyPDF2 = "~=1.27.5"
|
||||||
|
PyPOM = "~=2.2.4"
|
||||||
|
python-dateutil = "~=2.8.1"
|
||||||
|
pytoml = "~=0.1.21"
|
||||||
|
pytz = "~=2020.5"
|
||||||
|
reportlab = "*"
|
||||||
|
requests = "~=2.32.3"
|
||||||
|
retrying = "~=1.3.3"
|
||||||
|
simplejson = "~=3.17.2"
|
||||||
|
six = "~=1.15.0"
|
||||||
|
soupsieve = "~=2.1"
|
||||||
|
sqlparse = "~=0.5.0"
|
||||||
|
static3 = "~=0.7.0"
|
||||||
|
svg2rlg = "~=0.3"
|
||||||
|
tini = "~=3.0.1"
|
||||||
|
tornado = "~=6.3"
|
||||||
|
urllib3 = "~=1.26.19"
|
||||||
|
whitenoise = "~=5.2.0"
|
||||||
|
yolk = "~=0.4.3"
|
||||||
|
zipp = "~=3.4.0"
|
||||||
|
"zope.component" = "~=4.6.2"
|
||||||
|
"zope.deferredimport" = "~=4.3.1"
|
||||||
|
"zope.deprecation" = "~=4.4.0"
|
||||||
|
"zope.event" = "~=4.5.0"
|
||||||
|
"zope.hookable" = "~=5.0.1"
|
||||||
|
"zope.interface" = "~=5.2.0"
|
||||||
|
"zope.proxy" = "~=4.3.5"
|
||||||
|
"zope.schema" = "~=6.0.1"
|
||||||
|
sentry-sdk = "*"
|
||||||
|
diff-match-patch = "*"
|
||||||
|
python-barcode = "*"
|
||||||
|
django-hCaptcha = "*"
|
||||||
|
importlib-metadata = "*"
|
||||||
|
django-hcaptcha = "*"
|
||||||
|
"z3c.rml" = "*"
|
||||||
|
pikepdf = "*"
|
||||||
|
django-queryable-properties = "*"
|
||||||
|
django-mass-edit = "*"
|
||||||
|
selenium = "~=4.9.1"
|
||||||
|
|
||||||
|
[dev-packages]
|
||||||
|
pycodestyle = "~=2.9.1"
|
||||||
|
coveralls = "*"
|
||||||
|
django-coverage-plugin = "*"
|
||||||
|
pytest-cov = "*"
|
||||||
|
pytest-django = "*"
|
||||||
|
pluggy = "*"
|
||||||
|
pytest-splinter = "*"
|
||||||
|
pytest = "*"
|
||||||
|
pytest-reverse = "*"
|
||||||
|
|
||||||
|
[requires]
|
||||||
|
python_version = "3.10"
|
||||||
|
|
||||||
|
[dev-packages.pytest-xdist]
|
||||||
|
extras = [ "psutil",]
|
||||||
|
version = "*"
|
||||||
|
|
||||||
|
[dev-packages.PyPOM]
|
||||||
|
extras = [ "splinter",]
|
||||||
|
version = "*"
|
||||||
2309
Pipfile.lock
generated
Normal file
2309
Pipfile.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -79,9 +79,7 @@ def api_key_required(function):
|
|||||||
"""
|
"""
|
||||||
Decorator for views that checks api_pk and api_key.
|
Decorator for views that checks api_pk and api_key.
|
||||||
Failed users will be given a 403 error.
|
Failed users will be given a 403 error.
|
||||||
Should only be used for urls which include <api_pk> and <api_key> kwargs.
|
Should only be used for urls which include <api_pk> and <api_key> kwargs
|
||||||
|
|
||||||
Will update the kwargs to include the user object if successful (under the key 'user').
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def wrap(request, *args, **kwargs):
|
def wrap(request, *args, **kwargs):
|
||||||
@@ -99,7 +97,6 @@ def api_key_required(function):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
user_object = models.Profile.objects.get(pk=userid)
|
user_object = models.Profile.objects.get(pk=userid)
|
||||||
kwargs = {**kwargs, 'user': user_object}
|
|
||||||
except models.Profile.DoesNotExist:
|
except models.Profile.DoesNotExist:
|
||||||
return error_resp
|
return error_resp
|
||||||
|
|
||||||
|
|||||||
@@ -104,10 +104,7 @@ DATABASES = {
|
|||||||
if not DEBUG:
|
if not DEBUG:
|
||||||
import dj_database_url
|
import dj_database_url
|
||||||
|
|
||||||
if env("FRANKENRIGS_DATABASE_URL") is not None:
|
DATABASES['default'] = dj_database_url.config()
|
||||||
DATABASES['default'] = dj_database_url.config(env="FRANKENRIGS_DATABASE_URL")
|
|
||||||
else:
|
|
||||||
DATABASES['default'] = dj_database_url.config()
|
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
LOGGING = {
|
LOGGING = {
|
||||||
@@ -227,7 +224,7 @@ USE_L10N = True
|
|||||||
|
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
USE_THOUSAND_SEPARATOR = False
|
USE_THOUSAND_SEPARATOR = True
|
||||||
|
|
||||||
# Need to allow seconds as datetime-local input type spits out a time that has seconds
|
# Need to allow seconds as datetime-local input type spits out a time that has seconds
|
||||||
DATETIME_INPUT_FORMATS = ('%Y-%m-%dT%H:%M', '%Y-%m-%dT%H:%M:%S')
|
DATETIME_INPUT_FORMATS = ('%Y-%m-%dT%H:%M', '%Y-%m-%dT%H:%M:%S')
|
||||||
|
|||||||
@@ -154,9 +154,9 @@ class AssociateAdmin(VersionAdmin):
|
|||||||
|
|
||||||
@admin.register(models.Profile)
|
@admin.register(models.Profile)
|
||||||
class ProfileAdmin(UserAdmin, AssociateAdmin):
|
class ProfileAdmin(UserAdmin, AssociateAdmin):
|
||||||
list_display = ('username', 'name', 'is_approved', 'is_superuser', 'is_supervisor', 'number_of_events', 'last_login', 'date_joined')
|
list_display = ('username', 'name', 'is_approved', 'is_superuser', 'is_supervisor', 'number_of_events', 'last_login')
|
||||||
list_display_links = ['username']
|
list_display_links = ['username']
|
||||||
list_filter = UserAdmin.list_filter + ('is_approved', 'date_joined')
|
list_filter = UserAdmin.list_filter + ('is_approved',)
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, {'fields': ('username', 'password')}),
|
(None, {'fields': ('username', 'password')}),
|
||||||
(_('Personal info'), {
|
(_('Personal info'), {
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ class EventForm(forms.ModelForm):
|
|||||||
datetime_input_formats = list(settings.DATETIME_INPUT_FORMATS)
|
datetime_input_formats = list(settings.DATETIME_INPUT_FORMATS)
|
||||||
meet_at = forms.DateTimeField(input_formats=datetime_input_formats, required=False)
|
meet_at = forms.DateTimeField(input_formats=datetime_input_formats, required=False)
|
||||||
access_at = forms.DateTimeField(input_formats=datetime_input_formats, required=False)
|
access_at = forms.DateTimeField(input_formats=datetime_input_formats, required=False)
|
||||||
parking_and_access = forms.BooleanField(label="Additional parking or access requirements (i.e. campus parking permits, wristbands)?", required=False)
|
|
||||||
|
|
||||||
items_json = forms.CharField()
|
items_json = forms.CharField()
|
||||||
|
|
||||||
@@ -126,7 +125,7 @@ class EventForm(forms.ModelForm):
|
|||||||
fields = ['is_rig', 'name', 'venue', 'start_time', 'end_date', 'start_date',
|
fields = ['is_rig', 'name', 'venue', 'start_time', 'end_date', 'start_date',
|
||||||
'end_time', 'meet_at', 'access_at', 'description', 'notes', 'mic',
|
'end_time', 'meet_at', 'access_at', 'description', 'notes', 'mic',
|
||||||
'person', 'organisation', 'dry_hire', 'checked_in_by', 'status',
|
'person', 'organisation', 'dry_hire', 'checked_in_by', 'status',
|
||||||
'purchase_order', 'collector', 'forum_url', 'parking_and_access']
|
'purchase_order', 'collector', 'forum_url']
|
||||||
|
|
||||||
|
|
||||||
class BaseClientEventAuthorisationForm(forms.ModelForm):
|
class BaseClientEventAuthorisationForm(forms.ModelForm):
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ class Command(BaseCommand):
|
|||||||
new_invoice.void = True
|
new_invoice.void = True
|
||||||
elif random.randint(0, 2) > 1: # 1 in 3 have been paid
|
elif random.randint(0, 2) > 1: # 1 in 3 have been paid
|
||||||
models.Payment.objects.create(invoice=new_invoice, amount=new_invoice.balance,
|
models.Payment.objects.create(invoice=new_invoice, amount=new_invoice.balance,
|
||||||
date=datetime.date.today(), method=random.choice(models.Payment.METHODS)[0])
|
date=datetime.date.today())
|
||||||
if i == 1 or random.randint(0, 5) > 0: # Event 1 and 1 in 5 have a RA
|
if i == 1 or random.randint(0, 5) > 0: # Event 1 and 1 in 5 have a RA
|
||||||
models.RiskAssessment.objects.create(event=new_event, supervisor_consulted=bool(random.getrandbits(1)),
|
models.RiskAssessment.objects.create(event=new_event, supervisor_consulted=bool(random.getrandbits(1)),
|
||||||
nonstandard_equipment=bool(random.getrandbits(1)),
|
nonstandard_equipment=bool(random.getrandbits(1)),
|
||||||
@@ -276,7 +276,6 @@ class Command(BaseCommand):
|
|||||||
nonstandard_emergency_procedure=bool(random.getrandbits(1)),
|
nonstandard_emergency_procedure=bool(random.getrandbits(1)),
|
||||||
special_structures=bool(random.getrandbits(1)),
|
special_structures=bool(random.getrandbits(1)),
|
||||||
suspended_structures=bool(random.getrandbits(1)),
|
suspended_structures=bool(random.getrandbits(1)),
|
||||||
parking_and_access=bool(random.getrandbits(1)),
|
|
||||||
outside=bool(random.getrandbits(1)))
|
outside=bool(random.getrandbits(1)))
|
||||||
if i == 0 or random.randint(0, 1) > 0: # Event 1 and 1 in 10 have a Checklist
|
if i == 0 or random.randint(0, 1) > 0: # Event 1 and 1 in 10 have a Checklist
|
||||||
models.EventChecklist.objects.create(event=new_event,
|
models.EventChecklist.objects.create(event=new_event,
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 3.2.25 on 2024-11-20 20:17
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('RIGS', '0051_alter_payment_method'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='event',
|
|
||||||
name='parking_and_access',
|
|
||||||
field=models.BooleanField(default=False),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# Generated by Django 3.2.25 on 2024-11-20 21:18
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('RIGS', '0052_event_parking_and_access'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='riskassessment',
|
|
||||||
name='parking_and_access',
|
|
||||||
field=models.BooleanField(default=False, help_text='Are there additional requirements for parking and access to the venue? (i.e. campus parking permits, event access wristbands)'),
|
|
||||||
preserve_default=False,
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -351,9 +351,6 @@ class Event(models.Model, RevisionMixin):
|
|||||||
access_at = models.DateTimeField(blank=True, null=True)
|
access_at = models.DateTimeField(blank=True, null=True)
|
||||||
meet_at = models.DateTimeField(blank=True, null=True)
|
meet_at = models.DateTimeField(blank=True, null=True)
|
||||||
|
|
||||||
# Venue requirements
|
|
||||||
parking_and_access = models.BooleanField(default=False)
|
|
||||||
|
|
||||||
# Crew management
|
# Crew management
|
||||||
checked_in_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='event_checked_in', blank=True, null=True,
|
checked_in_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='event_checked_in', blank=True, null=True,
|
||||||
on_delete=models.CASCADE)
|
on_delete=models.CASCADE)
|
||||||
@@ -379,10 +376,6 @@ class Event(models.Model, RevisionMixin):
|
|||||||
return self.pk
|
return self.pk
|
||||||
return "????"
|
return "????"
|
||||||
|
|
||||||
@property
|
|
||||||
def needs_mic(self):
|
|
||||||
return self.is_rig and not self.dry_hire
|
|
||||||
|
|
||||||
# Calculated values
|
# Calculated values
|
||||||
"""
|
"""
|
||||||
EX Vat
|
EX Vat
|
||||||
@@ -512,7 +505,7 @@ class Event(models.Model, RevisionMixin):
|
|||||||
def can_check_in(self):
|
def can_check_in(self):
|
||||||
earliest = self.earliest_time
|
earliest = self.earliest_time
|
||||||
if isinstance(self.earliest_time, datetime.date):
|
if isinstance(self.earliest_time, datetime.date):
|
||||||
earliest = datetime.datetime.combine(self.earliest_time, datetime.time(00, 00))
|
earliest = datetime.datetime.combine(self.start_date, datetime.time(00, 00))
|
||||||
tz = pytz.timezone(settings.TIME_ZONE)
|
tz = pytz.timezone(settings.TIME_ZONE)
|
||||||
earliest = tz.localize(earliest)
|
earliest = tz.localize(earliest)
|
||||||
return not self.dry_hire and not self.status == Event.CANCELLED and earliest <= timezone.now()
|
return not self.dry_hire and not self.status == Event.CANCELLED and earliest <= timezone.now()
|
||||||
@@ -786,9 +779,6 @@ class RiskAssessment(ReviewableModel, RevisionMixin):
|
|||||||
persons_responsible_structures = models.TextField(blank=True, default='', help_text="Who are the persons on site responsible for their use?")
|
persons_responsible_structures = models.TextField(blank=True, default='', help_text="Who are the persons on site responsible for their use?")
|
||||||
rigging_plan = models.URLField(blank=True, default='', help_text="Upload your rigging plan to the <a href='https://nottinghamtec.sharepoint.com/'>Sharepoint</a> and submit a link", validators=[validate_url])
|
rigging_plan = models.URLField(blank=True, default='', help_text="Upload your rigging plan to the <a href='https://nottinghamtec.sharepoint.com/'>Sharepoint</a> and submit a link", validators=[validate_url])
|
||||||
|
|
||||||
# Venue Access
|
|
||||||
parking_and_access = models.BooleanField(help_text="Are there additional requirements for parking and access to the venue? (i.e. campus parking permits, event access wristbands)")
|
|
||||||
|
|
||||||
# Blimey that was a lot of options
|
# Blimey that was a lot of options
|
||||||
|
|
||||||
supervisor_consulted = models.BooleanField(null=True)
|
supervisor_consulted = models.BooleanField(null=True)
|
||||||
@@ -813,7 +803,6 @@ class RiskAssessment(ReviewableModel, RevisionMixin):
|
|||||||
'nonstandard_emergency_procedure': False,
|
'nonstandard_emergency_procedure': False,
|
||||||
'special_structures': False,
|
'special_structures': False,
|
||||||
'suspended_structures': False,
|
'suspended_structures': False,
|
||||||
'parking_and_access': False
|
|
||||||
}
|
}
|
||||||
inverted_fields = {key: value for (key, value) in expected_values.items() if not value}.keys()
|
inverted_fields = {key: value for (key, value) in expected_values.items() if not value}.keys()
|
||||||
|
|
||||||
|
|||||||
@@ -87,8 +87,6 @@
|
|||||||
|
|
||||||
<listStyle name="ul"
|
<listStyle name="ul"
|
||||||
start="bulletchar"
|
start="bulletchar"
|
||||||
leftIndent="0"
|
|
||||||
bulletDedent="10"
|
|
||||||
bulletFontSize="10"/>
|
bulletFontSize="10"/>
|
||||||
</stylesheet>
|
</stylesheet>
|
||||||
|
|
||||||
|
|||||||
@@ -6,36 +6,7 @@
|
|||||||
{% load total_invoices_todo from filters %}
|
{% load total_invoices_todo from filters %}
|
||||||
|
|
||||||
{% block titleheader %}
|
{% block titleheader %}
|
||||||
<style>
|
<a class="navbar-brand" style="margin-left: auto; margin-right: auto;" href="/">RIGS</a>
|
||||||
.franken {
|
|
||||||
font-family: Fontdiner Swanky;
|
|
||||||
color: #00ff00;
|
|
||||||
animation: glow 1.5s infinite alternate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes glow {
|
|
||||||
0% {
|
|
||||||
text-shadow: 0 0 5px #00ff00,
|
|
||||||
0 0 10px #00ff00,
|
|
||||||
0 0 20px #00ff00,
|
|
||||||
0 0 40px #00ff00;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
text-shadow: 0 0 10px #00ff00,
|
|
||||||
0 0 20px #00ff00,
|
|
||||||
0 0 30px #00ff00,
|
|
||||||
0 0 60px #00ff00;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
text-shadow: 0 0 5px #00ff00,
|
|
||||||
0 0 10px #00ff00,
|
|
||||||
0 0 20px #00ff00,
|
|
||||||
0 0 40px #00ff00;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<a class="navbar-brand" style="margin-left: auto; margin-right: auto;" href="/"><span class="franken">Franken</span>RIGS</a>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block titleelements %}
|
{% block titleelements %}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
{% block preload_js %}
|
{% block preload_js %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
<script src="{% static 'js/selects.js' %}"></script>
|
<script src="{% static 'js/selects.js' %}" async></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|||||||
@@ -1,21 +1,9 @@
|
|||||||
{% extends request.is_ajax|yesno:"base_ajax.html,base_rigs.html" %}
|
{% extends request.is_ajax|yesno:"base_ajax.html,base_rigs.html" %}
|
||||||
|
|
||||||
{% load markdown_tags %}
|
{% load markdown_tags %}
|
||||||
|
{% load button from filters %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
|
||||||
{% block js %}
|
|
||||||
{{ block.super }}
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(document).keydown(function(e) {
|
|
||||||
if ((e.ctrlKey || e.metaKey) && e.keyCode == 80) {
|
|
||||||
window.open("{% url 'event_print' object.pk %}", '_blank');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row my-3 py-3">
|
<div class="row my-3 py-3">
|
||||||
{% if not request.is_ajax %}
|
{% if not request.is_ajax %}
|
||||||
@@ -27,11 +15,8 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% if object.is_rig and perms.RIGS.view_event %}
|
{% if object.is_rig and perms.RIGS.view_event %}
|
||||||
{# only need contact details for a rig #}
|
{# only need contact details for a rig #}
|
||||||
<div class="col-md-6 mb-3">
|
<div class="col-md-6">
|
||||||
{% include 'partials/contact_details.html' %}
|
{% include 'partials/contact_details.html' %}
|
||||||
{% if object.parking_and_access or object.riskassessment.parking_and_access %}
|
|
||||||
{% include 'partials/parking_and_access.html' %}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
@@ -69,9 +54,43 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% if event.can_check_in %}
|
||||||
{% include 'partials/crew_list.html' %}
|
<div class="col-sm-12">
|
||||||
|
<div class="card mt-3">
|
||||||
|
<div class="card-header">Crew Record</div>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-sm">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Name</th>
|
||||||
|
<th scope="col">Vehicle</th>
|
||||||
|
<th scope="col">Start Time</th>
|
||||||
|
<th scope="col">Role</th>
|
||||||
|
<th scope="col">End Time</th>
|
||||||
|
<th scope="col">{% if request.user.pk is event.mic.pk %}<a href="{% url 'event_checkin_override' event.pk %}" class="btn btn-sm btn-success"><span class="fas fa-plus"></span> Add</a>{% endif %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="crewmembers">
|
||||||
|
{% for crew in object.crew.all %}
|
||||||
|
<tr>
|
||||||
|
<td>{{crew.person}}</td>
|
||||||
|
<td>{{crew.vehicle|default:"None"}}</td>
|
||||||
|
<td>{{crew.time}}</td>
|
||||||
|
<td>{{crew.role}}</td>
|
||||||
|
<td>{% if crew.end_time %}{{crew.end_time}}{% else %}<span class="text-success fas fa-clock" data-toggle="tooltip" title="This person is currently checked into this event"></span>{% endif %}</td>
|
||||||
|
<td>{% if crew.end_time %}{% if crew.person.pk == request.user.pk or event.mic.pk == request.user.pk %}{% button 'edit' 'edit_checkin' crew.pk clazz='btn-sm modal-href' %}{% endif %}{%endif%}</td>
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" class="text-center bg-warning">Apparently this event happened by magic...</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% if not request.is_ajax and perms.RIGS.view_event %}
|
{% if not request.is_ajax and perms.RIGS.view_event %}
|
||||||
<div class="col-sm-12 text-right">
|
<div class="col-sm-12 text-right">
|
||||||
{% include 'partials/event_detail_buttons.html' %}
|
{% include 'partials/event_detail_buttons.html' %}
|
||||||
|
|||||||
@@ -281,15 +281,8 @@
|
|||||||
{{ form.dry_hire.label }} {% render_field form.dry_hire %}
|
{{ form.dry_hire.label }} {% render_field form.dry_hire %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<div class="col-sm-offset-4 col-sm-8">
|
|
||||||
<label data-toggle="tooltip" title="Do we need to secure campus parking permits, wristbands for backstage access or other non-standard requirements?">
|
|
||||||
{{ form.parking_and_access.label }} {% render_field form.parking_and_access %}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{# Status is needed on all events types and it looks good here in the form #}
|
{# Status is needed on all events types and it looks good here in the form #}
|
||||||
<div class="form-group" data-toggle="tooltip" title="The current status of the event. Only mark as booked once paperwork is received">
|
<div class="form-group" data-toggle="tooltip" title="The current status of the event. Only mark as booked once paperwork is received">
|
||||||
|
|||||||
@@ -69,11 +69,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% include 'partials/crew_list.html' with event=object.event %}
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-12 text-right">
|
||||||
<div class="col-12 text-right mt-4">
|
|
||||||
{% button 'edit' url='ec_edit' pk=object.pk %}
|
{% button 'edit' url='ec_edit' pk=object.pk %}
|
||||||
{% button 'view' url='event_detail' pk=object.pk text="Event" %}
|
{% button 'view' url='event_detail' pk=object.pk text="Event" %}
|
||||||
<a href="{% url 'event_pt' object.event.pk %}" class="btn btn-info"><span class="fas fa-paperclip"></span> <span
|
<a href="{% url 'event_pt' object.event.pk %}" class="btn btn-info"><span class="fas fa-paperclip"></span> <span
|
||||||
|
|||||||
@@ -2,13 +2,8 @@
|
|||||||
{% load filters %}
|
{% load filters %}
|
||||||
|
|
||||||
{% block extrastyles %}
|
{% block extrastyles %}
|
||||||
<paraStyle name="style.powerReviewed" borderPadding="3" alignment="center" backColor="green" textColor="white"/>
|
<paraStyle name="style.powerReviewed" alignment="center" backColor="green" textColor="white"/>
|
||||||
<paraStyle name="style.powerUnreviewed" borderPadding="3" alignment="center" backColor="red" textColor="white"/>
|
<paraStyle name="style.powerUnreviewed" alignment="center" backColor="red" textColor="white"/>
|
||||||
<paraStyle name="style.smallText" fontSize="8"/>
|
|
||||||
|
|
||||||
<paraStyle leftIndent="2in" rightIndent="2in" name="style.smallEvent" fontSize="10" alignment="center" backColor="green" textColor="white" borderPadding="4" borderColor="black"/>
|
|
||||||
<paraStyle leftIndent="2in" rightIndent="2in" name="style.mediumEvent" fontSize="10" alignment="center" backColor="orange" textColor="white" borderPadding="4" borderColor="black"/>
|
|
||||||
<paraStyle leftIndent="2in" rightIndent="2in" name="style.largeEvent" fontSize="10" alignment="center" backColor="red" textColor="white" borderPadding="4" borderColor="black"/>
|
|
||||||
|
|
||||||
<blockTableStyle id="powerTable">
|
<blockTableStyle id="powerTable">
|
||||||
<blockValign value="middle"/>
|
<blockValign value="middle"/>
|
||||||
@@ -17,10 +12,6 @@
|
|||||||
<lineStyle kind="LINEAFTER" colorName="black" thickness="1"/>
|
<lineStyle kind="LINEAFTER" colorName="black" thickness="1"/>
|
||||||
<lineStyle kind="LINEBEFORE" colorName="black" thickness="1"/>
|
<lineStyle kind="LINEBEFORE" colorName="black" thickness="1"/>
|
||||||
</blockTableStyle>
|
</blockTableStyle>
|
||||||
|
|
||||||
<blockTableStyle id="voltageTable">
|
|
||||||
<blockValign value="middle"/>
|
|
||||||
</blockTableStyle>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
@@ -43,16 +34,6 @@
|
|||||||
<h2 fontSize="16">Power Plan Information</h2>
|
<h2 fontSize="16">Power Plan Information</h2>
|
||||||
<spacer length="15"/>
|
<spacer length="15"/>
|
||||||
|
|
||||||
{% if object.event.riskassessment.event_size == 0 %}
|
|
||||||
<para style="style.smallEvent"><strong>Small Event</strong></para>
|
|
||||||
{% elif object.event.riskassessment.event_size == 1 %}
|
|
||||||
<para style="style.mediumEvent"><strong>Medium Event</strong></para>
|
|
||||||
{% elif object.event.riskassessment.event_size == 2 %}
|
|
||||||
<para style="style.largeEvent"><strong>Large Event</strong></para>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<spacer length="15"/>
|
|
||||||
|
|
||||||
<blockTable colWidths="250,250">
|
<blockTable colWidths="250,250">
|
||||||
<tr>
|
<tr>
|
||||||
<td><para><strong>Power MIC:</strong> {{ object.power_mic }}</para></td>
|
<td><para><strong>Power MIC:</strong> {{ object.power_mic }}</para></td>
|
||||||
@@ -70,69 +51,38 @@
|
|||||||
</blockTable>
|
</blockTable>
|
||||||
|
|
||||||
<spacer length="15"/>
|
<spacer length="15"/>
|
||||||
|
|
||||||
{% if object.notes %}
|
|
||||||
<hr/>
|
<hr/>
|
||||||
<spacer length="15"/>
|
<spacer length="15"/>
|
||||||
<para><strong>Additional Notes:</strong></para>
|
|
||||||
<spacer length="15"/>
|
|
||||||
<para>{{ object.notes }}</para>
|
|
||||||
<spacer length="15"/>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
<spacer length="15"/>
|
|
||||||
|
|
||||||
{% comment %}
|
|
||||||
0 - Small event
|
|
||||||
1 - Medium event (extra power records)
|
|
||||||
2 - Large event (extra power records)
|
|
||||||
{% endcomment %}
|
|
||||||
|
|
||||||
{% if object.event.riskassessment.event_size >= 1 %}
|
|
||||||
|
|
||||||
<para alignment="center"><strong>Power Test results enclosed on next page</strong></para>
|
|
||||||
|
|
||||||
<condPageBreak height="10in"/>
|
<condPageBreak height="10in"/>
|
||||||
|
|
||||||
<h2 fontSize="16">Event Power Checklist</h2>
|
<h2 fontSize="16">Power Test Results</h2>
|
||||||
<spacer length="15"/>
|
<spacer length="15"/>
|
||||||
|
|
||||||
<blockTable colWidths="250,270" style="powerTable">
|
<para><strong>Source RCD protected?</strong> {{ object.source_rcd|yesno|capfirst }}</para>
|
||||||
<tr>
|
<para><sub>(If cable is more than 3 metres long)</sub></para>
|
||||||
<td><para><strong>All circuit RCDs tested?</strong></para><para style="style.smallText">(using test button)</para></td>
|
|
||||||
<td><para>{{ object.all_rcds_tested|yesno|capfirst }}</para></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><para><strong>Public/performer accessible circuits tested?</strong></para><para style="style.smallText">(using socket tester)</para></td>
|
|
||||||
<td><para>{{ object.public_sockets_tested|yesno|capfirst }}</para></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><para><strong>Source RCD protected?</strong></para><para style="style.smallText">(if cable is more than 3m long)</para></td>
|
|
||||||
<td><para>{{ object.source_rcd|yesno|capfirst }}</para></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><para><strong>Appropriate and clear labelling on distribution and cabling?</strong></para></td>
|
|
||||||
<td><para>{{ object.labelling|yesno|capfirst }}</para></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><para><strong>Equipment appropriately earthed?</strong></para><para style="style.smallText">(truss, stage, generators, etc.)</para></td>
|
|
||||||
<td><para>{{ object.earthing|yesno|capfirst }}</para></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><para><strong>All equipment in PAT period?</strong><br/><br/></para></td>
|
|
||||||
<td><para>{{ object.pat|yesno|capfirst }}</para></td>
|
|
||||||
</tr>
|
|
||||||
</blockTable>
|
|
||||||
|
|
||||||
<spacer length="15"/>
|
|
||||||
|
|
||||||
<h2 fontSize="14">Power tests (First Distro)</h2>
|
|
||||||
<spacer length="5"/>
|
<spacer length="5"/>
|
||||||
|
|
||||||
<blockTable colWidths="100,410" style="voltageTable">
|
<para><strong>Appropriate and clear labelling on distribution and cabling?</strong> {{ object.labelling|yesno|capfirst }}</para>
|
||||||
|
|
||||||
|
<spacer length="5"/>
|
||||||
|
|
||||||
|
<para><strong>Equipment appropriately earthed?</strong> {{ object.source_rcd|yesno|capfirst }}</para>
|
||||||
|
<para><sub>(truss, stage, generators etc.)</sub></para>
|
||||||
|
|
||||||
|
<spacer length="5"/>
|
||||||
|
|
||||||
|
<para><strong>All equipment in PAT period?</strong> {{ object.pat|yesno|capfirst }}</para>
|
||||||
|
|
||||||
|
<spacer length="15"/>
|
||||||
|
|
||||||
|
<h2 fontSize="14">Tests at first distro</h2>
|
||||||
|
<spacer length="5"/>
|
||||||
|
|
||||||
|
<blockTable colWidths="100,410">
|
||||||
<tr>
|
<tr>
|
||||||
<td><para><strong>Voltage</strong></para><para style="style.smallText">(cube meter) / V</para></td>
|
<td><para><strong>Voltage<br/><sub>(cube meter) / V</sub></strong></para></td>
|
||||||
<td>
|
<td>
|
||||||
<blockTable colWidths="100,100,100" style="powerTable">
|
<blockTable colWidths="100,100,100" style="powerTable">
|
||||||
<tr>
|
<tr>
|
||||||
@@ -150,11 +100,11 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</blockTable>
|
</blockTable>
|
||||||
|
|
||||||
<spacer length="10"/>
|
<spacer length="15"/>
|
||||||
|
|
||||||
<blockTable colWidths="100,100,190,120" style="voltageTable">
|
<blockTable colWidths="100,100,190,120">
|
||||||
<tr>
|
<tr>
|
||||||
<td><para><strong>Phase Rotation</strong></para><para style="style.smallText">(if required)</para></td>
|
<td><para><strong>Phase Rotation<br/><sub>(if required)</sub></strong></para></td>
|
||||||
<td><para>{{ object.fd_phase_rotation|yesno|capfirst }}</para></td>
|
<td><para>{{ object.fd_phase_rotation|yesno|capfirst }}</para></td>
|
||||||
<td><para><strong>Earth Fault Loop Impedance (Z<sub>s</sub>) / Ω</strong></para></td>
|
<td><para><strong>Earth Fault Loop Impedance (Z<sub>s</sub>) / Ω</strong></para></td>
|
||||||
<td><para>{{ object.fd_earth_fault }}</para></td>
|
<td><para>{{ object.fd_earth_fault }}</para></td>
|
||||||
@@ -163,11 +113,11 @@
|
|||||||
|
|
||||||
<spacer length="15"/>
|
<spacer length="15"/>
|
||||||
|
|
||||||
<para><strong>Prospective Short Circuit Current (PSCC)</strong> {{ object.fd_pssc }} A</para>
|
<para><strong>Prospective Short Circuit Current / A</strong> {{ object.fd_pssc }}</para>
|
||||||
|
|
||||||
<spacer length="15"/>
|
<spacer length="15"/>
|
||||||
|
|
||||||
<h2 fontSize="14">Power Tests (Worst Case Points)</h2>
|
<h2 fontSize="14">Tests 'Worst Case' points (at least 1 required)</h2>
|
||||||
<spacer length="15"/>
|
<spacer length="15"/>
|
||||||
|
|
||||||
<blockTable colWidths="100,100,190,120" style="powerTable">
|
<blockTable colWidths="100,100,190,120" style="powerTable">
|
||||||
@@ -203,33 +153,18 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</blockTable>
|
</blockTable>
|
||||||
|
|
||||||
{% else %}
|
<spacer length="15"/>
|
||||||
|
<h2 fontSize="14">Generic Tests</h2>
|
||||||
{% comment %}
|
|
||||||
Small power test
|
|
||||||
{% endcomment %}
|
|
||||||
|
|
||||||
<h2 fontSize="16">Power Checklist</h2>
|
|
||||||
<spacer length="15"/>
|
<spacer length="15"/>
|
||||||
|
|
||||||
<blockTable colWidths="250,270" style="powerTable">
|
<blockTable colWidths="250,270" style="powerTable">
|
||||||
<tr>
|
<tr>
|
||||||
<td><para><strong>RCDs installed where needed and tested?</strong><br/><br/></para></td>
|
<td><para><strong>All circuit RCDs tested?</strong><br/>(using test button)</para></td>
|
||||||
<td><para>{{ object.rcds|yesno|capfirst }}</para></td>
|
<td><para>{{ object.all_rcds_tested|yesno|capfirst }}</para></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><para><strong>Electrical supplies tested?</strong><br/><br/></para></td>
|
<td><para><strong>Public/performer accessible circuits tested?</strong><br/>(using socket tester)</para></td>
|
||||||
<td><para>{{ object.supply_test|yesno|capfirst }}</para></td>
|
<td><para>{{ object.public_sockets_tested|yesno|capfirst }}</para></td>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><para><strong>Equipment appropriately earthed?</strong></para><para style="style.smallText">(truss, stage, generators, etc.)</para></td>
|
|
||||||
<td><para>{{ object.earthing|yesno|capfirst }}</para></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><para><strong>All equipment in PAT period?</strong><br/><br/></para></td>
|
|
||||||
<td><para>{{ object.pat|yesno|capfirst }}</para></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</blockTable>
|
</blockTable>
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -124,13 +124,6 @@
|
|||||||
<td><para>{{ object|help_text:'persons_responsible_structures'|striptags }}</para></td>
|
<td><para>{{ object|help_text:'persons_responsible_structures'|striptags }}</para></td>
|
||||||
<td><para>{{ object.persons_responsible_structures|default:'N/A' }}</para></td>
|
<td><para>{{ object.persons_responsible_structures|default:'N/A' }}</para></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td colspan="2"><h3><strong>Venue Access</strong></h3></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><para>{{ object|help_text:'parking_and_access'|striptags }}</para></td>
|
|
||||||
<td><para>{{ object.parking_and_access|yesno|capfirst }}</para></td>
|
|
||||||
</tr>
|
|
||||||
</blockTable>
|
</blockTable>
|
||||||
<spacer length="15"/>\
|
<spacer length="15"/>\
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|||||||
@@ -151,19 +151,8 @@
|
|||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card card-default mb-3">
|
|
||||||
<div class="card-header">Venue Access</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<dl class="row">
|
|
||||||
<dt class="col-10">{{ object|help_text:'parking_and_access' }}</dt>
|
|
||||||
<dd class="col-2">
|
|
||||||
{{ object.parking_and_access|yesnoi:'invert' }}
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 text-right">
|
<div class="col-12 text-right">
|
||||||
{% button 'print' 'ra_print' object.pk %}
|
{% button 'print' 'ra_print' object.pk %}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block preload_js %}
|
{% block preload_js %}
|
||||||
<script src="{% static 'js/selects.js' %}"></script>
|
<script src="{% static 'js/selects.js' %}" async></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
@@ -162,17 +162,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row my-3">
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header">Venue Access</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<p><strong>If yes to the below, ensure you have communicated with the client and secured all necessary access prior to the event commencing.</strong></p>
|
|
||||||
{% include 'partials/yes_no_radio.html' with formitem=form.parking_and_access %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mt-3">
|
<div class="row mt-3">
|
||||||
<div class="col-sm-12 text-right">
|
<div class="col-sm-12 text-right">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
{% extends 'base_rigs.html' %}
|
{% extends 'base_rigs.html' %}
|
||||||
|
|
||||||
{% load humanize %}
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<form method="GET" action="{% url 'invoice_dashboard' %}">
|
<form method="GET" action="{% url 'invoice_dashboard' %}">
|
||||||
@@ -29,20 +28,16 @@
|
|||||||
|
|
||||||
<div class="card-deck">
|
<div class="card-deck">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<a href="{% url 'invoice_waiting' %}" class="text-decoration-none text-white">
|
<div class="card-body bg-info">
|
||||||
<div class="card-body bg-primary">
|
<h5 class="card-title text-center">Total Outstanding</h5>
|
||||||
<h5 class="card-title text-center">Total Waiting</h5>
|
<p class="card-text text-center h3"><strong>£{{ total_outstanding|floatformat:2 }}</strong></p>
|
||||||
<p class="card-text text-center h3"><strong>£{{ total_waiting|floatformat:"2g" }}</strong></p>
|
</div>
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<a href="{% url 'invoice_list' %}" class="text-decoration-none text-dark">
|
<div class="card-body bg-primary">
|
||||||
<div class="card-body bg-info">
|
<h5 class="card-title text-center">Total Waiting</h5>
|
||||||
<h5 class="card-title text-center">Total Outstanding</h5>
|
<p class="card-text text-center h3"><strong>£{{ total_waiting|floatformat:2 }}</strong></p>
|
||||||
<p class="card-text text-center h3"><strong>£{{ total_outstanding|floatformat:"2g" }}</strong></p>
|
</div>
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body bg-danger">
|
<div class="card-body bg-danger">
|
||||||
@@ -72,7 +67,7 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title"><strong>{{ source.method }}</strong></h5>
|
<h5 class="card-title"><strong>{{ source.method }}</strong></h5>
|
||||||
<p class="card-text h3">£{{ source.total|floatformat:"2g" }}</p>
|
<p class="card-text h3">£{{ source.total|floatformat:2 }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -86,7 +81,7 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title text-center">Total Income</h5>
|
<h5 class="card-title text-center">Total Income</h5>
|
||||||
<p class="card-text text-center h3"><strong>£{{ total_income|floatformat:"2g" }}</strong></p>
|
<p class="card-text text-center h3"><strong>£{{ total_income|floatformat:2 }}</strong></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -99,7 +94,7 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title text-center">Average Time to Pay</h5>
|
<h5 class="card-title text-center">Average Time to Pay</h5>
|
||||||
<p class="card-text text-center h3"><strong>{{ mean_invoice_to_payment|floatformat:"2g" }} days</strong></p>
|
<p class="card-text text-center h3"><strong>{{ mean_invoice_to_payment|floatformat:2 }} days</strong></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if object.organisation %}
|
{% if object.organisation %}
|
||||||
<div class="card card-default mb-3">
|
<div class="card card-default">
|
||||||
<div class="card-header">Organisation Details</div>
|
<div class="card-header">Organisation Details</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<dl class="row">
|
<dl class="row">
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
{% load button from filters %}
|
|
||||||
|
|
||||||
{% if event.can_check_in %}
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="card mt-3">
|
|
||||||
<div class="card-header">Crew Record</div>
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-sm">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">Name</th>
|
|
||||||
<th scope="col">Vehicle</th>
|
|
||||||
<th scope="col">Start Time</th>
|
|
||||||
<th scope="col">Role</th>
|
|
||||||
<th scope="col">End Time</th>
|
|
||||||
<th scope="col">{% if request.user.pk is event.mic.pk %}<a
|
|
||||||
href="{% url 'event_checkin_override' event.pk %}" class="btn btn-sm btn-success"><span
|
|
||||||
class="fas fa-plus"></span> Add</a>{% endif %}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="crewmembers">
|
|
||||||
{% for crew in event.crew.all %}
|
|
||||||
<tr>
|
|
||||||
<td>{{crew.person}}</td>
|
|
||||||
<td>{{crew.vehicle|default:"None"}}</td>
|
|
||||||
<td>{{crew.time}}</td>
|
|
||||||
<td>{{crew.role}}</td>
|
|
||||||
<td>{% if crew.end_time %}
|
|
||||||
{{crew.end_time}}
|
|
||||||
{% else %}
|
|
||||||
<span class="text-success fas fa-clock" data-toggle="tooltip"
|
|
||||||
title="This person is currently checked into this event"></span>{% endif %}
|
|
||||||
</td>
|
|
||||||
<td>{% if crew.end_time %}
|
|
||||||
{% if crew.person.pk == request.user.pk or event.mic.pk == request.user.pk %}
|
|
||||||
{% button 'edit' 'edit_checkin' crew.pk clazz='btn-sm modal-href' %}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}</td>
|
|
||||||
</tr>
|
|
||||||
{% empty %}
|
|
||||||
<tr>
|
|
||||||
<td colspan="6" class="text-center bg-warning">Apparently this event happened by magic...</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
@@ -11,7 +11,6 @@
|
|||||||
{{ object.venue|namewithnotes:'venue_detail' }}
|
{{ object.venue|namewithnotes:'venue_detail' }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if object.parking_and_access or object.riskassessment.parking_and_access %}<span class="badge badge-warning">Additional Access Requirements</span>{% endif %}
|
|
||||||
</dd>
|
</dd>
|
||||||
{% if object.venue %}
|
{% if object.venue %}
|
||||||
<dt class="col-sm-6">Venue Notes</dt>
|
<dt class="col-sm-6">Venue Notes</dt>
|
||||||
|
|||||||
@@ -1,147 +0,0 @@
|
|||||||
{% load namewithnotes from filters %}
|
|
||||||
{% load markdown_tags %}
|
|
||||||
|
|
||||||
<div class="card h-100 border-3 {{ border_class }} event-row">
|
|
||||||
<div class="card-header {{ header_bg }} {{ header_text }} py-3">
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
<span class="d-flex align-items-center">
|
|
||||||
<h5 class="mb-0 mr-3">
|
|
||||||
<a href="{% url 'event_detail' event.pk %}"
|
|
||||||
class="{{ header_text }} text-decoration-underline fw-bold">
|
|
||||||
<strong>{{ event.display_id }}</strong> - {{ event.name }}
|
|
||||||
</a>
|
|
||||||
</h5>
|
|
||||||
{% if event.dry_hire %}
|
|
||||||
<span class="badge px-3 py-2 rounded-pill fs-6 text-dark bg-light">Dry Hire</span>
|
|
||||||
{% endif %}
|
|
||||||
</span>
|
|
||||||
<span class="badge fs-6 px-3 py-2 bg-light text-dark rounded-pill">{{ event.get_status_display }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row align-items-start">
|
|
||||||
|
|
||||||
<div class="col-md-2 border-end event-dates">
|
|
||||||
<div class="mb-2">
|
|
||||||
<small class="text-muted">Meet at:</small>
|
|
||||||
{% if event.meet_at %}
|
|
||||||
<p class="mb-1">{{ event.meet_at|date:"D j M Y, H:i" }}</p>
|
|
||||||
{% else %}
|
|
||||||
<p class="mb-1">Not specified</p>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="mb-2">
|
|
||||||
<small class="text-muted">Access from:</small>
|
|
||||||
{% if event.access_at %}
|
|
||||||
<p class="mb-1">{{ event.access_at|date:"D j M Y, H:i" }}</p>
|
|
||||||
{% else %}
|
|
||||||
<p class="mb-1">Not specified</p>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="mb-2">
|
|
||||||
<small class="text-muted">Start:</small>
|
|
||||||
<p class="mb-1">
|
|
||||||
{% if event.start_date and event.start_time %}
|
|
||||||
{{ event.start_date|date:"D j M Y" }}, {{ event.start_time|date:"H:i" }}
|
|
||||||
{% elif event.start_date %}
|
|
||||||
{{ event.start_date|date:"D j M Y" }}
|
|
||||||
{% elif event.start_time %}
|
|
||||||
{{ event.start_time|date:"H:i" }}
|
|
||||||
{% else %}
|
|
||||||
Not specified
|
|
||||||
{% endif %}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="mb-2">
|
|
||||||
<small class="text-muted">End:</small>
|
|
||||||
<p class="mb-1">
|
|
||||||
{% if event.end_date and event.end_time %}
|
|
||||||
{{ event.end_date|date:"D j M Y" }}, {{ event.end_time|date:"H:i" }}
|
|
||||||
{% elif event.end_date %}
|
|
||||||
{{ event.end_date|date:"D j M Y" }}
|
|
||||||
{% elif event.end_time %}
|
|
||||||
{{ event.end_time|date:"H:i" }}
|
|
||||||
{% else %}
|
|
||||||
Not specified
|
|
||||||
{% endif %}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col-md-10">
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col-md-6">
|
|
||||||
|
|
||||||
{% if event.venue %}
|
|
||||||
<div class="mb-3">
|
|
||||||
<small class="text-muted">Venue:</small>
|
|
||||||
<p class="mb-1">{{ event.venue|namewithnotes:'venue_detail' }}</p>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
|
|
||||||
{% if event.is_rig %}
|
|
||||||
<div class="mb-3">
|
|
||||||
<small class="text-muted">Client:</small>
|
|
||||||
<p class="mb-1">
|
|
||||||
{% if event.person %}
|
|
||||||
<a href="{{ event.person.get_absolute_url }}">{{ event.person.name }}</a>
|
|
||||||
{% if event.organisation %}
|
|
||||||
for <a href="{{ event.organisation.get_absolute_url }}">{{ event.organisation }}</a>
|
|
||||||
{% endif %}
|
|
||||||
{% elif event.organisation %}
|
|
||||||
<a href="{{ event.organisation.get_absolute_url }}">{{ event.organisation }}</a>
|
|
||||||
{% else %}
|
|
||||||
No client specified
|
|
||||||
{% endif %}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if event.mic or event.needs_mic %}
|
|
||||||
<div class="mb-3">
|
|
||||||
<small class="text-muted">Member in Charge (MIC):</small>
|
|
||||||
<div class="d-flex align-items-center mt-1">
|
|
||||||
{% if event.mic %}
|
|
||||||
<img src="{{ event.mic.profile_picture }}" alt="{{ event.mic.name }}"
|
|
||||||
class="rounded-circle mr-1" width="32" height="32">
|
|
||||||
<span>
|
|
||||||
{% if perms.RIGS.view_profile %}
|
|
||||||
<a href="{% url 'profile_detail' event.mic.pk %}" class="modal-href">
|
|
||||||
{% endif %}
|
|
||||||
{{ event.mic.name }}
|
|
||||||
{% if perms.RIGS.view_profile %}
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
</span>
|
|
||||||
{% else %}
|
|
||||||
<span class="text-danger">No MIC assigned</span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col-md-6">
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<small class="text-muted">Description:</small>
|
|
||||||
<p class="mb-1">{{ event.description|markdown }}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<small class="text-muted">Status:</small>
|
|
||||||
<div class="mt-1">
|
|
||||||
{% include "partials/event_status.html" with status=event.status %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
{% if event.is_rig %}
|
{% if event.is_rig %}
|
||||||
{% if event.sum_total > 0 %}
|
{% if event.sum_total > 0 %}
|
||||||
{% if event.purchase_order %}
|
{% if event.purchase_order %}
|
||||||
<span class="badge badge-success">PO: Received</span>
|
<span class="badge badge-success">PO: {{ event.purchase_order }}</span>
|
||||||
{% elif event.authorised %}
|
{% elif event.authorised %}
|
||||||
<span class="badge badge-success">Authorisation: Complete <span class="fas fa-check"></span></span>
|
<span class="badge badge-success">Authorisation: Complete <span class="fas fa-check"></span></span>
|
||||||
{% elif event.authorisation and event.authorisation.amount != event.total and event.authorisation.last_edited_at > event.auth_request_at %}
|
{% elif event.authorisation and event.authorisation.amount != event.total and event.authorisation.last_edited_at > event.auth_request_at %}
|
||||||
@@ -44,8 +44,5 @@
|
|||||||
<span class="badge badge-info">Invoice: Not Generated</span>
|
<span class="badge badge-info">Invoice: Not Generated</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if event.parking_and_access %}
|
|
||||||
<span class="badge badge-warning">Addititional Access Requirements</span>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,70 +1,195 @@
|
|||||||
{% load namewithnotes from filters %}
|
{% load namewithnotes from filters %}
|
||||||
{% load markdown_tags %}
|
{% load markdown_tags %}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.light-link {
|
#event_table {
|
||||||
color: #ebf5ff !important;
|
display: grid;
|
||||||
|
grid-template-columns: max-content min-content minmax(max-content, 1fr) max-content;
|
||||||
|
column-gap: 1em;
|
||||||
|
}
|
||||||
|
.eventgrid {
|
||||||
|
display: inherit;
|
||||||
|
grid-column: 1/5;
|
||||||
|
grid-template-columns: subgrid;
|
||||||
|
padding: 1em;
|
||||||
|
dt, dd { display: block; float: left; }
|
||||||
|
dt { clear: both; }
|
||||||
|
dd { float: right; }
|
||||||
|
}
|
||||||
|
.grid-header {
|
||||||
|
border-bottom: 1px solid grey;
|
||||||
|
border-top: 1px solid grey;
|
||||||
|
}
|
||||||
|
#event_status {
|
||||||
|
grid-column-start: 3;
|
||||||
|
}
|
||||||
|
#event_mic {
|
||||||
|
grid-row-start: 1;
|
||||||
|
grid-column-start: 4;
|
||||||
|
}
|
||||||
|
.c-none {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.c-inline {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
@container (width <= 500px) {
|
||||||
|
#event_table {
|
||||||
|
grid-template-columns: 1fr !important;
|
||||||
}
|
}
|
||||||
|
.eventgrid {
|
||||||
.dark-link {
|
grid-column: 1/1 !important;
|
||||||
color: #4495ff !important;
|
padding: 0.5em;
|
||||||
}
|
}
|
||||||
|
.grid-header {
|
||||||
.link-on-green {
|
display: none;
|
||||||
color: #ffffff !important;
|
|
||||||
}
|
}
|
||||||
|
#event_dates {
|
||||||
|
order: 2;
|
||||||
|
}
|
||||||
|
#event_status {
|
||||||
|
order: 3;
|
||||||
|
}
|
||||||
|
#event_mic {
|
||||||
|
grid-row-start: auto;
|
||||||
|
grid-column-start: 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@container (width <= 700px) {
|
||||||
|
#event_table {
|
||||||
|
grid-template-columns: max-content;
|
||||||
|
column-gap: 0.5em;
|
||||||
|
}
|
||||||
|
.eventgrid {
|
||||||
|
grid-column: 1/3;
|
||||||
|
border: 1px solid grey;
|
||||||
|
}
|
||||||
|
#event_dates {
|
||||||
|
grid-row: 2;
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
#event_number {
|
||||||
|
grid-row: 1;
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
#event_mic {
|
||||||
|
grid-column: 2;
|
||||||
|
}
|
||||||
|
#event_status {
|
||||||
|
grid-column: span 2;
|
||||||
|
}
|
||||||
|
.grid-header, .c-md-none {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@container (width > 700px) {
|
||||||
|
.c-lg-block {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.c-lg-inline {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
.c-lg-none, .c-md-none {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<div id="event_table">
|
||||||
<div class="row">
|
<div class="eventgrid grid-header font-weight-bold">
|
||||||
{% for event in events %}
|
<div id="event_number">#</div>
|
||||||
<div class="col-12 mb-4">
|
<div id="event_dates">Dates & Times</div>
|
||||||
{% comment %} Determine card style based on event status {% endcomment %}
|
<div>Event Details</div>
|
||||||
{% if event.cancelled %}
|
<div id="event_mic">MIC</div>
|
||||||
|
|
||||||
{% with border_class="border-secondary" header_bg="bg-secondary" header_text="light-link" %}
|
|
||||||
{% include "partials/event_row.html" %}
|
|
||||||
{% endwith %}
|
|
||||||
|
|
||||||
{% elif not event.is_rig %}
|
|
||||||
|
|
||||||
{% with border_class="border-primary" header_bg="bg-primary" header_text="light-link" %}
|
|
||||||
{% include "partials/event_row.html" %}
|
|
||||||
{% endwith %}
|
|
||||||
|
|
||||||
{% elif not event.mic %}
|
|
||||||
|
|
||||||
{% with border_class="border-danger" header_bg="bg-danger" header_text="light-link" %}
|
|
||||||
{% include "partials/event_row.html" %}
|
|
||||||
{% endwith %}
|
|
||||||
|
|
||||||
{% elif event.confirmed and event.authorised %}
|
|
||||||
|
|
||||||
{% if event.dry_hire or event.riskassessment %}
|
|
||||||
|
|
||||||
{% with border_class="border-success" header_bg="bg-success" header_text="link-on-green" %}
|
|
||||||
{% include "partials/event_row.html" %}
|
|
||||||
{% endwith %}
|
|
||||||
|
|
||||||
{% else %}
|
|
||||||
|
|
||||||
{% with border_class="border-warning" header_bg="bg-warning" header_text="dark-link" %}
|
|
||||||
{% include "partials/event_row.html" %}
|
|
||||||
{% endwith %}
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% else %}
|
|
||||||
|
|
||||||
{% with border_class="border-warning" header_bg="bg-warning" header_text="dark-link" %}
|
|
||||||
{% include "partials/event_row.html" %}
|
|
||||||
{% endwith %}
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% empty %}
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="alert alert-info">
|
|
||||||
No events currently scheduled.
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% for event in events %}
|
||||||
{% endfor %}
|
<div class="eventgrid {% if event.cancelled %}
|
||||||
|
table-secondary
|
||||||
|
{% elif not event.is_rig %}
|
||||||
|
table-info
|
||||||
|
{% elif not event.mic %}
|
||||||
|
table-danger
|
||||||
|
{% elif event.confirmed and event.authorised %}
|
||||||
|
{% if event.dry_hire or event.riskassessment %}
|
||||||
|
table-success
|
||||||
|
{% else %}
|
||||||
|
table-warning
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
table-warning
|
||||||
|
{% endif %}" {% if event.cancelled %}style="opacity: 50% !important;"{% endif %} id="event_row">
|
||||||
|
<!---Number-->
|
||||||
|
<div class="font-weight-bold c-none c-lg-block" id="event_number">{{ event.display_id }}</div>
|
||||||
|
<!--Dates & Times-->
|
||||||
|
<div id="event_dates" style="min-width: 180px;">
|
||||||
|
<dl>
|
||||||
|
{% if not event.cancelled %}
|
||||||
|
{% if event.meet_at %}
|
||||||
|
<dt class="font-weight-normal">Meet:</dt>
|
||||||
|
<dd class="text-nowrap font-weight-bold text-lg-right">{{ event.meet_at|date:"D d/m/Y H:i" }}</dd>
|
||||||
|
{% endif %}
|
||||||
|
{% if event.access_at %}
|
||||||
|
<dt class="font-weight-normal">Access:</dt>
|
||||||
|
<dd class="text-nowrap font-weight-bold text-lg-right">{{ event.access_at|date:"D d/m/Y H:i" }}</dd>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
<dt class="font-weight-normal">Start:</dt>
|
||||||
|
<dd class="text-nowrap font-weight-bold text-lg-right">{{ event.start_date|date:"D d/m/Y" }}
|
||||||
|
{% if event.has_start_time %}
|
||||||
|
{{ event.start_time|date:"H:i" }}
|
||||||
|
{% endif %}
|
||||||
|
</dd>
|
||||||
|
{% if event.end_date %}
|
||||||
|
<dt class="font-weight-normal">End:</dt>
|
||||||
|
<dd class="text-nowrap font-weight-bold text-lg-right">{{ event.end_date|date:"D d/m/Y" }}
|
||||||
|
{% if event.has_end_time %}
|
||||||
|
{{ event.end_time|date:"H:i" }}
|
||||||
|
{% endif %}
|
||||||
|
</dd>
|
||||||
|
{% endif %}
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
<!---Details-->
|
||||||
|
<div id="event_details" class="w-100">
|
||||||
|
<h4>
|
||||||
|
<a href="{% url 'event_detail' event.pk %}">
|
||||||
|
<span class="c-inline c-lg-none">{{ event }}</span><span class="c-none c-lg-inline">{{ event.name }}</span>
|
||||||
|
</a>
|
||||||
|
{% if event.dry_hire %}
|
||||||
|
<span class="badge badge-secondary">Dry Hire</span>
|
||||||
|
{% endif %}
|
||||||
|
<br class="c-none c-lg-inline">
|
||||||
|
{% if event.venue %}
|
||||||
|
<small>at {{ event.venue|namewithnotes:'venue_detail' }}</small>
|
||||||
|
{% endif %}
|
||||||
|
</h4>
|
||||||
|
{% if event.is_rig and not event.cancelled %}
|
||||||
|
<h5>
|
||||||
|
<a href="{{ event.person.get_absolute_url }}">{{ event.person.name }}</a>
|
||||||
|
{% if event.organisation %}
|
||||||
|
for <a href="{{ event.organisation.get_absolute_url }}">{{ event.organisation.name }}</a>
|
||||||
|
{% endif %}
|
||||||
|
</h5>
|
||||||
|
{% endif %}
|
||||||
|
{% if not event.cancelled and event.description %}
|
||||||
|
<p>{{ event.description|markdown }}</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% include 'partials/event_status.html' %}
|
||||||
|
<!---MIC-->
|
||||||
|
<div id="event_mic" class="text-nowrap">
|
||||||
|
<span class="c-md-none align-middle">MIC:</span>
|
||||||
|
{% if event.mic %}
|
||||||
|
{% if perms.RIGS.view_profile %}
|
||||||
|
<a href="{% url 'profile_detail' event.mic.pk %}" class="modal-href">
|
||||||
|
{% endif %}
|
||||||
|
<img src="{{ event.mic.profile_picture }}" class="event-mic-photo"/>
|
||||||
|
{{ event.mic }}
|
||||||
|
{% if perms.RIGS.view_profile %}
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
{% elif event.is_rig %}
|
||||||
|
<span class="fas fa-exclamation"></span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1,195 +0,0 @@
|
|||||||
{% load namewithnotes from filters %}
|
|
||||||
{% load markdown_tags %}
|
|
||||||
<style>
|
|
||||||
#event_table {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: max-content min-content minmax(max-content, 1fr) max-content;
|
|
||||||
column-gap: 1em;
|
|
||||||
}
|
|
||||||
.eventgrid {
|
|
||||||
display: inherit;
|
|
||||||
grid-column: 1/5;
|
|
||||||
grid-template-columns: subgrid;
|
|
||||||
padding: 1em;
|
|
||||||
dt, dd { display: block; float: left; }
|
|
||||||
dt { clear: both; }
|
|
||||||
dd { float: right; }
|
|
||||||
}
|
|
||||||
.grid-header {
|
|
||||||
border-bottom: 1px solid grey;
|
|
||||||
border-top: 1px solid grey;
|
|
||||||
}
|
|
||||||
#event_status {
|
|
||||||
grid-column-start: 3;
|
|
||||||
}
|
|
||||||
#event_mic {
|
|
||||||
grid-row-start: 1;
|
|
||||||
grid-column-start: 4;
|
|
||||||
}
|
|
||||||
.c-none {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.c-inline {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
@container (width <= 500px) {
|
|
||||||
#event_table {
|
|
||||||
grid-template-columns: 1fr !important;
|
|
||||||
}
|
|
||||||
.eventgrid {
|
|
||||||
grid-column: 1/1 !important;
|
|
||||||
padding: 0.5em;
|
|
||||||
}
|
|
||||||
.grid-header {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
#event_dates {
|
|
||||||
order: 2;
|
|
||||||
}
|
|
||||||
#event_status {
|
|
||||||
order: 3;
|
|
||||||
}
|
|
||||||
#event_mic {
|
|
||||||
grid-row-start: auto;
|
|
||||||
grid-column-start: 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@container (width <= 700px) {
|
|
||||||
#event_table {
|
|
||||||
grid-template-columns: max-content;
|
|
||||||
column-gap: 0.5em;
|
|
||||||
}
|
|
||||||
.eventgrid {
|
|
||||||
grid-column: 1/3;
|
|
||||||
border: 1px solid grey;
|
|
||||||
}
|
|
||||||
#event_dates {
|
|
||||||
grid-row: 2;
|
|
||||||
grid-column: 1;
|
|
||||||
}
|
|
||||||
#event_number {
|
|
||||||
grid-row: 1;
|
|
||||||
grid-column: 1;
|
|
||||||
}
|
|
||||||
#event_mic {
|
|
||||||
grid-column: 2;
|
|
||||||
}
|
|
||||||
#event_status {
|
|
||||||
grid-column: span 2;
|
|
||||||
}
|
|
||||||
.grid-header, .c-md-none {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@container (width > 700px) {
|
|
||||||
.c-lg-block {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.c-lg-inline {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
.c-lg-none, .c-md-none {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<div id="event_table">
|
|
||||||
<div class="eventgrid grid-header font-weight-bold">
|
|
||||||
<div id="event_number">#</div>
|
|
||||||
<div id="event_dates">Dates & Times</div>
|
|
||||||
<div>Event Details</div>
|
|
||||||
<div id="event_mic">MIC</div>
|
|
||||||
</div>
|
|
||||||
{% for event in events %}
|
|
||||||
<div class="eventgrid {% if event.cancelled %}
|
|
||||||
table-secondary
|
|
||||||
{% elif not event.is_rig %}
|
|
||||||
table-info
|
|
||||||
{% elif not event.mic %}
|
|
||||||
table-danger
|
|
||||||
{% elif event.confirmed and event.authorised %}
|
|
||||||
{% if event.dry_hire or event.riskassessment %}
|
|
||||||
table-success
|
|
||||||
{% else %}
|
|
||||||
table-warning
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
|
||||||
table-warning
|
|
||||||
{% endif %}" {% if event.cancelled %}style="opacity: 50% !important;"{% endif %} id="event_row">
|
|
||||||
<!---Number-->
|
|
||||||
<div class="font-weight-bold c-none c-lg-block" id="event_number">{{ event.display_id }}</div>
|
|
||||||
<!--Dates & Times-->
|
|
||||||
<div id="event_dates" style="min-width: 180px;">
|
|
||||||
<dl>
|
|
||||||
{% if not event.cancelled %}
|
|
||||||
{% if event.meet_at %}
|
|
||||||
<dt class="font-weight-normal">Meet:</dt>
|
|
||||||
<dd class="text-nowrap font-weight-bold text-lg-right">{{ event.meet_at|date:"D d/m/Y H:i" }}</dd>
|
|
||||||
{% endif %}
|
|
||||||
{% if event.access_at %}
|
|
||||||
<dt class="font-weight-normal">Access:</dt>
|
|
||||||
<dd class="text-nowrap font-weight-bold text-lg-right">{{ event.access_at|date:"D d/m/Y H:i" }}</dd>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
<dt class="font-weight-normal">Start:</dt>
|
|
||||||
<dd class="text-nowrap font-weight-bold text-lg-right">{{ event.start_date|date:"D d/m/Y" }}
|
|
||||||
{% if event.has_start_time %}
|
|
||||||
{{ event.start_time|date:"H:i" }}
|
|
||||||
{% endif %}
|
|
||||||
</dd>
|
|
||||||
{% if event.end_date %}
|
|
||||||
<dt class="font-weight-normal">End:</dt>
|
|
||||||
<dd class="text-nowrap font-weight-bold text-lg-right">{{ event.end_date|date:"D d/m/Y" }}
|
|
||||||
{% if event.has_end_time %}
|
|
||||||
{{ event.end_time|date:"H:i" }}
|
|
||||||
{% endif %}
|
|
||||||
</dd>
|
|
||||||
{% endif %}
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
<!---Details-->
|
|
||||||
<div id="event_details" class="w-100">
|
|
||||||
<h4>
|
|
||||||
<a href="{% url 'event_detail' event.pk %}">
|
|
||||||
<span class="c-inline c-lg-none">{{ event }}</span><span class="c-none c-lg-inline">{{ event.name }}</span>
|
|
||||||
</a>
|
|
||||||
{% if event.dry_hire %}
|
|
||||||
<span class="badge badge-secondary">Dry Hire</span>
|
|
||||||
{% endif %}
|
|
||||||
<br class="c-none c-lg-inline">
|
|
||||||
{% if event.venue %}
|
|
||||||
<small>at {{ event.venue|namewithnotes:'venue_detail' }}</small>
|
|
||||||
{% endif %}
|
|
||||||
</h4>
|
|
||||||
{% if event.is_rig and not event.cancelled %}
|
|
||||||
<h5>
|
|
||||||
<a href="{{ event.person.get_absolute_url }}">{{ event.person.name }}</a>
|
|
||||||
{% if event.organisation %}
|
|
||||||
for <a href="{{ event.organisation.get_absolute_url }}">{{ event.organisation.name }}</a>
|
|
||||||
{% endif %}
|
|
||||||
</h5>
|
|
||||||
{% endif %}
|
|
||||||
{% if not event.cancelled and event.description %}
|
|
||||||
<p>{{ event.description|markdown }}</p>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% include 'partials/event_status.html' %}
|
|
||||||
<!---MIC-->
|
|
||||||
<div id="event_mic" class="text-nowrap">
|
|
||||||
<span class="c-md-none align-middle">MIC:</span>
|
|
||||||
{% if event.mic %}
|
|
||||||
{% if perms.RIGS.view_profile %}
|
|
||||||
<a href="{% url 'profile_detail' event.mic.pk %}" class="modal-href">
|
|
||||||
{% endif %}
|
|
||||||
<img src="{{ event.mic.profile_picture }}" class="event-mic-photo"/>
|
|
||||||
{{ event.mic }}
|
|
||||||
{% if perms.RIGS.view_profile %}
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
{% elif event.is_rig %}
|
|
||||||
<span class="fas fa-exclamation"></span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<div class="card card-default">
|
|
||||||
<div class="card-header">Parking and Access</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<p>This venue has additional parking and/or access requirements.</p>
|
|
||||||
|
|
||||||
<p>Ensure the MIC has:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Details of where to park</li>
|
|
||||||
<li>Details of how to access the venue</li>
|
|
||||||
<li>Details of any access restrictions</li>
|
|
||||||
<li>If on campus, sorted parking permits</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{% if object.parking_and_access and object.riskassessment.parking_and_access %}
|
|
||||||
<small>Additional parking marked on both rig details and risk assessment.</small>
|
|
||||||
{% elif object.parking_and_access %}
|
|
||||||
<small>Additional parking marked on rig details.</small>
|
|
||||||
{% elif object.riskassessment.parking_and_access %}
|
|
||||||
<small>Additional parking marked on risk assessment.</small>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -4,44 +4,15 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row align-items-center justify-content-between py-2 align-middle">
|
<div class="row align-items-center justify-content-between py-2 align-middle">
|
||||||
<div class="col-sm-12 col-md align-middle d-flex flex-wrap">
|
<div class="col-sm-12 col-md align-middle d-flex flex-wrap">
|
||||||
Key: <span class="table-success mr-1 px-2 rounded">Ready</span><span
|
Key: <span class="table-success mr-1 px-2 rounded">Ready</span><span class="table-warning mr-1 px-2 rounded text-nowrap">Action Required</span><span class="table-danger mr-1 px-2 rounded text-nowrap">Needs MIC</span><span class="table-secondary mr-1 px-2 rounded">Cancelled</span><span class="table-info px-2 rounded text-nowrap">Non-Rig</span>
|
||||||
class="table-warning mr-1 px-2 rounded text-nowrap">Action Required</span><span
|
|
||||||
class="table-danger mr-1 px-2 rounded text-nowrap">Needs MIC</span><span
|
|
||||||
class="table-secondary mr-1 px-2 rounded">Cancelled</span><span
|
|
||||||
class="table-info px-2 rounded text-nowrap">Non-Rig</span>
|
|
||||||
</div>
|
</div>
|
||||||
{% if perms.RIGS.add_event %}
|
{% if perms.RIGS.add_event %}
|
||||||
<div class="col text-right">
|
<div class="col text-right">
|
||||||
{% button 'new' 'event_create' %}
|
{% button 'new' 'event_create' %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not request.GET.legacy %}
|
|
||||||
|
|
||||||
{% if not request.GET.hide_cancelled %}
|
|
||||||
<a href="?hide_cancelled=true" class="btn btn-primary mr-3">Hide cancelled</a>
|
|
||||||
{% else %}
|
|
||||||
<a href="." class="btn btn-primary mr-3">Show cancelled</a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<a href="?legacy=true" class="btn btn-secondary">Legacy rigboard</a>
|
|
||||||
{% else %}
|
|
||||||
<a href="." class="btn btn-secondary">New rigboard</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if request.GET.legacy %}
|
|
||||||
<div class="alert alert-warning">
|
|
||||||
<strong>Warning:</strong> The legacy rigboard is being deprecated and will be removed in the future. Please use the
|
|
||||||
new rigboard.
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
|
|
||||||
<div style="container-type: inline-size;">
|
<div style="container-type: inline-size;">
|
||||||
{% if request.GET.legacy %}
|
{% include 'partials/event_table.html' %}
|
||||||
{% include 'partials/legacy_event_table.html' %}
|
|
||||||
{% else %}
|
|
||||||
{% include 'partials/event_table.html' %}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ def ra(basic_event, admin_user):
|
|||||||
known_venue=True, safe_loading=True, safe_storage=True,
|
known_venue=True, safe_loading=True, safe_storage=True,
|
||||||
area_outside_of_control=True, barrier_required=True,
|
area_outside_of_control=True, barrier_required=True,
|
||||||
nonstandard_emergency_procedure=True, special_structures=False,
|
nonstandard_emergency_procedure=True, special_structures=False,
|
||||||
suspended_structures=False, outside=False, parking_and_access=False)
|
suspended_structures=False, outside=False)
|
||||||
yield ra
|
yield ra
|
||||||
ra.delete()
|
ra.delete()
|
||||||
|
|
||||||
|
|||||||
@@ -16,14 +16,14 @@ class Rigboard(BasePage):
|
|||||||
URL_TEMPLATE = reverse('rigboard')
|
URL_TEMPLATE = reverse('rigboard')
|
||||||
|
|
||||||
_add_item_selector = (By.XPATH, "//a[contains(@class,'btn-primary') and contains(., 'New')]")
|
_add_item_selector = (By.XPATH, "//a[contains(@class,'btn-primary') and contains(., 'New')]")
|
||||||
_event_row_locator = (By.CLASS_NAME, "event-row")
|
_event_row_locator = (By.ID, 'event_row')
|
||||||
|
|
||||||
def add(self):
|
def add(self):
|
||||||
self.find_element(*self._add_item_selector).click()
|
self.find_element(*self._add_item_selector).click()
|
||||||
|
|
||||||
class EventListRow(Region):
|
class EventListRow(Region):
|
||||||
_event_number_locator = (By.ID, "event_number")
|
_event_number_locator = (By.ID, "event_number")
|
||||||
_event_dates_locator = (By.CLASS_NAME, "event-dates")
|
_event_dates_locator = (By.ID, "event_dates")
|
||||||
_event_details_locator = (By.ID, "event_details")
|
_event_details_locator = (By.ID, "event_details")
|
||||||
_event_mic_locator = (By.ID, "event_mic")
|
_event_mic_locator = (By.ID, "event_mic")
|
||||||
|
|
||||||
@@ -207,7 +207,6 @@ class CreateRiskAssessment(FormPage):
|
|||||||
'suspended_structures': (regions.RadioSelect, (By.ID, 'id_suspended_structures')),
|
'suspended_structures': (regions.RadioSelect, (By.ID, 'id_suspended_structures')),
|
||||||
'supervisor_consulted': (regions.CheckBox, (By.ID, 'id_supervisor_consulted')),
|
'supervisor_consulted': (regions.CheckBox, (By.ID, 'id_supervisor_consulted')),
|
||||||
'rigging_plan': (regions.TextBox, (By.ID, 'id_rigging_plan')),
|
'rigging_plan': (regions.TextBox, (By.ID, 'id_rigging_plan')),
|
||||||
'parking_and_access': (regions.RadioSelect, (By.ID, 'id_parking_and_access')),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -91,8 +91,8 @@ class TestRigboard(BaseRigboardTest):
|
|||||||
# self.live_server_url + '/event/create/', self.driver.current_url)
|
# self.live_server_url + '/event/create/', self.driver.current_url)
|
||||||
|
|
||||||
def test_event_order(self):
|
def test_event_order(self):
|
||||||
self.assertIn(self.testEvent.start_date.strftime('%-d %b %Y'), self.page.events[0].dates)
|
self.assertIn(self.testEvent.start_date.strftime('%a %d/%m/%Y'), self.page.events[0].dates)
|
||||||
self.assertIn(self.testEvent2.start_date.strftime('%-d %b %Y'), self.page.events[1].dates)
|
self.assertIn(self.testEvent2.start_date.strftime('%a %d/%m/%Y'), self.page.events[1].dates)
|
||||||
|
|
||||||
def test_add_button(self):
|
def test_add_button(self):
|
||||||
self.page.add()
|
self.page.add()
|
||||||
@@ -530,11 +530,10 @@ class TestCalendar(BaseRigboardTest):
|
|||||||
self.page.toggle_filter('cancelled')
|
self.page.toggle_filter('cancelled')
|
||||||
self.page.toggle_filter('provisional')
|
self.page.toggle_filter('provisional')
|
||||||
self.page.toggle_filter('confirmed')
|
self.page.toggle_filter('confirmed')
|
||||||
self.page.toggle_filter('only_mic')
|
|
||||||
|
|
||||||
# and then check the url is correct
|
# and then check the url is correct
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
"rigs.ics?rig=false&non-rig=false&dry-hire=false&cancelled=true&provisional=false&confirmed=false&only_mic=true",
|
"rigs.ics?rig=false&non-rig=false&dry-hire=false&cancelled=true&provisional=false&confirmed=false",
|
||||||
self.page.cal_url)
|
self.page.cal_url)
|
||||||
|
|
||||||
# Awesome - all seems to work
|
# Awesome - all seems to work
|
||||||
@@ -760,7 +759,6 @@ def test_ra_creation(logged_in_browser, live_server, admin_user, basic_event):
|
|||||||
page.barrier_required = False
|
page.barrier_required = False
|
||||||
page.nonstandard_emergency_procedure = False
|
page.nonstandard_emergency_procedure = False
|
||||||
page.special_structures = False
|
page.special_structures = False
|
||||||
page.parking_and_access = False
|
|
||||||
# self.page.persons_responsible_structures = "Nobody and her cat, She"
|
# self.page.persons_responsible_structures = "Nobody and her cat, She"
|
||||||
|
|
||||||
page.suspended_structures = True
|
page.suspended_structures = True
|
||||||
|
|||||||
@@ -40,19 +40,19 @@ class InvoiceDashboard(generic.TemplateView):
|
|||||||
time_filter = 'all'
|
time_filter = 'all'
|
||||||
|
|
||||||
if time_filter == 'all':
|
if time_filter == 'all':
|
||||||
context['events'] = models.Event.objects.filter(is_rig=True)
|
context['events'] = models.Event.objects.all()
|
||||||
context['invoices'] = models.Invoice.objects.all()
|
context['invoices'] = models.Invoice.objects.all()
|
||||||
context['payments'] = models.Payment.objects.all()
|
context['payments'] = models.Payment.objects.all()
|
||||||
elif time_filter == 'year':
|
elif time_filter == 'year':
|
||||||
context['events'] = models.Event.objects.filter(is_rig=True, start_date__gte=datetime.date.today() - datetime.timedelta(days=365))
|
context['events'] = models.Event.objects.filter(start_date__gte=datetime.date.today() - datetime.timedelta(days=365))
|
||||||
context['invoices'] = models.Invoice.objects.filter(invoice_date__gte=datetime.date.today() - datetime.timedelta(days=365))
|
context['invoices'] = models.Invoice.objects.filter(invoice_date__gte=datetime.date.today() - datetime.timedelta(days=365))
|
||||||
context['payments'] = models.Payment.objects.filter(date__gte=datetime.date.today() - datetime.timedelta(days=365))
|
context['payments'] = models.Payment.objects.filter(date__gte=datetime.date.today() - datetime.timedelta(days=365))
|
||||||
elif time_filter == 'month':
|
elif time_filter == 'month':
|
||||||
context['events'] = models.Event.objects.filter(is_rig=True, start_date__gte=datetime.date.today() - datetime.timedelta(days=30))
|
context['events'] = models.Event.objects.filter(start_date__gte=datetime.date.today() - datetime.timedelta(days=30))
|
||||||
context['invoices'] = models.Invoice.objects.filter(invoice_date__gte=datetime.date.today() - datetime.timedelta(days=30))
|
context['invoices'] = models.Invoice.objects.filter(invoice_date__gte=datetime.date.today() - datetime.timedelta(days=30))
|
||||||
context['payments'] = models.Payment.objects.filter(date__gte=datetime.date.today() - datetime.timedelta(days=30))
|
context['payments'] = models.Payment.objects.filter(date__gte=datetime.date.today() - datetime.timedelta(days=30))
|
||||||
elif time_filter == 'week':
|
elif time_filter == 'week':
|
||||||
context['events'] = models.Event.objects.filter(is_rig=True, start_date__gte=datetime.date.today() - datetime.timedelta(days=7))
|
context['events'] = models.Event.objects.filter(start_date__gte=datetime.date.today() - datetime.timedelta(days=7))
|
||||||
context['invoices'] = models.Invoice.objects.filter(invoice_date__gte=datetime.date.today() - datetime.timedelta(days=7))
|
context['invoices'] = models.Invoice.objects.filter(invoice_date__gte=datetime.date.today() - datetime.timedelta(days=7))
|
||||||
context['payments'] = models.Payment.objects.filter(date__gte=datetime.date.today() - datetime.timedelta(days=7))
|
context['payments'] = models.Payment.objects.filter(date__gte=datetime.date.today() - datetime.timedelta(days=7))
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ class CalendarICS(ICalFeed):
|
|||||||
# Rig = 'rig' = True
|
# Rig = 'rig' = True
|
||||||
# Provisional = 'provisional' = True
|
# Provisional = 'provisional' = True
|
||||||
# Confirmed/Booked = 'confirmed' = True
|
# Confirmed/Booked = 'confirmed' = True
|
||||||
# Only MIC = 'mic' = False
|
|
||||||
|
|
||||||
def get_object(self, request, *args, **kwargs):
|
def get_object(self, request, *args, **kwargs):
|
||||||
params = {}
|
params = {}
|
||||||
@@ -36,9 +35,6 @@ class CalendarICS(ICalFeed):
|
|||||||
params['cancelled'] = request.GET.get('cancelled', 'false') == 'true'
|
params['cancelled'] = request.GET.get('cancelled', 'false') == 'true'
|
||||||
params['provisional'] = request.GET.get('provisional', 'true') == 'true'
|
params['provisional'] = request.GET.get('provisional', 'true') == 'true'
|
||||||
params['confirmed'] = request.GET.get('confirmed', 'true') == 'true'
|
params['confirmed'] = request.GET.get('confirmed', 'true') == 'true'
|
||||||
params['only_mic'] = request.GET.get('only_mic', 'false') == 'true'
|
|
||||||
|
|
||||||
params['user'] = kwargs['user']
|
|
||||||
|
|
||||||
return params
|
return params
|
||||||
|
|
||||||
@@ -77,9 +73,6 @@ class CalendarICS(ICalFeed):
|
|||||||
|
|
||||||
filter = filter & typeFilters & statusFilters
|
filter = filter & typeFilters & statusFilters
|
||||||
|
|
||||||
if params['only_mic']:
|
|
||||||
filter = filter & Q(mic=params['user'])
|
|
||||||
|
|
||||||
return models.Event.objects.filter(filter).order_by('-start_date').select_related('person', 'organisation',
|
return models.Event.objects.filter(filter).order_by('-start_date').select_related('person', 'organisation',
|
||||||
'venue', 'mic')
|
'venue', 'mic')
|
||||||
|
|
||||||
|
|||||||
@@ -41,13 +41,8 @@ class RigboardIndex(generic.TemplateView):
|
|||||||
# get super context
|
# get super context
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
objects = models.Event.objects.current_events()
|
|
||||||
|
|
||||||
if self.request.GET.get('hide_cancelled', False):
|
|
||||||
objects = objects.exclude(status=models.Event.CANCELLED)
|
|
||||||
|
|
||||||
# call out method to get current events
|
# call out method to get current events
|
||||||
context['events'] = objects.select_related('riskassessment', 'invoice').prefetch_related('checklists')
|
context['events'] = models.Event.objects.current_events().select_related('riskassessment', 'invoice').prefetch_related('checklists')
|
||||||
context['page_title'] = "Rigboard"
|
context['page_title'] = "Rigboard"
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
{% block preload_js %}
|
{% block preload_js %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
<script src="{% static 'js/selects.js' %}"></script>
|
<script src="{% static 'js/selects.js' %}" async></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
{% block preload_js %}
|
{% block preload_js %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
<script src="{% static 'js/selects.js' %}"></script>
|
<script src="{% static 'js/selects.js' %}" async></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
|
|||||||
@@ -244,7 +244,6 @@ class TestSupplierList(AutoLoginTest):
|
|||||||
|
|
||||||
self.page.set_query("")
|
self.page.set_query("")
|
||||||
self.page.search()
|
self.page.search()
|
||||||
time.sleep(1)
|
|
||||||
self.assertTrue(len(self.page.suppliers) == 7)
|
self.assertTrue(len(self.page.suppliers) == 7)
|
||||||
|
|
||||||
self.page.set_query("This is not a supplier")
|
self.page.set_query("This is not a supplier")
|
||||||
|
|||||||
@@ -374,7 +374,7 @@ def generate_label(pk):
|
|||||||
barcode = Code39(str(obj.asset_id), writer=ImageWriter())
|
barcode = Code39(str(obj.asset_id), writer=ImageWriter())
|
||||||
|
|
||||||
logo_size = (200, 200)
|
logo_size = (200, 200)
|
||||||
image.paste(logo.resize(logo_size, Image.LANCZOS), box=(5, 5))
|
image.paste(logo.resize(logo_size, Image.ANTIALIAS), box=(5, 5))
|
||||||
barcode_image = barcode.render(writer_options={"quiet_zone": 0, "write_text": False})
|
barcode_image = barcode.render(writer_options={"quiet_zone": 0, "write_text": False})
|
||||||
width, height = barcode_image.size
|
width, height = barcode_image.size
|
||||||
image.paste(barcode_image.crop((0, 0, width, 100)), (int(((size[0] + logo_size[0]) - width) / 2), 40))
|
image.paste(barcode_image.crop((0, 0, width, 100)), (int(((size[0] + logo_size[0]) - width) / 2), 40))
|
||||||
|
|||||||
648
package-lock.json
generated
648
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,99 +0,0 @@
|
|||||||
[project]
|
|
||||||
name = "pyrigs"
|
|
||||||
version = "0.1.0"
|
|
||||||
description = "A Django-based event booking system designed for use by TEC PA and Lighting"
|
|
||||||
readme = "README.md"
|
|
||||||
requires-python = "~=3.10.0"
|
|
||||||
dependencies = [
|
|
||||||
"ansicolors~=1.1.8",
|
|
||||||
"asgiref~=3.3.1",
|
|
||||||
"backports.tempfile~=1.0",
|
|
||||||
"backports.weakref~=1.0.post1",
|
|
||||||
"beautifulsoup4~=4.9.3",
|
|
||||||
"Brotli~=1.0.9",
|
|
||||||
"cachetools~=4.2.1",
|
|
||||||
"chardet~=4.0.0",
|
|
||||||
"configparser~=5.0.1",
|
|
||||||
"contextlib2~=0.6.0.post1",
|
|
||||||
"cssselect~=1.1.0",
|
|
||||||
"cssutils~=1.0.2",
|
|
||||||
"dj-database-url~=0.5.0",
|
|
||||||
"dj-static~=0.0.6",
|
|
||||||
"Django~=3.2",
|
|
||||||
"django-debug-toolbar~=4.0.0",
|
|
||||||
"django-filter~=2.4.0",
|
|
||||||
"django-ical~=1.7.1",
|
|
||||||
"django-recurrence~=1.10.3",
|
|
||||||
"django-registration-redux~=2.9",
|
|
||||||
"django-reversion~=3.0.9",
|
|
||||||
"django-widget-tweaks~=1.4.8",
|
|
||||||
"django-htmlmin~=0.11.0",
|
|
||||||
"envparse",
|
|
||||||
"gunicorn~=22.0.0",
|
|
||||||
"icalendar~=4.0.7",
|
|
||||||
"idna~=3.7",
|
|
||||||
"Markdown~=3.3.3",
|
|
||||||
"msgpack~=1.0.2",
|
|
||||||
"pep517~=0.9.1",
|
|
||||||
"Pillow~=10.0.1",
|
|
||||||
"premailer~=3.7.0",
|
|
||||||
"progress~=1.5",
|
|
||||||
"psutil~=5.8.0",
|
|
||||||
"psycopg2-binary",
|
|
||||||
"Pygments~=2.15.0",
|
|
||||||
"pyparsing~=2.4.7",
|
|
||||||
"PyPDF2~=1.27.5",
|
|
||||||
"PyPOM~=2.2.4",
|
|
||||||
"python-dateutil~=2.8.1",
|
|
||||||
"pytoml~=0.1.21",
|
|
||||||
"pytz~=2020.5",
|
|
||||||
"reportlab",
|
|
||||||
"requests~=2.32.3",
|
|
||||||
"retrying~=1.3.3",
|
|
||||||
"simplejson~=3.17.2",
|
|
||||||
"six~=1.15.0",
|
|
||||||
"soupsieve~=2.1",
|
|
||||||
"sqlparse~=0.5.0",
|
|
||||||
"static3~=0.7.0",
|
|
||||||
"svg2rlg~=0.3",
|
|
||||||
"tini~=3.0.1",
|
|
||||||
"tornado~=6.3",
|
|
||||||
"urllib3~=1.26.19",
|
|
||||||
"whitenoise~=5.2.0",
|
|
||||||
"yolk~=0.4.3",
|
|
||||||
"zipp~=3.4.0",
|
|
||||||
"zope.component~=4.6.2",
|
|
||||||
"zope.deferredimport~=4.3.1",
|
|
||||||
"zope.deprecation~=4.4.0",
|
|
||||||
"zope.event~=4.5.0",
|
|
||||||
"zope.hookable~=5.0.1",
|
|
||||||
"zope.proxy~=4.3.5",
|
|
||||||
"zope.schema~=6.0.1",
|
|
||||||
"sentry-sdk",
|
|
||||||
"diff-match-patch",
|
|
||||||
"python-barcode",
|
|
||||||
"django-hCaptcha",
|
|
||||||
"importlib-metadata",
|
|
||||||
"django-hcaptcha",
|
|
||||||
"z3c.rml",
|
|
||||||
"pikepdf",
|
|
||||||
"django-queryable-properties",
|
|
||||||
"django-mass-edit",
|
|
||||||
"selenium~=4.9.1",
|
|
||||||
"zope.interface",
|
|
||||||
]
|
|
||||||
|
|
||||||
[dependency-groups]
|
|
||||||
dev = [
|
|
||||||
"pycodestyle~=2.9.1",
|
|
||||||
"coveralls",
|
|
||||||
"django-coverage-plugin",
|
|
||||||
"pytest-cov",
|
|
||||||
"pytest-django",
|
|
||||||
"pluggy",
|
|
||||||
"pytest-splinter",
|
|
||||||
"pytest",
|
|
||||||
"pytest-reverse",
|
|
||||||
"pytest-xdist[psutil]",
|
|
||||||
"PyPOM[splinter]",
|
|
||||||
]
|
|
||||||
@@ -1,3 +1,2 @@
|
|||||||
[pycodestyle]
|
[pycodestyle]
|
||||||
max-line-length = 320
|
max-line-length = 320
|
||||||
exclude = .venv
|
|
||||||
|
|||||||
@@ -13,10 +13,6 @@
|
|||||||
<meta name="theme-color" content="#3853a4">
|
<meta name="theme-color" content="#3853a4">
|
||||||
<meta name="color-scheme" content="light dark">
|
<meta name="color-scheme" content="light dark">
|
||||||
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Fontdiner+Swanky&display=swap" rel="stylesheet">
|
|
||||||
|
|
||||||
<link rel="icon" type="image/png" href="{% static 'imgs/pyrigs-avatar.png' %}">
|
<link rel="icon" type="image/png" href="{% static 'imgs/pyrigs-avatar.png' %}">
|
||||||
<link rel="apple-touch-icon" href="{% static 'imgs/pyrigs-avatar.png' %}">
|
<link rel="apple-touch-icon" href="{% static 'imgs/pyrigs-avatar.png' %}">
|
||||||
|
|
||||||
@@ -40,7 +36,7 @@
|
|||||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark" role="navigation">
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark" role="navigation">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<a class="navbar-brand" href="{% if request.user.is_authenticated %}https://rigs.nottinghamtec.co.uk{%else%}https://nottinghamtec.co.uk{%endif%}">
|
<a class="navbar-brand" href="{% if request.user.is_authenticated %}https://rigs.nottinghamtec.co.uk{%else%}https://nottinghamtec.co.uk{%endif%}">
|
||||||
<img src="{% static 'imgs/logo.webp' %}" class="mr-auto" style="max-height: 40px;" alt="TEC's Logo: Serif 'TEC' vertically next to a blue box with the words 'PA and Lighting', surrounded by graduated rings" id="logo">
|
<img src="{% static 'imgs/logo.webp' %}" class="mr-auto" style="max-height: 40px; position: absolute; left: 0.5em; top: 0;" alt="TEC's Logo: Serif 'TEC' vertically next to a blue box with the words 'PA and Lighting', surrounded by graduated rings" id="logo">
|
||||||
</a>
|
</a>
|
||||||
{% block titleheader %}
|
{% block titleheader %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
{% for event in now %}
|
{% for event in now %}
|
||||||
<div class="alert alert-primary rounded-0">
|
<div class="alert alert-primary rounded-0">
|
||||||
Event <a href="{% url 'event_detail' event.pk %}" class="text-danger">{{ event }}</a> is happening today! <a href="{% url 'event_checkin' event.pk %}" class="btn btn-success btn-sm modal-href align-baseline {% if request.user.current_event %}disabled{%endif%}"><span class="fas fa-user-clock"></span> <span class="d-none d-sm-inline">Check In</span></a><br/>
|
Event {{ event }} is happening today! <a href="{% url 'event_checkin' event.pk %}" class="btn btn-success btn-sm modal-href align-baseline {% if request.user.current_event %}disabled{%endif%}"><span class="fas fa-user-clock"></span> <span class="d-none d-sm-inline">Check In</span></a><br/>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
@@ -56,9 +56,6 @@
|
|||||||
<a class="list-group-item list-group-item-action" href="{% url 'trainee_list' %}"><span class="fas fa-users"></span><span class="align-middle"> Trainee List</span></a>
|
<a class="list-group-item list-group-item-action" href="{% url 'trainee_list' %}"><span class="fas fa-users"></span><span class="align-middle"> Trainee List</span></a>
|
||||||
<a class="list-group-item list-group-item-action" href="{% url 'level_list' %}"><span class="fas fa-layer-group"></span> <span class="align-middle">Level List</span></a>
|
<a class="list-group-item list-group-item-action" href="{% url 'level_list' %}"><span class="fas fa-layer-group"></span> <span class="align-middle">Level List</span></a>
|
||||||
<a class="list-group-item list-group-item-action" href="{% url 'item_list' %}"><span class="fas fa-sitemap"></span> <span class="align-middle">Item List</span></a>
|
<a class="list-group-item list-group-item-action" href="{% url 'item_list' %}"><span class="fas fa-sitemap"></span> <span class="align-middle">Item List</span></a>
|
||||||
{% if request.user.is_supervisor %}
|
|
||||||
<a class="list-group-item list-group-item-action" href="{% url 'session_log' %}"><span class="fas fa-users"></span> <span class="align-middle">Log Session</span></a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
<label for="supervisor" class="col-sm-2 col-form-label">Supervisor</label>
|
<label for="supervisor" class="col-sm-2 col-form-label">Supervisor</label>
|
||||||
<select name="supervisor" id="supervisor_id" class="selectpicker col-sm-10" data-live-search="true"
|
<select name="supervisor" id="supervisor_id" class="selectpicker col-sm-10" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" required data-noclear="true">
|
||||||
data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" required
|
{% if supervisor %}
|
||||||
data-noclear="true">
|
|
||||||
{% if supervisor %}
|
|
||||||
<option value="{{form.supervisor.value}}" selected>{{ supervisor }}</option>
|
<option value="{{form.supervisor.value}}" selected>{{ supervisor }}</option>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<option value="{{request.user.pk}}" selected>{{ request.user }}</option>
|
|
||||||
</select>
|
</select>
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ def select_super(page, supervisor):
|
|||||||
assert page.supervisor_selector.is_open
|
assert page.supervisor_selector.is_open
|
||||||
page.supervisor_selector.search(supervisor.name[:-6])
|
page.supervisor_selector.search(supervisor.name[:-6])
|
||||||
time.sleep(2) # Slow down for javascript
|
time.sleep(2) # Slow down for javascript
|
||||||
page.supervisor_selector.set_option(supervisor.name, True)
|
|
||||||
assert page.supervisor_selector.options[0].selected
|
assert page.supervisor_selector.options[0].selected
|
||||||
|
page.supervisor_selector.toggle()
|
||||||
|
|
||||||
|
|
||||||
def test_add_qualification(logged_in_browser, live_server, trainee, supervisor, training_item):
|
def test_add_qualification(logged_in_browser, live_server, trainee, supervisor, training_item):
|
||||||
@@ -40,7 +40,6 @@ def test_add_qualification(logged_in_browser, live_server, trainee, supervisor,
|
|||||||
page.item_selector.toggle()
|
page.item_selector.toggle()
|
||||||
|
|
||||||
select_super(page, supervisor)
|
select_super(page, supervisor)
|
||||||
page.supervisor_selector.toggle()
|
|
||||||
|
|
||||||
page.submit()
|
page.submit()
|
||||||
assert page.success
|
assert page.success
|
||||||
|
|||||||
@@ -126,9 +126,6 @@
|
|||||||
<label class="checkbox-inline ml-lg-2">
|
<label class="checkbox-inline ml-lg-2">
|
||||||
<input type="checkbox" value="confirmed" data-default="true" checked> Confirmed/Booked
|
<input type="checkbox" value="confirmed" data-default="true" checked> Confirmed/Booked
|
||||||
</label>
|
</label>
|
||||||
<label class="checkbox-inline ml-lg-2">
|
|
||||||
<input type="checkbox" value="only_mic" data-default="false" > Only MIC
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</dd>
|
</dd>
|
||||||
|
|||||||
Reference in New Issue
Block a user