Browse Source

Refactored efling

pull/172/head
Michael Olund 5 years ago
parent
commit
24f08351ed
8 changed files with 149 additions and 148 deletions
  1. +83
    -6
      edivorce/apps/core/efilinghub.py
  2. +3
    -3
      edivorce/apps/core/middleware/keycloak.py
  3. +1
    -1
      edivorce/apps/core/tests/test_efiling_hub.py
  4. +4
    -5
      edivorce/apps/core/urls.py
  5. +12
    -16
      edivorce/apps/core/utils/cso_filing.py
  6. +43
    -0
      edivorce/apps/core/views/efiling.py
  7. +2
    -116
      edivorce/apps/core/views/main.py
  8. +1
    -1
      edivorce/apps/poc/views.py

+ 83
- 6
edivorce/apps/core/efilinghub.py View File

@ -1,12 +1,18 @@
import hashlib
import json import json
import requests
import logging import logging
import re
import requests
import uuid import uuid
from django.conf import settings from django.conf import settings
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.urls import reverse from django.urls import reverse
from edivorce.apps.core.models import Document
from edivorce.apps.core.utils.question_step_mapping import list_of_registries
from edivorce.apps.core.views.pdf import images_to_pdf, pdf_form
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
PACKAGE_DOCUMENT_FORMAT = { PACKAGE_DOCUMENT_FORMAT = {
@ -49,7 +55,7 @@ PACKAGE_FORMAT = {
class EFilingHub: class EFilingHub:
def __init__(self):
def __init__(self, initial_filing):
self.client_id = settings.EFILING_HUB_CLIENT_ID self.client_id = settings.EFILING_HUB_CLIENT_ID
self.client_secret = settings.EFILING_HUB_CLIENT_SECRET self.client_secret = settings.EFILING_HUB_CLIENT_SECRET
self.token_base_url = settings.EFILING_HUB_TOKEN_BASE_URL self.token_base_url = settings.EFILING_HUB_TOKEN_BASE_URL
@ -57,6 +63,7 @@ class EFilingHub:
self.api_base_url = settings.EFILING_HUB_API_BASE_URL self.api_base_url = settings.EFILING_HUB_API_BASE_URL
self.submission_id = None self.submission_id = None
self.initial_filing = initial_filing
def _get_token(self, request): def _get_token(self, request):
payload = f'client_id={self.client_id}&grant_type=client_credentials&client_secret={self.client_secret}' payload = f'client_id={self.client_id}&grant_type=client_credentials&client_secret={self.client_secret}'
@ -177,14 +184,83 @@ class EFilingHub:
reverse('dashboard_nav', args=['check_with_registry'])) reverse('dashboard_nav', args=['check_with_registry']))
package['navigationUrls']['error'] = request.build_absolute_uri( package['navigationUrls']['error'] = request.build_absolute_uri(
reverse('dashboard_nav', args=['check_with_registry'])) reverse('dashboard_nav', args=['check_with_registry']))
package['navigationUrls']['cancel'] = request.build_absolute_uri(
reverse('dashboard_nav', args=['check_with_registry']))
if self.initial_filing:
package['navigationUrls']['cancel'] = request.build_absolute_uri(
reverse('dashboard_nav', args=['initial_filing']))
else:
package['navigationUrls']['cancel'] = request.build_absolute_uri(
reverse('dashboard_nav', args=['final_filing']))
return package return package
def _get_data(self, request, responses, uploaded, generated):
post_files = []
documents = []
for form in generated:
document = self._get_document(form['doc_type'], 0)
pdf_response = pdf_form(request, str(form['form_number']))
document['md5'] = hashlib.md5(pdf_response.content).hexdigest()
post_files.append(('files', (document['name'], pdf_response.content)))
documents.append(document)
for form in uploaded:
party_code = form['party_code']
doc_type = form['doc_type']
pdf_response = images_to_pdf(request, doc_type, party_code)
if pdf_response.status_code == 200:
document = self._get_document(doc_type, party_code)
document['md5'] = hashlib.md5(pdf_response.content).hexdigest()
post_files.append(('files', (document['name'], pdf_response.content)))
documents.append(document)
# generate the list of parties to send to eFiling Hub
parties = []
party1 = PACKAGE_PARTY_FORMAT.copy()
party1['firstName'] = responses.get('given_name_1_you', '').strip()
party1['middleName'] = (responses.get('given_name_2_you', '') +
' ' +
responses.get('given_name_3_you', '')).strip()
party1['lastName'] = responses.get('last_name_you', '').strip()
parties.append(party1)
party2 = PACKAGE_PARTY_FORMAT.copy()
party2['firstName'] = responses.get('given_name_1_spouse', '').strip()
party2['middleName'] = (responses.get('given_name_2_spouse', '') +
' ' +
responses.get('given_name_3_spouse', '')).strip()
party2['lastName'] = responses.get('last_name_spouse', '').strip()
parties.append(party2)
location_name = responses.get('court_registry_for_filing', '')
location = list_of_registries.get(location_name, '0000')
package_data = self._format_package(request, post_files, documents, parties, location)
return package_data, post_files
def _get_document(self, doc_type, party_code):
document = PACKAGE_DOCUMENT_FORMAT.copy()
filename = self._get_filename(doc_type, party_code)
document['name'] = filename
document['type'] = doc_type
return document
def _get_filename(self, doc_type, party_code):
form_name = Document.form_types[doc_type]
slug = re.sub('[^0-9a-zA-Z]+', '-', form_name).strip('-')
if party_code == 0:
return slug + ".pdf"
elif party_code == 1:
return slug + "--Claimant1.pdf"
else:
return slug + "--Claimant2.pdf"
# -- EFILING HUB INTERFACE -- # -- EFILING HUB INTERFACE --
def upload(self, request, files, documents=None, parties=None, location=None):
def upload(self, request, responses, uploaded, generated):
""" """
Does an initial upload of documents and gets the generated eFiling Hub url. Does an initial upload of documents and gets the generated eFiling Hub url.
:param parties: :param parties:
@ -202,6 +278,8 @@ class EFilingHub:
if bce_id is None: if bce_id is None:
raise PermissionDenied() raise PermissionDenied()
package_data, files = self._get_data(request, responses, uploaded, generated)
url = f'{self.api_base_url}/submission/documents' url = f'{self.api_base_url}/submission/documents'
response = self._get_api(request, url, transaction_id, bce_id, headers={}, files=files) response = self._get_api(request, url, transaction_id, bce_id, headers={}, files=files)
if response.status_code == 200: if response.status_code == 200:
@ -212,7 +290,6 @@ class EFilingHub:
headers = { headers = {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
} }
package_data = self._format_package(request, files, documents, parties, location)
url = f"{self.api_base_url}/submission/{response['submissionId']}/generateUrl" url = f"{self.api_base_url}/submission/{response['submissionId']}/generateUrl"
response = self._get_api(request, url, transaction_id, bce_id, headers=headers, response = self._get_api(request, url, transaction_id, bce_id, headers=headers,
data=json.dumps(package_data)) data=json.dumps(package_data))


+ 3
- 3
edivorce/apps/core/middleware/keycloak.py View File

@ -2,8 +2,6 @@ from django.conf import settings
from mozilla_django_oidc.auth import OIDCAuthenticationBackend from mozilla_django_oidc.auth import OIDCAuthenticationBackend
from mozilla_django_oidc.utils import absolutify from mozilla_django_oidc.utils import absolutify
from ..models import BceidUser
class EDivorceKeycloakBackend(OIDCAuthenticationBackend): class EDivorceKeycloakBackend(OIDCAuthenticationBackend):
@ -35,7 +33,7 @@ class EDivorceKeycloakBackend(OIDCAuthenticationBackend):
user.user_guid = claims.get('universal-id', '') user.user_guid = claims.get('universal-id', '')
user.save() user.save()
self.request.session['bcgov_userguid'] = user.user_guid
self.request.session['bcgov_userguid'] = user.user_guid
return user return user
@ -47,6 +45,8 @@ class EDivorceKeycloakBackend(OIDCAuthenticationBackend):
def keycloak_logout(request): def keycloak_logout(request):
request.session.flush()
redirect_uri = absolutify(request, settings.FORCE_SCRIPT_NAME) redirect_uri = absolutify(request, settings.FORCE_SCRIPT_NAME)
return f'{settings.KEYCLOAK_LOGOUT}?redirect_uri={redirect_uri}' return f'{settings.KEYCLOAK_LOGOUT}?redirect_uri={redirect_uri}'

+ 1
- 1
edivorce/apps/core/tests/test_efiling_hub.py View File

@ -47,7 +47,7 @@ class EFilingHubTests(TransactionTestCase):
middleware.process_request(self.request) middleware.process_request(self.request)
self.request.session.save() self.request.session.save()
self.hub = EFilingHub()
self.hub = EFilingHub(initial_filing=True)
def _mock_response(self, status=200, text="Text", json_data=None, raise_for_status=None): def _mock_response(self, status=200, text="Text", json_data=None, raise_for_status=None):
mock_resp = mock.Mock() mock_resp = mock.Mock()


+ 4
- 5
edivorce/apps/core/urls.py View File

@ -1,7 +1,7 @@
from django.conf.urls import url from django.conf.urls import url
from django.urls import path from django.urls import path
from .views import main, system, pdf, api
from .views import main, system, pdf, api, efiling
urlpatterns = [ urlpatterns = [
# url(r'^guide$', styleguide.guide), # url(r'^guide$', styleguide.guide),
@ -13,17 +13,16 @@ urlpatterns = [
# we add an extra 'x' to the file extension so the siteminder proxy doesn't treat it as an image # we add an extra 'x' to the file extension so the siteminder proxy doesn't treat it as an image
path('api/documents/<doc_type>/<int:party_code>/<filename>x/<int:size>/', api.DocumentView.as_view(), name='document'), path('api/documents/<doc_type>/<int:party_code>/<filename>x/<int:size>/', api.DocumentView.as_view(), name='document'),
url(r'^signin$', main.signin, name="signin"),
url(r'^signin$', main.after_login, name="signin"),
url(r'^register$', main.register, name="register"), url(r'^register$', main.register, name="register"),
url(r'^register_sc$', main.register_sc, name="register_sc"), url(r'^register_sc$', main.register_sc, name="register_sc"),
url(r'^logout$', main.logout, name="logout"),
url(r'^overview$', main.overview, name="overview"), url(r'^overview$', main.overview, name="overview"),
url(r'^success$', main.success, name="success"), url(r'^success$', main.success, name="success"),
url(r'^incomplete$', main.incomplete, name="incomplete"), url(r'^incomplete$', main.incomplete, name="incomplete"),
url(r'^intercept$', main.intercept_page, name="intercept"), url(r'^intercept$', main.intercept_page, name="intercept"),
url(r'^dashboard/(?P<nav_step>.*)', main.dashboard_nav, name="dashboard_nav"), url(r'^dashboard/(?P<nav_step>.*)', main.dashboard_nav, name="dashboard_nav"),
path('submit/initial', main.submit_initial_files, name="submit_initial_files"),
path('submit/final', main.submit_final_files, name="submit_final_files"),
path('submit/initial', efiling.submit_initial_files, name="submit_initial_files"),
path('submit/final', efiling.submit_final_files, name="submit_final_files"),
url(r'^health$', system.health), url(r'^health$', system.health),
url(r'^legal$', main.legal, name="legal"), url(r'^legal$', main.legal, name="legal"),
url(r'^acknowledgements$', main.acknowledgements, name="acknowledgements"), url(r'^acknowledgements$', main.acknowledgements, name="acknowledgements"),


+ 12
- 16
edivorce/apps/core/utils/cso_filing.py View File

@ -1,22 +1,29 @@
import random import random
import re
from django.conf import settings from django.conf import settings
from edivorce.apps.core.efilinghub import EFilingHub
from edivorce.apps.core.models import Document, UserResponse from edivorce.apps.core.models import Document, UserResponse
from edivorce.apps.core.utils.derived import get_derived_data from edivorce.apps.core.utils.derived import get_derived_data
def file_documents(user, responses, initial=False):
(forms, _) = forms_to_file(responses, initial)
def file_documents(request, responses, initial=False):
user = request.user
(uploaded, generated) = forms_to_file(responses, initial)
missing_forms = [] missing_forms = []
for form in forms:
for form in uploaded:
docs = Document.objects.filter(bceid_user=user, doc_type=form['doc_type'], party_code=form.get('party_code', 0)) docs = Document.objects.filter(bceid_user=user, doc_type=form['doc_type'], party_code=form.get('party_code', 0))
if docs.count() == 0: if docs.count() == 0:
missing_forms.append(Document.form_types[form['doc_type']]) missing_forms.append(Document.form_types[form['doc_type']])
if missing_forms: if missing_forms:
return missing_forms
return missing_forms, None
hub = EFilingHub(initial_filing=initial)
redirect_url, msg = hub.upload(request, responses, uploaded, generated)
if redirect_url:
return None, redirect_url
# Save dummy data for now. Eventually replace with data from CSO # Save dummy data for now. Eventually replace with data from CSO
prefix = 'initial' if initial else 'final' prefix = 'initial' if initial else 'final'
@ -150,14 +157,3 @@ def forms_to_file(responses_dict, initial=False):
return [], [] return [], []
return uploaded, generated return uploaded, generated
def get_filename(doc_type, party_code):
form_name = Document.form_types[doc_type]
slug = re.sub('[^0-9a-zA-Z]+', '-', form_name).strip('-')
if party_code == 0:
return slug + ".pdf"
elif party_code == 1:
return slug + "--Claimant1.pdf"
else:
return slug + "--Claimant2.pdf"

+ 43
- 0
edivorce/apps/core/views/efiling.py View File

@ -0,0 +1,43 @@
from django.contrib import messages
from django.shortcuts import redirect
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from ..decorators import prequal_completed
from ..utils.cso_filing import file_documents
from ..utils.user_response import get_data_for_user
@login_required
@prequal_completed
def submit_initial_files(request):
return _submit_files(request, initial=True)
@login_required
@prequal_completed
def submit_final_files(request):
return _submit_files(request, initial=False)
def _submit_files(request, initial=False):
responses_dict = get_data_for_user(request.user)
if initial:
original_step = 'initial_filing'
next_page = 'wait_for_number'
else:
original_step = 'final_filing'
next_page = 'next_steps'
missing_forms, hub_redirect_url = file_documents(request, responses_dict, initial=initial)
if hub_redirect_url:
return redirect(hub_redirect_url)
if missing_forms:
next_page = original_step
for form_name in missing_forms:
messages.add_message(request, messages.ERROR, f'Missing documents for {form_name}')
responses_dict['active_page'] = next_page
return redirect(reverse('dashboard_nav', kwargs={'nav_step': next_page}), context=responses_dict)

+ 2
- 116
edivorce/apps/core/views/main.py View File

@ -1,17 +1,12 @@
import datetime
import hashlib
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.urls import reverse from django.urls import reverse
from django.utils import timezone
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from edivorce.apps.core.utils.derived import get_derived_data from edivorce.apps.core.utils.derived import get_derived_data
from ..decorators import intercept, prequal_completed from ..decorators import intercept, prequal_completed
from ..utils.cso_filing import file_documents, forms_to_file, get_filename
from ..efilinghub import EFilingHub, PACKAGE_PARTY_FORMAT, PACKAGE_DOCUMENT_FORMAT
from ..utils.cso_filing import forms_to_file
from ..utils.question_step_mapping import list_of_registries from ..utils.question_step_mapping import list_of_registries
from ..utils.step_completeness import get_error_dict, get_missed_question_keys, get_step_completeness, is_complete, get_formatted_incomplete_list from ..utils.step_completeness import get_error_dict, get_missed_question_keys, get_step_completeness, is_complete, get_formatted_incomplete_list
from ..utils.template_step_order import template_step_order from ..utils.template_step_order import template_step_order
@ -22,7 +17,6 @@ from ..utils.user_response import (
get_responses_from_session, get_responses_from_session,
get_responses_from_session_grouped_by_steps, get_responses_from_session_grouped_by_steps,
) )
from .pdf import images_to_pdf, pdf_form
def home(request): def home(request):
@ -117,34 +111,15 @@ def register_sc(request):
return redirect(settings.REGISTER_BCSC_URL) return redirect(settings.REGISTER_BCSC_URL)
def signin(request):
def after_login(request):
if not request.user.is_authenticated: if not request.user.is_authenticated:
return render(request, '407.html') return render(request, '407.html')
# I think Django might be doing this automatically now that we have switched to mozilla-django-oidc?
# if timezone.now() - request.user.last_login > datetime.timedelta(minutes=1):
# request.user.last_login = timezone.now()
# request.user.save()
copy_session_to_db(request, request.user) copy_session_to_db(request, request.user)
return redirect(settings.PROXY_BASE_URL + settings.FORCE_SCRIPT_NAME[:-1] + '/overview') return redirect(settings.PROXY_BASE_URL + settings.FORCE_SCRIPT_NAME[:-1] + '/overview')
def logout(request):
"""
Clear session and log out of BCeID
"""
request.session.flush()
response = redirect(settings.LOGOUT_URL)
if settings.DEPLOYMENT_TYPE in ['localdev', 'minishift']:
response = redirect('/')
return response
@login_required @login_required
@prequal_completed @prequal_completed
@intercept @intercept
@ -205,95 +180,6 @@ def dashboard_nav(request, nav_step):
return render(request, template_name=template_name, context=responses_dict) return render(request, template_name=template_name, context=responses_dict)
@login_required
@prequal_completed
def submit_initial_files(request):
return _submit_files(request, initial=True)
@login_required
@prequal_completed
def submit_final_files(request):
return _submit_files(request, initial=False)
def _submit_files(request, initial=False):
responses_dict = get_data_for_user(request.user)
if initial:
original_step = 'initial_filing'
next_page = 'wait_for_number'
else:
original_step = 'final_filing'
next_page = 'next_steps'
missing_forms = file_documents(request.user, responses_dict, initial=initial)
if missing_forms:
next_page = original_step
for form_name in missing_forms:
messages.add_message(request, messages.ERROR, f'Missing documents for {form_name}')
responses_dict['active_page'] = next_page
#################
# todo: refactor this!!!!
post_files = []
documents = []
(uploaded, generated) = forms_to_file(responses_dict, initial)
for form in generated:
pdf_response = pdf_form(request, str(form['form_number']))
document = PACKAGE_DOCUMENT_FORMAT.copy()
filename = get_filename(form['doc_type'], 0)
document['name'] = filename
document['type'] = form['doc_type']
document['md5'] = hashlib.md5(pdf_response.content).hexdigest()
post_files.append(('files', (filename, pdf_response.content)))
documents.append(document)
for form in uploaded:
pdf_response = images_to_pdf(request, form['doc_type'], form['party_code'])
if pdf_response.status_code == 200:
document = PACKAGE_DOCUMENT_FORMAT.copy()
filename = get_filename(form['doc_type'], 0)
document['name'] = filename
document['type'] = form['doc_type']
document['md5'] = hashlib.md5(pdf_response.content).hexdigest()
post_files.append(('files', (filename, pdf_response.content)))
documents.append(document)
# generate the list of parties to send to eFiling Hub
parties = []
party1 = PACKAGE_PARTY_FORMAT.copy()
party1['firstName'] = responses_dict.get('given_name_1_you', '').strip()
party1['middleName'] = (responses_dict.get('given_name_2_you', '') +
' ' +
responses_dict.get('given_name_3_you', '')).strip()
party1['lastName'] = responses_dict.get('last_name_you', '').strip()
parties.append(party1)
party2 = PACKAGE_PARTY_FORMAT.copy()
party2['firstName'] = responses_dict.get('given_name_1_spouse', '').strip()
party2['middleName'] = (responses_dict.get('given_name_2_spouse', '') +
' ' +
responses_dict.get('given_name_3_spouse', '')).strip()
party2['lastName'] = responses_dict.get('last_name_spouse', '').strip()
parties.append(party2)
location_name = responses_dict.get('court_registry_for_filing', '')
location = list_of_registries.get(location_name, '0000')
hub = EFilingHub()
redirect_url, msg = hub.upload(request, post_files, documents, parties, location)
if redirect_url:
return redirect(redirect_url)
#################
return redirect(reverse('dashboard_nav', kwargs={'nav_step': next_page}), context=responses_dict)
@login_required @login_required
@prequal_completed @prequal_completed
def question(request, step, sub_step=None): def question(request, step, sub_step=None):


+ 1
- 1
edivorce/apps/poc/views.py View File

@ -99,7 +99,7 @@ class EfilingHubUpload(FormView):
party['lastName'] = 'Test' party['lastName'] = 'Test'
parties.append(party) parties.append(party)
hub = EFilingHub()
hub = EFilingHub(initial_filing=True)
redirect, msg = hub.upload(request, post_files, parties=parties) redirect, msg = hub.upload(request, post_files, parties=parties)
if redirect: if redirect:
self.success_url = redirect self.success_url = redirect


Loading…
Cancel
Save