Compare commits

..

11 Commits

22 changed files with 90 additions and 82 deletions

View File

@@ -18,34 +18,35 @@ jobs:
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Cache python deps
- uses: actions/cache@v2
id: pcache
uses: actions/cache@v2
with:
path: ${{ env.pythonLocation }}
key: ${{ env.pythonLocation }}-${{ hashFiles('Pipfile.lock') }}
path: ~/.local/share/virtualenvs
key: ${{ runner.os }}-pipenv-${{ hashFiles('Pipfile.lock') }}
restore-keys: |
${{ runner.os }}-pipenv-
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install pipenv
pipenv install -d
- name: Basic Checks
run: |
pipenv run pycodestyle . --exclude=migrations,node_modules
pipenv run python manage.py check
pipenv run python manage.py makemigrations --check --dry-run
# if: steps.pcache.outputs.cache-hit != 'true'
- name: Cache Static Files
id: static-cache
uses: actions/cache@v2
with:
path: 'static/'
path: 'pipeline/built_assets'
key: ${{ hashFiles('package-lock.json') }}-${{ hashFiles('pipeline/source_assets') }}
- uses: bahmutov/npm-install@v1
if: steps.static-cache.outputs.cache-hit != 'true'
- run: node node_modules/gulp/bin/gulp build
if: steps.static-cache.outputs.cache-hit != 'true'
- run: pipenv run python manage.py collectstatic --noinput
if: steps.static-cache.outputs.cache-hit != 'true'
- name: Basic Checks
run: |
pipenv run pycodestyle . --exclude=migrations,node_modules
pipenv run python manage.py check
pipenv run python manage.py makemigrations --check --dry-run
pipenv run python manage.py collectstatic --noinput
- name: Run Tests
run: pipenv run pytest -n auto -vv --cov
- uses: actions/upload-artifact@v2

View File

@@ -253,7 +253,7 @@ TEMPLATES = [
"django.template.context_processors.request",
"django.contrib.messages.context_processors.messages",
],
'debug': DEBUG or CI
'debug': DEBUG
},
},
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.1.7 on 2021-03-02 11:21
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('RIGS', '0041_auto_20210208_1603'),
]
operations = [
migrations.AlterField(
model_name='profile',
name='phone',
field=models.CharField(blank=True, default='', max_length=13),
),
]

View File

@@ -21,7 +21,7 @@ from reversion.models import Version
class Profile(AbstractUser):
initials = models.CharField(max_length=5, unique=True, null=True, blank=False)
phone = models.CharField(max_length=13, null=True, default='')
phone = models.CharField(max_length=13, blank=True, default='')
api_key = models.CharField(max_length=40, blank=True, editable=False, default='')
is_approved = models.BooleanField(default=False)
# Currently only populated by the admin approval email. TODO: Populate it each time we send any email, might need that...
@@ -707,7 +707,7 @@ class RiskAssessment(models.Model, RevisionMixin):
]
@cached_property
def fields(self):
def fieldz(self):
return [n.name for n in list(self._meta.get_fields()) if n.name != 'reviewed_at' and n.name != 'reviewed_by' and not n.is_relation and not n.auto_created]
@property
@@ -792,16 +792,16 @@ class EventChecklist(models.Model, RevisionMixin):
inverted_fields = []
@cached_property
def fields(self):
return [n.name for n in list(self._meta.get_fields()) if n.name != 'reviewed_at' and n.name != 'reviewed_by' and not n.is_relation and not n.auto_created]
class Meta:
ordering = ['event']
permissions = [
('review_eventchecklist', 'Can review Event Checklists')
]
@cached_property
def fieldz(self):
return [n.name for n in list(self._meta.get_fields()) if n.name != 'reviewed_at' and n.name != 'reviewed_by' and not n.is_relation and not n.auto_created]
@property
def activity_feed_string(self):
return str(self.event)

View File

