+ This is the affidavit
+ of {% required responses.name_you %} and
+ {% required responses.name_spouse %} in this case,
+ and was made on
+
+
+
+ In the Supreme Court of British Columbia
+
+
+
+
+
Claimant 1:
+
+
{% include "partials/name_with_alias.html" with name=responses.name_you use_other_name=responses.any_other_name_you other_names=responses.other_name_you class_name='form-entry_claimant' %}
+
+
Claimant 1:
+
+
{% include "partials/name_with_alias.html" with name=responses.name_spouse use_other_name=responses.any_other_name_spouse other_names=responses.other_name_spouse class_name='form-entry_claimant' %}
+ {% if derived.wants_child_support %}
+ The Notice of Joint Family Claim includes a claim for a child
+ support order.
+ {% else %}
+ The Notice of Joint Family Claim never included a claim for a child
+ support order.
+ {% endif %}
+
+
+
+
+
Claimant 1's annual income as determined under sections 15 to
+ 20 of the Guidelines: $amount
+
Claimant 2's annual income as determined under sections 15 to
+ 20 of the Guidelines: $amount
+
Claimant 1 and Claimant 2 have entered into an agreement as
+ to income pursuant to section 15(2) of the Guidelines, a copy
+ of which agreement is attached.
+
Section 4 is omitted as inapplicable.
+
+
+
+
+ {% if derived.has_fact_sheets %}
+ I have completed and attached to this Affidavit:
+ {% if derived.show_fact_sheet_b %}Supplementary Child Support Fact Sheet B {% endif %}
+ {% if derived.show_fact_sheet_c %}Supplementary Child Support Fact Sheet C {% endif %}
+ {% if derived.show_fact_sheet_d %}Supplementary Child Support Fact Sheet D {% endif %}
+ {% if derived.show_fact_sheet_e %}Supplementary Child Support Fact Sheet E {% endif %}
+ {% if derived.show_fact_sheet_f %}Supplementary Child Support Fact Sheet F {% endif %}
+ {% else %}
+ The monthly amount in Schedule 1 of the Guidelines is
+ {{ derived.schedule_1_amount|money }}, payable by
+ {{ derived.schedule_1_payor }}.
+ {% endif %}
+
+
+
+ The proposed order sets out that $amount is the amount of child
+ support payable by Claimant 1 or Claimant 2 which amount accords
+ with the Guidelines.
+
+ The proposed order by consent, pursuant to section 15.1(7) of the
+ Divorce Act (Canada) or section 150(2) of the Family Law Act,
+ sets out that $amount is the amount of child support payable by
+ Claimant 1 orClaimant 2, which amount is different than the amount
+ required by the Guidelines.
+
+ The proposed order sets out that $amount is the amount of child
+ support payable by Claimant 1 or Claimant 2, which amount is
+ different than the amount required by the Guidelines, but the
+ following special provisions, within the meaning of section 15.1(5)
+ of the Divorce Act(Canada), have been made: describe
+
+ The proposed order sets out that $amount is the amount of child
+ support payable by Claimant 1 or Claimant 2, in accordance with the
+ agreement referred to in section 4(c) of this Affidavit.
+
+ The proposed order does not include child support but the following
+ arrangements have been made for the support of the child: describe
+
+
+
+ {% if 'None' in responses.special_extraordinary_expenses %}
+ Expenses under section 7 of the Child Support Guidelines are not
+ included in the proposed order.
+ {% else %}
+ I have completed and attached to this affidavit Supplementary
+ Child Support Fact Sheet A (special expenses), and the amount set
+ out in the proposed order for the expenses under section 7 of the
+ Guidelines is $amount.
+ {% endif %}
+
+
+
+ Medical coverage is available for the children under Claimant 1's
+ medical insurance plan.
+
+ Medical coverage is available for the children under Claimant 2's
+ medical insurance plan.
+
+ Medical coverage is not available for the children under either of
+ the party’s medical insurance plans.
+
+
+
+ {% if responses.have_court_order == 'YES' %}
+ Attached as Exhibit {{ exhibits.pop }} is the order in force
+ that deals with the support of the children.
+ {% else %}
+ There is no order of any court in force dealing with support of the
+ children.
+ {% endif %}
+
+
+
+ {% if responses.have_separation_agreement == 'YES' %}
+ Attached as Exhibit {{ exhibits.pop }} is the written
+ agreement that deals with the support of the children.
+ {% else %}
+ There is no agreement dealing with support of the children.
+ {% endif %}
+
+
+
+ The amount of arrears of child support, as at date, under any
+ existing order or written agreement is nil or$amount.
+
+
+
+
+
+
+
+
+
+
SWORN (OR AFFIRMED) BEFORE ME
+
)
+
+
+
+
at , British Columbia
+
)
+
+
+
+
on
+
)
+
+
+
+
+
)
+
+
+
+
+
)
+
+
+
+
+
)
+
+
+
+
+
)
+
+
+
+
A commissioner for taking
+
)
+
{{ responses.name_you|upper }}
+
+
+
affidavits for British Columbia
+
)
+
+
+
+
+
+
+
+ Printed on {% now "F jS, Y" %} from https://justice.gov.bc.ca/divorce
+
diff --git a/edivorce/apps/core/templatetags/format_utils.py b/edivorce/apps/core/templatetags/format_utils.py
index 6dc9f4fb..b99b2b3b 100644
--- a/edivorce/apps/core/templatetags/format_utils.py
+++ b/edivorce/apps/core/templatetags/format_utils.py
@@ -1,14 +1,19 @@
-from django import template
from datetime import datetime
+import locale
import re
+
+from django import template
from django.utils.safestring import mark_safe
+from django.utils.timesince import timesince
+
+locale.setlocale(locale.LC_ALL, 'en_CA.utf-8')
register = template.Library()
@register.filter
def linebreaksli(value):
- "Converts strings with newlines into s"
+ """ Converts strings with newlines into s """
value = re.sub(r'\r\n|\r|\n', '\n', value.strip()) # normalize newlines
lines = re.split('\n', value)
lines = ['
%s
' % line for line in lines if line and not line.isspace()]
@@ -17,22 +22,20 @@ def linebreaksli(value):
@register.filter
def date_formatter(value):
- """
- Changes date format from dd/mm/yyyy to dd/mmm/yyyy
- """
+ """ Changes date format from dd/mm/yyyy to dd/mmm/yyyy """
if value is None or value == '':
return ''
try:
- d = datetime.strptime(value, '%d/%m/%Y')
+ date = datetime.strptime(value, '%d/%m/%Y')
except ValueError:
- d = None
+ date = None
- if d is None:
- d = datetime.strptime(value, '%b %d, %Y')
+ if date is None:
+ date = datetime.strptime(value, '%b %d, %Y')
- return d.strftime('%d %b %Y')
+ return date.strftime('%d %b %Y')
@register.simple_tag()
@@ -83,6 +86,37 @@ def checkbox(context, *args, **kwargs):
@register.filter
def claimantize(value, claimant='1'):
""" Replace 'you' with 'claimant 1' and 'spouse' with 'claimant 2' """
- value = value.replace('you', 'claimant %s' % claimant)
- value = value.replace('spouse', 'claimant %s' % '2' if claimant == '1' else '1')
+ value = value.replace('you', 'claimant\xa0%s' % claimant)
+ value = value.replace('spouse', 'claimant\xa0%s' % '2' if claimant == '1' else '1')
return value
+
+@register.filter
+def age(date):
+ """
+ Return the difference between now and date in the largest unit.
+
+ This uses Django's timesince filter but takes only the first term,
+ printing '46 years' instead of print '46 years, 7 months'.
+ """
+ try:
+ birth = datetime.strptime(date, '%b %d, %Y')
+ except ValueError:
+ try:
+ birth = datetime.strptime(date, '%b %d, %Y')
+ except ValueError:
+ birth = None
+ if birth is not None:
+ return timesince(birth).split(',')[0]
+ return ''
+
+
+@register.filter
+def money(amount):
+ """ Return a properly formatted currency string including symbol """
+
+ try:
+ return locale.currency(float(amount), grouping=True)
+ except ValueError:
+ pass
+
+ return ''
diff --git a/edivorce/apps/core/utils/derived.py b/edivorce/apps/core/utils/derived.py
index caafec33..fd5d06c0 100644
--- a/edivorce/apps/core/utils/derived.py
+++ b/edivorce/apps/core/utils/derived.py
@@ -1,3 +1,4 @@
+# pylint: disable=W0613
"""Values derived from a user's responses.
This module provides functions to take a set of responses from a user and create
@@ -12,13 +13,26 @@ under the _derived_ key.
import json
-DERIVED = [
+# This array is order sensitive: later functions may depend on values from
+# earlier ones
+DERIVED_DATA = [
+ 'orders_wanted',
+ 'children',
+ 'wants_divorce_order',
+ 'wants_spousal_support',
+ 'wants_property_division',
+ 'wants_child_support',
+ 'wants_other_orders',
'show_fact_sheet_a',
'show_fact_sheet_b',
'show_fact_sheet_c',
'show_fact_sheet_d',
'show_fact_sheet_e',
'show_fact_sheet_f',
+ 'has_fact_sheets',
+ 'schedule_1_amount',
+ 'schedule_1_payor',
+ 'fact_sheet_a_total',
]
@@ -26,10 +40,58 @@ def get_derived_data(responses):
""" Return a dict of data derived from the user's responses """
functions = globals()
- return {func: functions[func](responses) for func in DERIVED}
+ derived = {}
+ for func in DERIVED_DATA:
+ derived[func] = functions[func](responses, derived)
+ return derived
-def show_fact_sheet_a(responses):
+def orders_wanted(responses, derived):
+ """ Return a list of orders the user has indicated """
+
+ return json.loads(responses.get('want_which_orders', '[]'))
+
+
+def children(responses, derived):
+ """ Return a list of child dicts, parsed from ``claimants_children`` """
+
+ return json.loads(responses.get('claimant_children', '[]'))
+
+
+def wants_divorce_order(responses, derived):
+ """ Return whether or not the user wants an order for divorce """
+
+ return 'A legal end to the marriage' in derived['orders_wanted']
+
+
+def wants_spousal_support(responses, derived):
+ """ Return whether or not the user wants an order for spousal support """
+
+ return 'Spousal support' in derived['orders_wanted']
+
+
+def wants_property_division(responses, derived):
+ """
+ Return whether or not the user wants an order for division of property and
+ debts
+ """
+
+ return 'Division of property and debts' in responses.get('want_which_orders', '')
+
+
+def wants_child_support(responses, derived):
+ """ Return whether or not the user wants an order for child_support """
+
+ return 'Child support' in derived['orders_wanted']
+
+
+def wants_other_orders(responses, derived):
+ """ Return whether or not the user wants other orders """
+
+ return 'Other orders' in derived['orders_wanted']
+
+
+def show_fact_sheet_a(responses, derived):
"""
If the claimant is claiming special extraordinary expenses, Fact Sheet A is
indicated.
@@ -39,19 +101,17 @@ def show_fact_sheet_a(responses):
return len(expenses) > 0 and "None" not in expenses
-def show_fact_sheet_b(responses):
+def show_fact_sheet_b(responses, derived):
"""
If any child lives with both parents, custody is shared, so Fact Sheet B
is indicated.
"""
- children = json.loads(responses.get('claimant_children', '[]'))
- print(children)
return any([child['child_live_with'] == 'Lives with both'
- for child in children])
+ for child in derived['children']])
-def show_fact_sheet_c(responses):
+def show_fact_sheet_c(responses, derived):
"""
If any child lives with one parent and there's another child who lives with
the other parent or is shared, Fact Sheet C is indicated.
@@ -60,8 +120,7 @@ def show_fact_sheet_c(responses):
with_you = 0
with_spouse = 0
with_both = 0
- children = json.loads(responses.get('claimant_children', '[]'))
- for child in children:
+ for child in derived['children']:
if child['child_live_with'] == 'Lives with you':
with_you += 1
elif child['child_live_with'] == 'Lives with spouse':
@@ -72,7 +131,7 @@ def show_fact_sheet_c(responses):
with_spouse > 0 and (with_you + with_both > 0))
-def show_fact_sheet_d(responses):
+def show_fact_sheet_d(responses, derived):
"""
If a claimaint is claiming financial support for a child of the marriage
over 19, Fact Sheet D is indicated.
@@ -82,7 +141,7 @@ def show_fact_sheet_d(responses):
return len(support) > 0 and 'NO' not in support and responses.get('children_of_marriage', '') == 'YES'
-def show_fact_sheet_e(responses):
+def show_fact_sheet_e(responses, derived):
"""
If the claimant is claiming undue hardship, Fact Sheet E is indicated.
"""
@@ -90,7 +149,7 @@ def show_fact_sheet_e(responses):
return responses.get('claiming_undue_hardship', '') == 'YES'
-def show_fact_sheet_f(responses):
+def show_fact_sheet_f(responses, derived):
"""
If one of the claimants earns over $150,000, Fact Sheet F is indicated.
"""
@@ -106,3 +165,32 @@ def show_fact_sheet_f(responses):
spouses = 0
return annual > 150000 or spouses > 150000
+
+
+def has_fact_sheets(responses, derived):
+ """ Return whether or not the user is submitting fact sheets """
+
+ return any([derived['show_fact_sheet_a'], derived['show_fact_sheet_b'],
+ derived['show_fact_sheet_c'], derived['show_fact_sheet_d'],
+ derived['show_fact_sheet_e'], derived['show_fact_sheet_f'], ])
+
+
+def schedule_1_amount(responses, derived):
+ """ Return the amount as defined in schedule 1 for child support """
+
+ return 155689.333
+
+
+def schedule_1_payor(responses, derived):
+ """ Return the amount as defined in schedule 1 for child support """
+
+ return 'Claimant 1'
+
+
+def fact_sheet_a_total(responses, derived):
+ """ Return the total amount of special expenses from Fact Sheet A """
+
+ return 0
+
+
+
diff --git a/edivorce/apps/core/views/pdf.py b/edivorce/apps/core/views/pdf.py
index 097b895a..c4e233d7 100644
--- a/edivorce/apps/core/views/pdf.py
+++ b/edivorce/apps/core/views/pdf.py
@@ -1,43 +1,58 @@
+""" Views for generated forms """
+
import json
-from django.template.loader import render_to_string
+from django.conf import settings
from django.http import HttpResponse
-import requests
+from django.template.loader import render_to_string
-from django.conf import settings
+import requests
-from edivorce.apps.core.decorators import bceid_required
-from edivorce.apps.core.models import BceidUser
+from ..decorators import bceid_required
+from ..utils.derived import get_derived_data
from ..utils.user_response import get_responses_from_db
+letters = 'abcdefghijklmnopqrstuvwxyz'
+exhibits = list(letters.upper()[::-1])
@bceid_required
def form(request, form_number):
- """
- View for rendering PDF's and previews
- """
+ """ View for rendering PDF's and previews """
+
responses = get_responses_from_db(request.user)
- if form_number == "1":
+ if form_number == '1' or form_number.startswith('37'):
# Add an array of children that includes blanks for possible children
under = int(responses.get('number_children_under_19') or 0)
over = int(responses.get('number_children_under_19') or 0)
actual = json.loads(responses.get('claimant_children', '[]'))
total = len(actual)
- responses["children"] = [actual[i] if i < total else {}
+ responses['children'] = [actual[i] if i < total else {}
for i in range(0, max(under + over, total))]
- elif form_number == "38_claimant1":
- form_number = "38"
+
+ if form_number == "37_claimant1":
+ form_number = "37"
responses = __add_claimant_info(responses, '_you')
responses["which_claimant"] = "Claimant 1"
- elif form_number == "38_claimant2":
- form_number = "38"
+ elif form_number == "37_claimant2":
+ form_number = "37"
responses = __add_claimant_info(responses, '_spouse')
responses["which_claimant"] = "Claimant 2"
+ if form_number == "38_claimant1":
+ form_number = "38"
+ responses = __add_claimant_info(responses, '_you')
+ responses['which_claimant'] = 'Claimant 1'
+ elif form_number == '38_claimant2':
+ form_number = '38'
+ responses = __add_claimant_info(responses, '_spouse')
+ responses['which_claimant'] = 'Claimant 2'
+
return __render_form(request, 'form%s' % form_number, {
- "css_root": settings.WEASYPRINT_CSS_LOOPBACK,
- "responses": responses
+ 'css_root': settings.WEASYPRINT_CSS_LOOPBACK,
+ 'responses': responses,
+ 'derived': get_derived_data(responses),
+ 'exhibits': exhibits[:],
})
@@ -46,25 +61,25 @@ def __render_form(request, form_name, context):
output_as_html = request.GET.get('html', None) is not None
if output_as_html:
- context["css_root"] = settings.FORCE_SCRIPT_NAME[:-1]
+ context['css_root'] = settings.FORCE_SCRIPT_NAME[:-1]
# render to form as HTML
- rendered_html = render_to_string('pdf/' + form_name + '.html', context=context, request=request)
+ rendered_html = render_to_string('pdf/' + form_name + '.html',
+ context=context, request=request)
# if '?html' is in the querystring, then return the plain html
if output_as_html:
return HttpResponse(rendered_html)
- else:
- # post the html to the weasyprint microservice
- url = settings.WEASYPRINT_URL + '/pdf?filename=' + form_name + '.pdf'
- pdf = requests.post(url, data=rendered_html)
+ # post the html to the weasyprint microservice
+ url = settings.WEASYPRINT_URL + '/pdf?filename=' + form_name + '.pdf'
+ pdf = requests.post(url, data=rendered_html.encode('utf-8'))
- # return the response as a pdf
- response = HttpResponse(pdf, content_type='application/pdf')
- response['Content-Disposition'] = 'inline;filename=' + form_name + '.pdf'
+ # return the response as a pdf
+ response = HttpResponse(pdf, content_type='application/pdf')
+ response['Content-Disposition'] = 'inline;filename=' + form_name + '.pdf'
- return response
+ return response
def __add_claimant_info(responses, claimant):
diff --git a/edivorce/settings/base.py b/edivorce/settings/base.py
index 38a2f36a..39d6a428 100644
--- a/edivorce/settings/base.py
+++ b/edivorce/settings/base.py
@@ -40,6 +40,7 @@ INSTALLED_APPS = (
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
+ 'django.contrib.humanize',
'rest_framework',
'debug_toolbar',
'edivorce.apps.core',
@@ -97,14 +98,13 @@ REST_FRAMEWORK = {
LANGUAGE_CODE = 'en-us'
+USE_TZ = True
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
-
-USE_TZ = True
-
+USE_THOUSANDS_SEPARATOR = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/