Skip to content

Commit

Permalink
Upgraded billing info pages
Browse files Browse the repository at this point in the history
  • Loading branch information
orangejenny committed Jan 14, 2019
1 parent 8d010c2 commit 93c8c7f
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 34 deletions.
34 changes: 16 additions & 18 deletions corehq/apps/accounting/forms.py
Expand Up @@ -150,10 +150,10 @@ def __init__(self, account, *args, **kwargs):
'name': account.name,
'salesforce_account_id': account.salesforce_account_id,
'currency': account.currency.code,
'email_list': ','.join(contact_info.email_list),
'email_list': contact_info.email_list,
'is_active': account.is_active,
'is_customer_billing_account': account.is_customer_billing_account,
'enterprise_admin_emails': ','.join(account.enterprise_admin_emails),
'enterprise_admin_emails': account.enterprise_admin_emails,
'enterprise_restricted_signup_domains': ','.join(account.enterprise_restricted_signup_domains),
'invoicing_plan': account.invoicing_plan,
'dimagi_contact': account.dimagi_contact,
Expand Down Expand Up @@ -200,9 +200,11 @@ def __init__(self, account, *args, **kwargs):
'invoicing_plan',
crispy.Field(
'enterprise_admin_emails',
css_class='input-xxlarge accounting-email-select2'
css_class='input-xxlarge accounting-email-select2',
data_initial=json.dumps(self.initial.get('enterprise_admin_emails')),
),
data_bind='visible: is_customer_billing_account'
data_bind='visible: is_customer_billing_account',
data_initial=json.dumps(self.initial.get('enterprise_admin_emails')),
)
)
additional_fields.append(
Expand All @@ -227,13 +229,14 @@ def __init__(self, account, *args, **kwargs):
crispy.Fieldset(
'Basic Information',
'name',
crispy.Field('email_list', css_class='input-xxlarge accounting-email-select2'),
crispy.Field('email_list', css_class='input-xxlarge accounting-email-select2',
data_initial=json.dumps(self.initial.get('email_list'))),
crispy.Div(
crispy.Div(
css_class='col-sm-3 col-md-2'
),
crispy.Div(
crispy.HTML(self.initial['email_list']),
crispy.HTML(", ".join(self.initial.get('email_list'))),
css_class='col-sm-9 col-md-8 col-lg-6'
),
css_id='emails-text',
Expand Down Expand Up @@ -285,14 +288,10 @@ def clean_name(self):
return name

def clean_email_list(self):
return self.cleaned_data['email_list'].split(',')
return self.data.getlist('email_list')

def clean_enterprise_admin_emails(self):
# Do not return a list with an empty string
if self.cleaned_data['enterprise_admin_emails']:
return [e.strip() for e in self.cleaned_data['enterprise_admin_emails'].split(r',')]
else:
return []
return self.data.getlist('enterprise_admin_emails')

def clean_enterprise_restricted_signup_domains(self):
if self.cleaned_data['enterprise_restricted_signup_domains']:
Expand Down Expand Up @@ -416,6 +415,7 @@ def __init__(self, account, *args, **kwargs):
self.helper.form_class = "form-horizontal"
self.helper.label_class = 'col-sm-3 col-md-2'
self.helper.field_class = 'col-sm-9 col-md-8 col-lg-6'
country_code = args[0].get('country') if len(args) > 0 else account.billingcontactinfo.country
self.helper.layout = crispy.Layout(
crispy.Fieldset(
'Contact Information',
Expand All @@ -431,11 +431,8 @@ def __init__(self, account, *args, **kwargs):
crispy.Field(
'country',
css_class="input-xlarge accounting-country-select2",
data_countryname=COUNTRIES.get(
args[0].get('country') if len(args) > 0
else account.billingcontactinfo.country,
''
)
data_country_code=country_code or '',
data_country_name=COUNTRIES.get(country_code, ''),
),
),
hqcrispy.FormActions(
Expand Down Expand Up @@ -2055,7 +2052,8 @@ def __init__(self, *args, **kwargs):
self.helper.layout = crispy.Layout(
crispy.Fieldset(
'Trigger Bookkeeper Email Details',
crispy.Field('emails', css_class='input-xxlarge accounting-email-select2'),
crispy.Field('emails', css_class='input-xxlarge accounting-email-select2',
data_initial=json.dumps(self.initial.get('emails'))),
crispy.Field('month', css_class="input-large"),
crispy.Field('year', css_class="input-large"),
),
Expand Down
172 changes: 172 additions & 0 deletions corehq/apps/accounting/static/accounting/js/widgets_v4.js
@@ -0,0 +1,172 @@
hqDefine('accounting/js/widgets_v4', [
'jquery',
'knockout',
'underscore',
'select2/dist/js/select2.full.min',
], function (
$,
ko,
_
) {
var asyncSelect2Handler = function (field, multiple) {
'use strict';
var self = {};

self.fieldName = field;
self.multiple = !! multiple;

self.init = function (initial) {
var $field = $('form [name="' + self.fieldName + '"]');
if ($field.attr('type') !== 'hidden') {
if (initial) {
if (!_.isArray(initial)) {
initial = [{id: initial, text: initial}];
}

// Add a DOM option for each value, which select2 will pick up on change
_.each(initial, function (result) {
$field.append(new Option(result.text, result.id));
});

// Set the actual value; using an array works for both single and multiple selects
$field.val(_.pluck(initial, 'id'));
}
$field.select2({
minimumInputLength: 0,
placeholder: '', // required for allowClear to work
allowClear: true,
ajax: {
quietMillis: 150,
url: '',
dataType: 'json',
type: 'post',
data: function (params) {
return {
handler: 'select2_billing',
action: self.fieldName,
searchString: params.term,
existing: $('form [name="' + self.fieldName + '"]').val(),
additionalData: self.getAdditionalData(),
};
},
},
multiple: self.multiple,
});
}
};

self.getAdditionalData = function () {
return null;
};

return self;
};

var emailSelect2Handler = function (field) {
'use strict';
var self = {};

self.fieldName = field;
self.validEmailText = gettext("Please enter a valid email.");

self.init = function (initial) {
var $field = $('form [name="' + self.fieldName + '"]');
if (initial) {
if (!_.isArray(initial)) {
initial = [{id: initial, text: initial}];
}

// Add a DOM option for each value, which select2 will pick up on change
_.each(initial, function (result) {
$field.append(new Option(result.text, result.id));
});

// Set the actual value; using an array works for both single and multiple selects
$field.val(_.pluck(initial, 'id'));
}
$field.select2({
tags: true,
createTag: function (params) {
var term = params.term,
data = this.$element.select2("data");

// Prevent duplicates
var matchedData = $(data).filter(function () {
return this.text.localeCompare(term) === 0;
});

if (matchedData.length === 0 && self.utils.validateEmail(term)) {
return { id: term, text: term };
}
},
multiple: true,
data: [],
language: {
noResults: function () {
return self.validEmailText;
},
},
});
};

self.utils = {
validateEmail: function (email) {
// from http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; // eslint-disable-line no-useless-escape
return re.test(email);
},
};

return self;
};

var adjustBalanceFormModel = function () {
var self = {};
self.adjustmentType = ko.observable("current");
self.showCustomAmount = ko.computed(function () {
return self.adjustmentType() === 'credit';
}, self);

return self;
};

$(function () {
_.each($(".accounting-email-select2"), function (input) {
var handler = emailSelect2Handler($(input).attr("name"));
handler.init(_.map($(input).data("initial"), function (e) {
return {
id: e,
text: e,
};
}));
});
$(".accounting-email-select2").removeAttr('required');

_.each($(".accounting-async-select2"), function (input) {
var handler = asyncSelect2Handler($(input).attr("name"));
handler.init();
});

_.each($(".accounting-country-select2"), function (el) {
var country = asyncSelect2Handler('country'),
data = $(el).data(),
initial = [];
if (data.countryCode) {
initial = [{
id: data.countryCode,
text: data.countryName,
}];
}
country.init(initial);
});

_.each($('.ko-adjust-balance-form'), function (form) {
$(form).koApplyBindings(adjustBalanceFormModel());
});
});

return {
asyncSelect2Handler: asyncSelect2Handler,
emailSelect2Handler: emailSelect2Handler,
};
});
27 changes: 18 additions & 9 deletions corehq/apps/domain/forms.py
Expand Up @@ -2,6 +2,7 @@
from __future__ import unicode_literals
import datetime
import io
import json
import logging
import re
import sys
Expand Down Expand Up @@ -1445,12 +1446,14 @@ class EditBillingAccountInfoForm(forms.ModelForm):
email_list = forms.CharField(
label=BillingContactInfo._meta.get_field('email_list').verbose_name,
help_text=BillingContactInfo._meta.get_field('email_list').help_text,
widget=forms.SelectMultiple(choices=[]),
)

class Meta(object):
model = BillingContactInfo
fields = ['first_name', 'last_name', 'phone_number', 'company_name', 'first_line',
'second_line', 'city', 'state_province_region', 'postal_code', 'country']
widgets = {'country': forms.Select(choices=[])}

def __init__(self, account, domain, creating_user, data=None, *args, **kwargs):
self.account = account
Expand All @@ -1467,7 +1470,7 @@ def __init__(self, account, domain, creating_user, data=None, *args, **kwargs):
try:
kwargs['instance'] = self.account.billingcontactinfo
kwargs['initial'] = {
'email_list': ','.join(self.account.billingcontactinfo.email_list),
'email_list': self.account.billingcontactinfo.email_list,
}

except BillingContactInfo.DoesNotExist:
Expand All @@ -1480,7 +1483,8 @@ def __init__(self, account, domain, creating_user, data=None, *args, **kwargs):
'company_name',
'first_name',
'last_name',
crispy.Field('email_list', css_class='input-xxlarge accounting-email-select2'),
crispy.Field('email_list', css_class='input-xxlarge accounting-email-select2',
data_initial=json.dumps(self.initial.get('email_list'))),
'phone_number'
]

Expand All @@ -1490,7 +1494,7 @@ def __init__(self, account, domain, creating_user, data=None, *args, **kwargs):
css_class='col-sm-3 col-md-2'
),
crispy.Div(
crispy.HTML(self.initial['email_list']),
crispy.HTML(", ".join(self.initial.get('email_list'))),
css_class='col-sm-9 col-md-8 col-lg-6'
),
css_id='emails-text',
Expand Down Expand Up @@ -1528,7 +1532,8 @@ def __init__(self, account, domain, creating_user, data=None, *args, **kwargs):
'state_province_region',
'postal_code',
crispy.Field('country', css_class="input-large accounting-country-select2",
data_countryname=COUNTRIES.get(self.current_country, '')),
data_country_code=self.current_country or '',
data_country_name=COUNTRIES.get(self.current_country, '')),
),
hqcrispy.FormActions(
StrictButton(
Expand All @@ -1553,7 +1558,7 @@ def clean_phone_number(self):
return "+%s%s" % (parsed_number.country_code, parsed_number.national_number)

def clean_email_list(self):
return self.cleaned_data['email_list'].split(',')
return self.data.getlist('email_list')

# Does not use the commit kwarg.
# TODO - Should support it or otherwise change the function name
Expand Down Expand Up @@ -1592,7 +1597,8 @@ def __init__(self, account, domain, creating_user, plan_version, current_subscri
'company_name',
'first_name',
'last_name',
crispy.Field('email_list', css_class='input-xxlarge accounting-email-select2'),
crispy.Field('email_list', css_class='input-xxlarge accounting-email-select2',
data_initial=json.dumps(self.initial.get('email_list'))),
'phone_number',
),
crispy.Fieldset(
Expand All @@ -1603,7 +1609,8 @@ def __init__(self, account, domain, creating_user, plan_version, current_subscri
'state_province_region',
'postal_code',
crispy.Field('country', css_class="input-large accounting-country-select2",
data_countryname=COUNTRIES.get(self.current_country, ''))
data_country_code=self.current_country or '',
data_country_name=COUNTRIES.get(self.current_country, ''))
),
hqcrispy.FormActions(
hqcrispy.LinkButton(_("Cancel"),
Expand Down Expand Up @@ -1711,7 +1718,8 @@ def __init__(self, account, domain, creating_user, current_subscription,
'company_name',
'first_name',
'last_name',
crispy.Field('email_list', css_class='input-xxlarge accounting-email-select2'),
crispy.Field('email_list', css_class='input-xxlarge accounting-email-select2',
data_initial=json.dumps(self.initial.get('email_list'))),
'phone_number',
),
crispy.Fieldset(
Expand All @@ -1722,7 +1730,8 @@ def __init__(self, account, domain, creating_user, current_subscription,
'state_province_region',
'postal_code',
crispy.Field('country', css_class="input-large accounting-country-select2",
data_countryname=COUNTRIES.get(self.current_country, ''))
data_country_code=self.current_country or '',
data_country_name=COUNTRIES.get(self.current_country, ''))
),
hqcrispy.FormActions(
hqcrispy.LinkButton(
Expand Down
Expand Up @@ -3,7 +3,7 @@ hqDefine('domain/js/update_billing_contact_info', [
'hqwebapp/js/initial_page_data',
'accounting/js/stripe_card_manager',
'accounting/js/lib/stripe',
'accounting/js/widgets_v3',
'accounting/js/widgets_v4',
'hqwebapp/js/knockout_bindings.ko', // openModal
], function (
$,
Expand Down
Expand Up @@ -4,7 +4,7 @@
{% load i18n %}

{% block js %}{{ block.super }}
<script src="{% static 'accounting/js/widgets_v3.js' %}"></script>
<script src="{% static 'accounting/js/widgets_v4.js' %}"></script>
<script src="https://js.stripe.com/v2/"></script>
<script src="{% static 'accounting/js/stripe_card_manager.js' %}"></script>
<script src="{% static 'domain/js/confirm_billing_info.js' %}"></script>
Expand Down

0 comments on commit 93c8c7f

Please sign in to comment.