@@ -11,7 +11,7 @@ import simplejson
from PyPDF2 import PdfFileMerger, PdfFileReader
from django.conf import settings
from django.contrib import messages
from django.contrib.staticfiles.storage import staticfiles_storage
from django.contrib.staticfiles import finders
from django.core import signing
from django.core.exceptions import SuspiciousOperation
from django.core.mail import EmailMultiAlternatives
@@ -274,6 +274,7 @@ class EventArchive(generic.ListView):
class EventAuthorise(generic.UpdateView):
template_name = 'eventauthorisation_form.html'
success_template = 'eventauthorisation_success.html'
preview = False
def form_valid(self, form):
self.object = form.save()
@@ -301,6 +302,7 @@ class EventAuthorise(generic.UpdateView):
context['page_title'] = "{}: {}".format(self.event.display_id, self.event.name)
if self.event.dry_hire:
context['page_title'] += ' <span class="badge badge-secondary align-top">Dry Hire</span>'
context['preview'] = self.preview
return context
def get(self, request, *args, **kwargs):
@@ -387,7 +389,7 @@ class EventAuthorisationRequest(generic.FormView, generic.detail.SingleObjectMix
to=[email],
reply_to=[self.request.user.email],
)
css = staticfiles_storage.path('css/email.css')
css = finders.find('css/email.css')
html = premailer.Premailer(get_template("eventauthorisation_client_request.html").render(context),
external_styles=css).transform()
msg.attach_alternative(html, 'text/html')
@@ -402,8 +404,7 @@ class EventAuthoriseRequestEmailPreview(generic.DetailView):
model = models.Event
def render_to_response(self, context, **response_kwargs):
from django.contrib.staticfiles.storage import staticfiles_storage
css = staticfiles_storage.path('css/email.css')
css = finders.find('css/email.css')
response = super(EventAuthoriseRequestEmailPreview, self).render_to_response(context, **response_kwargs)
assert isinstance(response, HttpResponse)
response.content = premailer.Premailer(response.rendered_content, external_styles=css).transform()
@@ -417,4 +418,5 @@ class EventAuthoriseRequestEmailPreview(generic.DetailView):
'sent_by': self.request.user.pk,
})
context['to_name'] = self.request.GET.get('to_name', None)
context['target'] = 'event_authorise_form_preview'
return context

View File

@@ -6,7 +6,7 @@ from io import BytesIO
from PyPDF2 import PdfFileReader, PdfFileMerger
from django.conf import settings
from django.contrib.staticfiles.storage import staticfiles_storage
from django.contrib.staticfiles import finders
from django.core.cache import cache
from django.core.mail import EmailMessage, EmailMultiAlternatives
from django.db.models.signals import post_save
@@ -63,7 +63,7 @@ def send_eventauthorisation_success_email(instance):
reply_to=[settings.AUTHORISATION_NOTIFICATION_ADDRESS],
)
css = staticfiles_storage.path('css/email.css')
css = finders.find('css/email.css')
html = Premailer(get_template("eventauthorisation_client_success.html").render(context),
external_styles=css).transform()
client_email.attach_alternative(html, 'text/html')
@@ -121,7 +121,7 @@ def send_admin_awaiting_approval_email(user, request, **kwargs):
to=[admin.email],
reply_to=[user.email],
)
css = staticfiles_storage.path('css/email.css')
css = finders.find('css/email.css')
html = Premailer(get_template("admin_awaiting_approval.html").render(context),
external_styles=css).transform()
email.attach_alternative(html, 'text/html')

View File

@@ -7,7 +7,7 @@
{% if not request.is_ajax %}
{% if perms.RIGS.view_event %}
<div class="col-sm-12 text-right">
{% include 'event_detail_buttons.html' %}
{% include 'partials/event_detail_buttons.html' %}
</div>
{% endif %}
{% endif %}
@@ -77,7 +77,7 @@
{% endif %}
{% if not request.is_ajax and perms.RIGS.view_event %}
<div class="col-sm-12 text-right">
{% include 'event_detail_buttons.html' %}
{% include 'partials/event_detail_buttons.html' %}
</div>
{% endif %}
{% if event.is_rig %}
@@ -97,7 +97,7 @@
</div>
{% if not request.is_ajax and perms.RIGS.view_event %}
<div class="col-sm-12 text-right">
{% include 'event_detail_buttons.html' %}
{% include 'partials/event_detail_buttons.html' %}
</div>
{% endif %}
{% endif %}

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE document SYSTEM "rml.dtd">
<document filename="{{filename}}">
<docinit>
<registerTTFont faceName="OpenSans" fileName="static/fonts/OpenSans-Regular.tff"/>

View File

@@ -1,10 +0,0 @@
<blockTable style="signatureTable" colWidths="50,120,60,120,35,110">
<tr>
<td>Signature</td>
<td></td>
<td>Print Name</td>
<td></td>
<td>Date</td>
<td></td>
</tr>
</blockTable>

