diff --git a/services/web/app/src/Features/Subscription/RecurlyWrapper.js b/services/web/app/src/Features/Subscription/RecurlyWrapper.js index 991fdae222..2762183d92 100644 --- a/services/web/app/src/Features/Subscription/RecurlyWrapper.js +++ b/services/web/app/src/Features/Subscription/RecurlyWrapper.js @@ -517,14 +517,13 @@ module.exports = RecurlyWrapper = { ) }, - getAccounts(callback) { + getAccounts(queryParams, callback) { + queryParams.per_page = queryParams.per_page || 200 let allAccounts = [] var getPageOfAccounts = (cursor = null) => { const opts = { url: 'accounts', - qs: { - per_page: 200 - } + qs: queryParams } if (cursor != null) { opts.qs.cursor = cursor @@ -546,11 +545,12 @@ module.exports = RecurlyWrapper = { ) cursor = __guard__( response.headers.link != null - ? response.headers.link.match(/cursor=([0-9]+)&/) + ? response.headers.link.match(/cursor=([0-9]+%3A[0-9]+)&/) : undefined, x1 => x1[1] ) if (cursor != null) { + cursor = decodeURIComponent(cursor) return getPageOfAccounts(cursor) } else { return callback(err, allAccounts) diff --git a/services/web/scripts/recurly/get_paypal_accounts_csv.js b/services/web/scripts/recurly/get_paypal_accounts_csv.js new file mode 100644 index 0000000000..4a3528fa0a --- /dev/null +++ b/services/web/scripts/recurly/get_paypal_accounts_csv.js @@ -0,0 +1,100 @@ +const RecurlyWrapper = require('../../app/src/Features/Subscription/RecurlyWrapper') +const async = require('async') +const CSVParser = require('json2csv').Parser + +const NOW = new Date() + +const getAccountSubscription = (account, callback) => + RecurlyWrapper.getSubscriptions(account.account_code, (error, response) => { + if (error) { + console.warn( + `Errors getting subscription for account ${account.account_code}`, + error + ) + return callback() + } + callback(null, response.subscriptions[0]) + }) + +const isAccountUsingPaypal = (account, callback) => + RecurlyWrapper.getBillingInfo(account.account_code, (error, response) => { + if (error) { + console.warn( + `Errors getting billing info for account ${account.account_code}`, + error + ) + return callback(null, false) + } + if (response.billing_info.paypal_billing_agreement_id) { + return callback(null, true) + } + callback(null, false) + }) + +const printAccountCSV = (account, callback) => { + isAccountUsingPaypal(account, (error, isPaypal) => { + if (error || !isPaypal) { + return callback(error) + } + getAccountSubscription(account, (error, subscription) => { + if (error || !subscription) { + return callback(error) + } + const endAt = new Date(subscription.current_period_ends_at) + if (subscription.expires_at) { + return callback() + } + const csvData = { + email: account.email, + first_name: account.first_name, + last_name: account.last_name, + hosted_login_token: account.hosted_login_token, + billing_info_url: `https://sharelatex.recurly.com/account/billing_info/edit?ht=${ + account.hosted_login_token + }`, + account_management_url: `https://sharelatex.recurly.com/account/${ + account.hosted_login_token + }`, + current_period_ends_at: `${endAt.getFullYear()}-${endAt.getMonth() + + 1}-${endAt.getDate()}`, + current_period_ends_at_segment: parseInt( + ((endAt - NOW) / 1000 / 3600 / 24 / 365) * 7 + ) + } + callback(null, csvData) + }) + }) +} + +const printAccountsCSV = callback => { + RecurlyWrapper.getAccounts({ state: 'subscriber' }, (error, accounts) => { + if (error) { + return callback(error) + } + async.mapLimit(accounts, 10, printAccountCSV, (error, csvData) => { + csvData = csvData.filter(d => !!d) + callback(error, csvData) + }) + }) +} + +const csvFields = [ + 'email', + 'first_name', + 'last_name', + 'hosted_login_token', + 'billing_info_url', + 'account_management_url', + 'current_period_ends_at', + 'current_period_ends_at_segment' +] +const csvParser = new CSVParser({ csvFields }) + +// print each account +printAccountsCSV((error, csvData) => { + if (error) { + throw error + } + console.log(csvParser.parse(csvData)) + process.exit() +})