diff --git a/services/web/app/src/Features/Subscription/RecurlyWrapper.js b/services/web/app/src/Features/Subscription/RecurlyWrapper.js
index b29d7f65ab..6ec1451d4e 100644
--- a/services/web/app/src/Features/Subscription/RecurlyWrapper.js
+++ b/services/web/app/src/Features/Subscription/RecurlyWrapper.js
@@ -86,7 +86,7 @@ module.exports = RecurlyWrapper = {
let address
try {
- address = getAddressFromSubscriptionDetails(subscriptionDetails)
+ address = getAddressFromSubscriptionDetails(subscriptionDetails, false)
} catch (error) {
return next(error)
}
@@ -173,25 +173,36 @@ module.exports = RecurlyWrapper = {
)
},
- setAddress(cache, next) {
+ setAddressAndCompanyBillingInfo(cache, next) {
const { user } = cache
const { subscriptionDetails } = cache
- logger.log({ user_id: user._id }, 'setting billing address in recurly')
+ logger.log(
+ { user_id: user._id },
+ 'setting billing address and company info in recurly'
+ )
const accountCode = __guard__(
cache != null ? cache.account : undefined,
x1 => x1.account_code
)
if (!accountCode) {
- return next(new Error('no account code at setAddress stage'))
+ return next(
+ new Error('no account code at setAddressAndCompanyBillingInfo stage')
+ )
}
- let address
+ let addressAndCompanyBillingInfo
try {
- address = getAddressFromSubscriptionDetails(subscriptionDetails)
+ addressAndCompanyBillingInfo = getAddressFromSubscriptionDetails(
+ subscriptionDetails,
+ true
+ )
} catch (error) {
return next(error)
}
- const requestBody = RecurlyWrapper._buildXml('billing_info', address)
+ const requestBody = RecurlyWrapper._buildXml(
+ 'billing_info',
+ addressAndCompanyBillingInfo
+ )
return RecurlyWrapper.apiRequest(
{
@@ -296,7 +307,7 @@ module.exports = RecurlyWrapper = {
Async.apply(RecurlyWrapper._paypal.checkAccountExists, cache),
RecurlyWrapper._paypal.createAccount,
RecurlyWrapper._paypal.createBillingInfo,
- RecurlyWrapper._paypal.setAddress,
+ RecurlyWrapper._paypal.setAddressAndCompanyBillingInfo,
RecurlyWrapper._paypal.createSubscription
],
function(err, result) {
@@ -1048,8 +1059,12 @@ function getCustomFieldsFromSubscriptionDetails(subscriptionDetails) {
return { custom_field: customFields }
}
-function getAddressFromSubscriptionDetails(subscriptionDetails) {
+function getAddressFromSubscriptionDetails(
+ subscriptionDetails,
+ includeCompanyInfo
+) {
const { address } = subscriptionDetails
+
if (!address || !address.country) {
throw new Errors.InvalidError({
message: 'Invalid country',
@@ -1070,6 +1085,21 @@ function getAddressFromSubscriptionDetails(subscriptionDetails) {
country: address.country
}
+ if (
+ includeCompanyInfo &&
+ subscriptionDetails.billing_info &&
+ subscriptionDetails.billing_info.company &&
+ subscriptionDetails.billing_info.company !== ''
+ ) {
+ addressObject.company = subscriptionDetails.billing_info.company
+ if (
+ subscriptionDetails.billing_info.vat_number &&
+ subscriptionDetails.billing_info.vat_number !== ''
+ ) {
+ addressObject.vat_number = subscriptionDetails.billing_info.vat_number
+ }
+ }
+
return addressObject
}
diff --git a/services/web/app/views/subscriptions/dashboard/_personal_subscription_recurly.pug b/services/web/app/views/subscriptions/dashboard/_personal_subscription_recurly.pug
index 579281ab89..78a046d8e7 100644
--- a/services/web/app/views/subscriptions/dashboard/_personal_subscription_recurly.pug
+++ b/services/web/app/views/subscriptions/dashboard/_personal_subscription_recurly.pug
@@ -8,6 +8,7 @@ div(ng-controller="RecurlySubscriptionController")
case personalSubscription.recurly.state
when "active"
p !{translate("currently_subscribed_to_plan", {planName:"" + personalSubscription.plan.name + ""})}
+ |
a(href, ng-click="switchToChangePlanView()", ng-if="showChangePlanButton") !{translate("change_plan")}.
-if (personalSubscription.recurly.trialEndsAtFormatted && personalSubscription.recurly.trial_ends_at > Date.now())
p You're on a free trial which ends on #{personalSubscription.recurly.trialEndsAtFormatted}
diff --git a/services/web/app/views/subscriptions/new.pug b/services/web/app/views/subscriptions/new.pug
index 42f8fd54b5..974237bc4b 100644
--- a/services/web/app/views/subscriptions/new.pug
+++ b/services/web/app/views/subscriptions/new.pug
@@ -62,7 +62,6 @@ block content
novalidate
)
-
div.payment-method-toggle
a.payment-method-toggle-switch(
href
@@ -165,22 +164,42 @@ block content
ng-model="data.country"
name="country"
ng-change="updateCountry()"
- required,
ng-selected="{{country.code == data.country}}"
+ ng-model-options="{ debounce: 200 }"
+ required
)
option(value='', disabled) #{translate("country")}
option(value='-', disabled) --------------
option(ng-repeat="country in countries" ng-bind-html="country.name" value="{{country.code}}")
span.input-feedback-message {{ simpleCCForm.country.$error.required ? 'This field is required' : '' }}
- if (showVatField)
- .form-group
- label(for="vat-no") #{translate('vat_number')}
- input#vat-no.form-control(
- type="text"
- ng-blur="applyVatNumber()"
- ng-model="data.vat_number"
- )
+ .form-group
+ .checkbox
+ label
+ input(
+ type="checkbox"
+ ng-model="ui.addCompanyDetails"
+ )
+ |
+ | #{translate("add_company_details")}
+
+ .form-group(ng-show="ui.addCompanyDetails")
+ label(for="company-name") #{translate("company_name")}
+ input#company-name.form-control(
+ type="text"
+ name="companyName"
+ ng-model="data.company"
+ )
+
+ .form-group(ng-show="ui.addCompanyDetails && price.taxes.length")
+ label(for="vat-number") #{translate("vat_number")}
+ input#vat-number.form-control(
+ type="text"
+ name="vatNumber"
+ ng-model="data.vat_number"
+ ng-blur="applyVatNumber()"
+ )
+
if (showCouponField)
.form-group
label(for="coupon-code") #{translate('coupon_code')}
@@ -192,11 +211,19 @@ block content
p(ng-if="paymentMethod.value === 'paypal'") #{translate("paypal_upgrade")}
- div.price-breakdown(ng-if="price.next.tax !== '0.00'")
+ div.price-breakdown(
+ ng-show="price.taxes.length"
+ )
hr.thin
- span Total:
- strong {{availableCurrencies[currencyCode]['symbol']}}{{price.next.total}}
- span ({{availableCurrencies[currencyCode]['symbol']}}{{price.next.subtotal}} + {{availableCurrencies[currencyCode]['symbol']}}{{price.next.tax}} tax)
+ span
+ | Total:
+ |
+ strong
+ | {{availableCurrencies[currencyCode]['symbol']}}{{price.next.total}}
+ |
+ span
+ | ({{availableCurrencies[currencyCode]['symbol']}}{{price.next.subtotal}} + {{availableCurrencies[currencyCode]['symbol']}}{{price.next.tax}} tax)
+ |
span(ng-if="monthlyBilling") #{translate("every")} #{translate("month")}
span(ng-if="!monthlyBilling") #{translate("every")} #{translate("year")}
hr.thin
diff --git a/services/web/frontend/js/main/new-subscription.js b/services/web/frontend/js/main/new-subscription.js
index 8997d25501..1fa5157161 100644
--- a/services/web/frontend/js/main/new-subscription.js
+++ b/services/web/frontend/js/main/new-subscription.js
@@ -17,6 +17,10 @@ define(['../base', '../directives/creditCards'], App =>
return
}
+ $scope.ui = {
+ addCompanyDetails: false
+ }
+
$scope.recurlyLoadError = false
$scope.currencyCode = MultiCurrencyPricing.currencyCode
$scope.allCurrencies = MultiCurrencyPricing.plans
@@ -58,6 +62,8 @@ define(['../base', '../directives/creditCards'], App =>
address2: '',
state: '',
city: '',
+ company: '',
+ vat_number: '',
country: window.countryCode,
coupon: window.couponCode
}
@@ -99,7 +105,9 @@ define(['../base', '../directives/creditCards'], App =>
pricing
.plan(window.plan_code, { quantity: 1 })
- .address({ country: $scope.data.country })
+ .address({
+ country: $scope.data.country
+ })
.tax({ tax_code: 'digital', vat_number: '' })
.currency($scope.currencyCode)
.coupon($scope.data.coupon)
@@ -219,7 +227,6 @@ define(['../base', '../directives/creditCards'], App =>
coupon_code: pricing.items.coupon ? pricing.items.coupon.code : '',
first_name: $scope.data.first_name,
last_name: $scope.data.last_name,
-
isPaypal: $scope.paymentMethod.value === 'paypal',
address: {
address1: $scope.data.address1,
@@ -233,6 +240,21 @@ define(['../base', '../directives/creditCards'], App =>
}
}
+ if (
+ postData.subscriptionDetails.isPaypal &&
+ $scope.ui.addCompanyDetails
+ ) {
+ postData.subscriptionDetails.billing_info = {}
+ if ($scope.data.company && $scope.data.company !== '') {
+ postData.subscriptionDetails.billing_info.company =
+ $scope.data.company
+ }
+ if ($scope.data.vat_number && $scope.data.vat_number !== '') {
+ postData.subscriptionDetails.billing_info.vat_number =
+ $scope.data.vat_number
+ }
+ }
+
eventTracking.sendMB('subscription-form-submitted', {
currencyCode: postData.subscriptionDetails.currencyCode,
plan_code: postData.subscriptionDetails.plan_code,
@@ -244,7 +266,6 @@ define(['../base', '../directives/creditCards'], App =>
'subscription-form-submitted',
postData.subscriptionDetails.plan_code
)
-
return $http
.post('/user/subscription/create', postData)
.then(function() {
@@ -274,9 +295,14 @@ define(['../base', '../directives/creditCards'], App =>
$scope.processing = true
if ($scope.paymentMethod.value === 'paypal') {
const opts = { description: $scope.planName }
- return recurly.paypal(opts, completeSubscription)
+ recurly.paypal(opts, completeSubscription)
} else {
- return recurly.token($scope.data, completeSubscription)
+ const tokenData = _.cloneDeep($scope.data)
+ if (!$scope.ui.addCompanyDetails) {
+ delete tokenData.company
+ delete tokenData.vat_number
+ }
+ recurly.token(tokenData, completeSubscription)
}
}
diff --git a/services/web/test/unit/src/Subscription/RecurlyWrapperTests.js b/services/web/test/unit/src/Subscription/RecurlyWrapperTests.js
index 25651dd654..bcd939358a 100644
--- a/services/web/test/unit/src/Subscription/RecurlyWrapperTests.js
+++ b/services/web/test/unit/src/Subscription/RecurlyWrapperTests.js
@@ -862,7 +862,10 @@ describe('RecurlyWrapper', function() {
this.RecurlyWrapper._paypal,
'createBillingInfo'
)
- this.setAddress = sinon.stub(this.RecurlyWrapper._paypal, 'setAddress')
+ this.setAddressAndCompanyBillingInfo = sinon.stub(
+ this.RecurlyWrapper._paypal,
+ 'setAddressAndCompanyBillingInfo'
+ )
this.createSubscription = sinon.stub(
this.RecurlyWrapper._paypal,
'createSubscription'
@@ -917,7 +920,7 @@ describe('RecurlyWrapper', function() {
account: { accountCode: 'xx' },
billingInfo: { token_id: 'abc' }
})
- this.setAddress.callsArgWith(1, null, {
+ this.setAddressAndCompanyBillingInfo.callsArgWith(1, null, {
user,
subscriptionDetails,
recurlyTokenIds,
@@ -949,7 +952,7 @@ describe('RecurlyWrapper', function() {
this.checkAccountExists.restore()
this.createAccount.restore()
this.createBillingInfo.restore()
- this.setAddress.restore()
+ this.setAddressAndCompanyBillingInfo.restore()
return this.createSubscription.restore()
})
@@ -973,7 +976,7 @@ describe('RecurlyWrapper', function() {
this.checkAccountExists.callCount.should.equal(1)
this.createAccount.callCount.should.equal(1)
this.createBillingInfo.callCount.should.equal(1)
- this.setAddress.callCount.should.equal(1)
+ this.setAddressAndCompanyBillingInfo.callCount.should.equal(1)
this.createSubscription.callCount.should.equal(1)
return done()
})
@@ -996,7 +999,7 @@ describe('RecurlyWrapper', function() {
this.checkAccountExists.callCount.should.equal(1)
this.createAccount.callCount.should.equal(1)
this.createBillingInfo.callCount.should.equal(0)
- this.setAddress.callCount.should.equal(0)
+ this.setAddressAndCompanyBillingInfo.callCount.should.equal(0)
this.createSubscription.callCount.should.equal(0)
return done()
})
@@ -1414,12 +1417,15 @@ describe('RecurlyWrapper', function() {
})
})
- describe('_paypal.setAddress', function() {
+ describe('_paypal.setAddressAndCompanyBillingInfo', function() {
beforeEach(function() {
this.cache.account = { account_code: 'abc' }
this.cache.billingInfo = {}
return (this.call = callback => {
- return this.RecurlyWrapper._paypal.setAddress(this.cache, callback)
+ return this.RecurlyWrapper._paypal.setAddressAndCompanyBillingInfo(
+ this.cache,
+ callback
+ )
})
})