View File

@@ -1,10 +1,10 @@
{% extends 'base_client_email.html' %}
{% block content %}
<p>Hi {{ to_name|default:"there" }},</p>
<p><b>{{ request.user.get_full_name }}</b> has requested that you authorise <b>N{{ object.pk|stringformat:"05d" }}
<p><b>{{ request.user.get_full_name }}</b> has requested that you authorise <b>{{ object.display_id }}
| {{ object.name }}</b>{% if not to_name %} on behalf of <b>{{ object.person.name }}</b>{% endif %}.</p>
<p>
@@ -23,7 +23,7 @@
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="button" align="center">
<a href="{{ request.scheme }}://{{ request.get_host }}{% url 'event_authorise' object.pk hmac %}">
<a href="{{ request.scheme }}://{{ request.get_host }}{% url target|default:'event_authorise' object.pk hmac %}">
Complete Authorisation Form
</a>
</td>

View File

@@ -1,9 +1,6 @@
{% extends 'eventauthorisation.html' %}
{% load widget_tweaks %}
{% block js %}
{% endblock %}
{% block authorisation %}
<div class="row">
<div class="col-sm-12">
@@ -86,7 +83,7 @@
<div class="text-right">
<div class="btn-group">
<button class="btn btn-primary btn-lg" type="submit">Authorise</button>
<button class="btn btn-primary btn-lg" type="submit" {% if preview %}disabled="" data-toggle="tooltip" title="This is only a preview!"{%endif%}>Authorise</button>
</div>
</div>
</div>

View File

@@ -30,14 +30,6 @@
{% render_field form.email type="email" class+="form-control" %}
</div>
</div>
<div class="text-right col-sm-3 offset-sm-9">
<div class="form-group">
<button type="submit" class="form-control btn btn-primary">
<i class="fas fa-paper-plane"></i>
Send
</button>
</div>
</div>
</form>
</div>
</div>
@@ -48,3 +40,14 @@
});
</script>
{% endblock %}
{% block footer %}
<div class="form-row">
<div class="btn-group" role="group">
<a type="button" target="_blank" href="{% url 'event_authorise_preview' object.pk %}" class="btn btn-info text-nowrap"><span class="fas fa-drafting-compass"></span> Preview</a>
<button type="submit" class="form-control btn btn-primary" form="auth-request-form">
<span class="fas fa-paper-plane"></span> Send
</button>
</div>
</div>
{% endblock %}

View File

