diff --git a/edivorce/apps/core/efilinghub.py b/edivorce/apps/core/efilinghub.py
index 931f372d..f618c2aa 100644
--- a/edivorce/apps/core/efilinghub.py
+++ b/edivorce/apps/core/efilinghub.py
@@ -1,12 +1,19 @@
+import datetime
+import hashlib
import json
-import requests
import logging
+import re
+import requests
import uuid
from django.conf import settings
from django.core.exceptions import PermissionDenied
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__)
PACKAGE_DOCUMENT_FORMAT = {
@@ -46,10 +53,58 @@ PACKAGE_FORMAT = {
}
}
+NJF_ALIAS_FORMAT = {
+ "nameType": "AKA",
+ "surname": "",
+ "given1": "",
+ "given2": "",
+ "given3": ""
+}
+
+NJF_JSON_FORMAT = {
+ "parties": [
+ {
+ "label": "Claimant 1",
+ "surname": "",
+ "given1": "",
+ "given2": "",
+ "given3": "",
+ "birthDate": "",
+ "email": "",
+ "aliases": [],
+ "surnameAtBirth": "",
+ "surnameBeforeMarriage": "",
+ "signingVirtually": False
+ },
+ {
+ "label": "Claimant 2",
+ "surname": "",
+ "given1": "",
+ "given2": "",
+ "given3": "",
+ "birthDate": "",
+ "email": "",
+ "aliases": [],
+ "surnameAtBirth": "",
+ "surnameBeforeMarriage": "",
+ "signingVirtually": False
+ }
+ ],
+ "placeOfMarriage": {
+ "country": "",
+ "province": "",
+ "city": ""
+ },
+ "dateOfMarriage": "",
+ "reasonForDivorce": "S",
+ "act": "",
+ "ordersSought": []
+}
+
class EFilingHub:
- def __init__(self):
+ def __init__(self, initial_filing):
self.client_id = settings.EFILING_HUB_CLIENT_ID
self.client_secret = settings.EFILING_HUB_CLIENT_SECRET
self.token_base_url = settings.EFILING_HUB_TOKEN_BASE_URL
@@ -57,6 +112,7 @@ class EFilingHub:
self.api_base_url = settings.EFILING_HUB_API_BASE_URL
self.submission_id = None
+ self.initial_filing = initial_filing
def _get_token(self, request):
payload = f'client_id={self.client_id}&grant_type=client_credentials&client_secret={self.client_secret}'
@@ -177,12 +233,141 @@ class EFilingHub:
reverse('dashboard_nav', args=['check_with_registry']))
package['navigationUrls']['error'] = request.build_absolute_uri(
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
+ 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"
+
+ def _get_json_data(self, responses):
+
+ def format_date(str):
+ try:
+ return datetime.datetime.strptime(str, '%b %d, %Y').strftime('%Y-%m-%d')
+ except:
+ return ''
+
+ r = responses
+ d = NJF_JSON_FORMAT.copy()
+
+ signing_location_you = ''
+ signing_location_spouse = ''
+
+ if r.get('how_to_sign') == 'Together':
+ signing_location_you = r.get('signing_location')
+ signing_location_spouse = r.get('signing_location')
+ elif r.get('how_to_sign') == 'Separately':
+ signing_location_you = r.get('signing_location_you')
+ signing_location_spouse = r.get('signing_location_spouse')
+
+ party1 = d["parties"][0]
+ party1["surname"] = r.get('last_name_you', '').strip()
+ party1["given1"] = r.get('given_name_1_you', '').strip()
+ party1["given2"] = r.get('given_name_2_you', '').strip()
+ party1["given3"] = r.get('given_name_3_you', '').strip()
+ party1["birthDate"] = format_date(r.get('birthday_you'))
+ party1["surnameAtBirth"] = r.get('last_name_born_you', '').strip()
+ party1["surnameBeforeMarriage"] = r.get('last_name_before_married_you', '').strip()
+ email = r.get('email_you', '').strip()
+ if not email:
+ email = r.get('address_to_send_official_document_email_you', '').strip()
+ party1["email"] = email
+ party1["signingVirtually"] = signing_location_you == 'Virtual'
+ party1["aliases"] = []
+
+ party2 = d["parties"][1]
+ party2["surname"] = r.get('last_name_spouse', '').strip()
+ party2["given1"] = r.get('given_name_1_spouse', '').strip()
+ party2["given2"] = r.get('given_name_2_spouse', '').strip()
+ party2["given3"] = r.get('given_name_3_spouse', '').strip()
+ party2["birthDate"] = format_date(r.get('birthday_spouse'))
+ party2["surnameAtBirth"] = r.get('last_name_born_spouse', '').strip()
+ party2["surnameBeforeMarriage"] = r.get('last_name_before_married_spouse', '').strip()
+ email = r.get('email_spouse', '').strip()
+ if not email:
+ email = r.get('address_to_send_official_document_email_spouse', '').strip()
+ party2["email"] = email
+ party2["signingVirtually"] = signing_location_spouse == 'Virtual'
+ party2["aliases"] = []
+
+ d["dateOfMarriage"] = format_date(r.get('when_were_you_married'))
+
+ return d
+
# -- EFILING HUB INTERFACE --
+ def get_files(self, request, responses, uploaded, generated):
+
+ post_files = []
+ documents = []
+
+ for form in generated:
+ doc_type = form['doc_type']
+ document = self._get_document(doc_type, 0)
+ if doc_type == 'NJF':
+ document['data'] = self._get_json_data(responses)
+ 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)
+
+ return post_files, documents
+
+ def get_parties(self, responses):
+
+ # 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)
+
+ return parties
+
+ def get_location(self, responses):
+ location_name = responses.get('court_registry_for_filing', '')
+ return list_of_registries.get(location_name, '0000')
def upload(self, request, files, documents=None, parties=None, location=None):
"""
@@ -202,6 +387,8 @@ class EFilingHub:
if bce_id is None:
raise PermissionDenied()
+ # package_data, files = self._get_data(request, responses, uploaded, generated)
+
url = f'{self.api_base_url}/submission/documents'
response = self._get_api(request, url, transaction_id, bce_id, headers={}, files=files)
if response.status_code == 200:
@@ -214,8 +401,8 @@ class EFilingHub:
}
package_data = self._format_package(request, files, documents, parties, location)
url = f"{self.api_base_url}/submission/{response['submissionId']}/generateUrl"
- response = self._get_api(request, url, transaction_id, bce_id, headers=headers,
- data=json.dumps(package_data))
+ data = json.dumps(package_data)
+ response = self._get_api(request, url, transaction_id, bce_id, headers, data)
if response.status_code == 200:
response = json.loads(response.text)
diff --git a/edivorce/apps/core/middleware/keycloak.py b/edivorce/apps/core/middleware/keycloak.py
index b25187ef..a4260536 100644
--- a/edivorce/apps/core/middleware/keycloak.py
+++ b/edivorce/apps/core/middleware/keycloak.py
@@ -2,8 +2,6 @@ from django.conf import settings
from mozilla_django_oidc.auth import OIDCAuthenticationBackend
from mozilla_django_oidc.utils import absolutify
-from ..models import BceidUser
-
class EDivorceKeycloakBackend(OIDCAuthenticationBackend):
@@ -35,7 +33,7 @@ class EDivorceKeycloakBackend(OIDCAuthenticationBackend):
user.user_guid = claims.get('universal-id', '')
user.save()
- self.request.session['bcgov_userguid'] = user.user_guid
+ self.request.session['bcgov_userguid'] = user.user_guid
return user
@@ -47,6 +45,8 @@ class EDivorceKeycloakBackend(OIDCAuthenticationBackend):
def keycloak_logout(request):
+ request.session.flush()
+
redirect_uri = absolutify(request, settings.FORCE_SCRIPT_NAME)
return f'{settings.KEYCLOAK_LOGOUT}?redirect_uri={redirect_uri}'
diff --git a/edivorce/apps/core/templates/success.html b/edivorce/apps/core/templates/success.html
index 5e2be4ea..2dd9aa5b 100644
--- a/edivorce/apps/core/templates/success.html
+++ b/edivorce/apps/core/templates/success.html
@@ -28,7 +28,7 @@
Login with a
BCeID or BC Services Card
Once you login, you’ll be taken back to this website.
-
+
Login
diff --git a/edivorce/apps/core/templatetags/format_utils.py b/edivorce/apps/core/templatetags/format_utils.py
index 9959c17c..988eae47 100644
--- a/edivorce/apps/core/templatetags/format_utils.py
+++ b/edivorce/apps/core/templatetags/format_utils.py
@@ -117,7 +117,7 @@ def age(date):
printing '46 years' instead of print '46 years, 7 months'.
"""
try:
- birth = datetime.strptime(date, '%b %d, %Y')
+ birth = datetime.strptime(date, strptime)
except ValueError:
try:
birth = datetime.strptime(date, '%b %d, %Y')
diff --git a/edivorce/apps/core/tests/test_efiling_hub.py b/edivorce/apps/core/tests/test_efiling_hub.py
index 79e3380b..6bf11565 100644
--- a/edivorce/apps/core/tests/test_efiling_hub.py
+++ b/edivorce/apps/core/tests/test_efiling_hub.py
@@ -47,7 +47,7 @@ class EFilingHubTests(TransactionTestCase):
middleware.process_request(self.request)
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):
mock_resp = mock.Mock()
diff --git a/edivorce/apps/core/urls.py b/edivorce/apps/core/urls.py
index ce578fac..fb749177 100644
--- a/edivorce/apps/core/urls.py
+++ b/edivorce/apps/core/urls.py
@@ -1,7 +1,7 @@
from django.conf.urls import url
from django.urls import path
-from .views import main, system, pdf, api
+from .views import main, system, pdf, api, efiling
urlpatterns = [
# 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
path('api/documents///x//', 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_sc$', main.register_sc, name="register_sc"),
- url(r'^logout$', main.logout, name="logout"),
url(r'^overview$', main.overview, name="overview"),
url(r'^success$', main.success, name="success"),
url(r'^incomplete$', main.incomplete, name="incomplete"),
url(r'^intercept$', main.intercept_page, name="intercept"),
url(r'^dashboard/(?P.*)', 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'^legal$', main.legal, name="legal"),
url(r'^acknowledgements$', main.acknowledgements, name="acknowledgements"),
diff --git a/edivorce/apps/core/utils/cso_filing.py b/edivorce/apps/core/utils/cso_filing.py
index 317e293b..ae8925be 100644
--- a/edivorce/apps/core/utils/cso_filing.py
+++ b/edivorce/apps/core/utils/cso_filing.py
@@ -1,13 +1,14 @@
import random
-import re
from django.conf import settings
+from edivorce.apps.core.efilinghub import EFilingHub
from edivorce.apps.core.models import Document, UserResponse
from edivorce.apps.core.utils.derived import get_derived_data
-def file_documents(user, responses, initial=False):
+def file_documents(request, responses, initial=False):
+ user = request.user
errors = []
if not initial:
user_has_submitted_initial = _get_response(user, 'initial_filing_submitted')
@@ -16,14 +17,26 @@ def file_documents(user, responses, initial=False):
court_file_number = _get_response(user, 'court_file_number')
if not court_file_number:
errors.append("You must input your Court File Number")
- uploaded_forms, _ = forms_to_file(responses, initial)
- for form in uploaded_forms:
+
+ uploaded, generated = forms_to_file(responses, initial)
+ for form in uploaded:
docs = Document.objects.filter(bceid_user=user, doc_type=form['doc_type'], party_code=form.get('party_code', 0))
if docs.count() == 0:
errors.append(f"Missing documents for {Document.form_types[form['doc_type']]}")
if errors:
- return errors
+ return errors, None
+
+ hub = EFilingHub(initial_filing=initial)
+
+ post_files, documents = hub.get_files(request, responses, uploaded, generated)
+ location = hub.get_location(responses)
+ parties = hub.get_parties(responses)
+
+ redirect_url, msg = hub.upload(request, post_files, documents, parties, location)
+
+ if redirect_url:
+ return errors, redirect_url
# Save dummy data for now. Eventually replace with data from CSO
prefix = 'initial' if initial else 'final'
@@ -52,6 +65,7 @@ def file_documents(user, responses, initial=False):
package_link = base_url + '/cso/register.do?packageNumber=' + package_number
_save_response(user, f'{prefix}_filing_package_link', package_link)
+ return None, None
def _save_response(user, question, value):
@@ -164,14 +178,3 @@ def forms_to_file(responses_dict, initial=False):
return [], []
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"
diff --git a/edivorce/apps/core/views/efiling.py b/edivorce/apps/core/views/efiling.py
new file mode 100644
index 00000000..470035fb
--- /dev/null
+++ b/edivorce/apps/core/views/efiling.py
@@ -0,0 +1,45 @@
+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)
+
+ errors, hub_redirect_url = file_documents(request, responses_dict, initial=initial)
+
+ if hub_redirect_url:
+ return redirect(hub_redirect_url)
+
+ if initial:
+ original_step = 'initial_filing'
+ next_page = 'wait_for_number'
+ else:
+ original_step = 'final_filing'
+ next_page = 'next_steps'
+
+ if errors:
+ next_page = original_step
+ for error in errors:
+ messages.add_message(request, messages.ERROR, error)
+
+ responses_dict['active_page'] = next_page
+
+ return redirect(reverse('dashboard_nav', kwargs={'nav_step': next_page}), context=responses_dict)
diff --git a/edivorce/apps/core/views/main.py b/edivorce/apps/core/views/main.py
index 14cc384b..5970880b 100644
--- a/edivorce/apps/core/views/main.py
+++ b/edivorce/apps/core/views/main.py
@@ -1,17 +1,12 @@
-import datetime
-import hashlib
-
from django.conf import settings
from django.contrib import messages
from django.shortcuts import render, redirect
from django.urls import reverse
-from django.utils import timezone
from django.contrib.auth.decorators import login_required
from edivorce.apps.core.utils.derived import get_derived_data
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.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
@@ -22,7 +17,6 @@ from ..utils.user_response import (
get_responses_from_session,
get_responses_from_session_grouped_by_steps,
)
-from .pdf import images_to_pdf, pdf_form
def home(request):
@@ -117,34 +111,15 @@ def register_sc(request):
return redirect(settings.REGISTER_BCSC_URL)
-def signin(request):
+def after_login(request):
if not request.user.is_authenticated:
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)
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
@prequal_completed
@intercept
@@ -218,97 +193,6 @@ def _add_error_messages(nav_step, request, responses_dict):
'Please try again now and if this issue persists try again later.')
-@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'
- errors = file_documents(request.user, responses_dict, initial=initial)
- if errors:
- next_page = original_step
- for error in errors:
- messages.add_message(request, messages.ERROR, error)
- responses_dict['active_page'] = next_page
- return redirect(reverse('dashboard_nav', kwargs={'nav_step': next_page}), context=responses_dict)
- 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
@prequal_completed
def question(request, step, sub_step=None):
diff --git a/edivorce/apps/poc/views.py b/edivorce/apps/poc/views.py
index 69c8c566..f6f09fae 100644
--- a/edivorce/apps/poc/views.py
+++ b/edivorce/apps/poc/views.py
@@ -99,7 +99,7 @@ class EfilingHubUpload(FormView):
party['lastName'] = 'Test'
parties.append(party)
- hub = EFilingHub()
+ hub = EFilingHub(initial_filing=True)
redirect, msg = hub.upload(request, post_files, parties=parties)
if redirect:
self.success_url = redirect