@@ -21,7 +21,7 @@
<th scope="col">Event</th>
{# mmm hax #}
{% if object_list.0 != None %}
{% for field in object_list.0.fields %}
{% for field in object_list.0.fieldz %}
<th scope="col">{{ object_list.0|verbose_name:field|title }}</th>
{% endfor %}
{% endif %}
@@ -33,7 +33,7 @@
<tr class="{% if object.reviewed_by %}table-success{%endif%}">
{# General #}
<th scope="row"><a href="{% url 'event_detail' object.event.pk %}">{{ object.event }}</a></th>
{% for field in object_list.0.fields %}
{% for field in object_list.0.fieldz %}
<td>{{ object|get_field:field }}</td>
{% endfor %}
{# Buttons #}

View File

@@ -1,15 +1,15 @@
<div class="card card-default
{% if object.authorised %}
card-success
{% if event.authorised %}
border-success
{% elif event.authorisation and event.authorisation.amount != event.total and event.authorisation.last_edited_at > event.auth_request_at %}
card-warning
border-warning
{% elif event.auth_request_to %}
card-info
border-info
{% endif %}
">
<div class="card-header">Client Authorisation</div>
<div class="card-body row">
<dl class="col-md-6">
<dl class="col-sm-6">
<dt>Authorisation Request</dt>
<dd>{{ object.auth_request_to|yesno:"Yes,No" }}</dd>
@@ -22,8 +22,8 @@
<dt>To</dt>
<dd>{{ object.auth_request_to }}</dd>
</dl>
<dd class="d-block d-sm-none">&nbsp;</dd>
<dl class="col-md-6">
<dl class="col-sm-6">
<hr class="d-block d-sm-none">
<dt>Authorised</dt>
<dd>{{ object.authorised|yesno:"Yes,No" }}</dd>

View File

@@ -9,7 +9,7 @@
{% if event.internal %}
<a class="btn item-add modal-href event-authorise-request
{% if event.authorised %}
btn-success
btn-success active
{% elif event.authorisation and event.authorisation.amount != event.total and event.authorisation.last_edited_at > event.auth_request_at %}
btn-warning
{% elif event.auth_request_to %}
@@ -19,7 +19,7 @@
{% endif %}
"
href="{% url 'event_authorise_request' object.pk %}">
<i class="fas fa-paper-plane"></i>
<span class="fas fa-paper-plane"></span>
<span class="d-none d-sm-inline">
{% if event.authorised %}
Authorised

View File

@@ -20,15 +20,7 @@
{% if event.is_rig %}
<dt class="col-sm-6">Event MIC</dt>
<dd class="col-sm-6">
{% if event.mic and perms.RIGS.view_profile %}
<a href="{% url 'profile_detail' event.mic.pk %}" class="modal-href">
{{ event.mic.name }}
</a>
{% else %}
{{ event.mic.name }}
{% endif %}
</dd>
<dd class="col-sm-6">{% include 'partials/linked_name.html' with profile=event.mic %}</dd>
{% endif %}
<dt class="col-sm-6">Status</dt>
@@ -71,7 +63,7 @@
{% if event.dry_hire %}
<dt class="col-sm-6">Checked In By</dt>
<dd class="col-sm-6">{{ object.checked_in_by.name }}</dd>
<dd class="col-sm-6">{% include 'partials/linked_name.html' with profile=event.checked_in_by %}</dd>
{% endif %}
{% if event.is_rig %}

View File

@@ -0,0 +1,7 @@
{% if profile and perms.RIGS.view_profile %}
<a href="{% url 'profile_detail' profile.pk %}" class="modal-href">
{{ profile.name }}
</a>
{% else %}
{{ profile.name }}
{% endif %}

View File

@@ -173,7 +173,7 @@ def title_spaced(string):
@register.filter(needs_autoescape=True)
def namewithnotes(obj, url, autoescape=True):
if hasattr(obj, 'notes') and obj.notes is not None and len(obj.notes) > 0:
return mark_safe(obj.name + " <a href='{}'><span class='far fa-sticky-note'></span></a>".format(reverse(url, kwargs={'pk': obj.pk})))
return mark_safe(obj.name + " <a href='{}'><span class='fas fa-sticky-note'></span></a>".format(reverse(url, kwargs={'pk': obj.pk})))
else:
return obj.name

View File

@@ -132,6 +132,8 @@ urlpatterns = [
name='event_authorise_preview'),
re_path(r'^event/(?P<pk>\d+)/(?P<hmac>[-:\w]+)/$', rigboard.EventAuthorise.as_view(),
name='event_authorise'),
re_path(r'^event/(?P<pk>\d+)/(?P<hmac>[-:\w]+)/preview/$', rigboard.EventAuthorise.as_view(preview=True),
name='event_authorise_form_preview'),
# ICS Calendar - API key authentication
re_path(r'^ical/(?P<api_pk>\d+)/(?P<api_key>\w+)/rigs.ics$', api_key_required(ical.CalendarICS()),

View File

@@ -5,7 +5,7 @@
{% button 'submit' %}
{% elif duplicate %}
<!--duplicate-->
<button type="submit" class="btn btn-success"><i class="fas fa-check"></i> Create Duplicate</button>
<button type="submit" class="btn btn-success"><span class="fas fa-check"></span> Create Duplicate</button>
{% else %}
<!--detail view-->
<div class="btn-group">

View File

@@ -11,10 +11,7 @@
<meta name="color-scheme" content="light dark">
<link href="{% static 'fonts/OpenSans-Regular.tff' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/screen.css' %}">
</head>
<body>

View File

@@ -16,7 +16,7 @@
<th scope="row">{{ version.revision.date_created }}</th>
<td><a href="{{ version.changes.new.get_absolute_url }}">{{ version.changes.new.display_id|default:version.changes.new.pk }} | {{version.changes.new|to_class_name}}</a></td>
<td>{{ version.pk }}|{{ version.revision.pk }}</td>
<td>{{ version.revision.user.name|default:"System" }}</td>
<td>{% include 'partials/linked_name.html' with profile=version.revision.user %}</td>
<td>
{% if version.changes.old == None %}
Created {{version.changes.new|to_class_name}}