This commit is contained in:
Angus McLeod
2018-06-28 09:32:58 +10:00
parent fd0b53c67c
commit 1b1eb215e4
18 changed files with 478 additions and 140 deletions
@@ -1,3 +1,6 @@
import { ajax } from 'discourse/lib/ajax';
import { popupAjaxError } from 'discourse/lib/ajax-error';
export default Ember.Component.extend({
classNames: 'donation-list',
hasSubscriptions: Ember.computed.notEmpty('subscriptions'),
@@ -0,0 +1,96 @@
import { ajax } from 'discourse/lib/ajax';
import { popupAjaxError } from 'discourse/lib/ajax-error';
import { formatAnchor, formatAmount } from '../lib/donation-utilities';
import { default as computed, observes, on } from 'ember-addons/ember-computed-decorators';
import showModal from "discourse/lib/show-modal";
export default Ember.Component.extend({
classNameBindings: [':donation-row', 'canceled', 'updating'],
includePrefix: Ember.computed.or('invoice', 'charge'),
canceled: Ember.computed.equal('subscription.status', 'canceled'),
@computed('subscription', 'invoice', 'charge', 'customer')
data(subscription, invoice, charge, customer) {
if (subscription) {
return $.extend({}, subscription.plan, {
anchor: subscription.billing_cycle_anchor
});
} else if (invoice) {
let receiptSent = false;
if (invoice.receipt_number && customer.email) {
receiptSent = true;
}
return $.extend({}, invoice.lines.data[0], {
anchor: invoice.date,
invoiceLink: invoice.invoice_pdf,
receiptSent
});
} else if (charge) {
let receiptSent = false;
if (charge.receipt_number && charge.receipt_email) {
receiptSent = true;
}
return $.extend({}, charge, {
anchor: charge.created,
receiptSent
});
}
},
@computed('data.currency')
currency(currency) {
return currency ? currency.toUpperCase() : null;
},
@computed('data.amount', 'currency')
amount(amount, currency) {
return formatAmount(amount, currency);
},
@computed('data.interval')
interval(interval) {
return interval || 'once';
},
@computed('data.anchor', 'interval')
period(anchor, interval) {
return I18n.t(`discourse_donations.period.${interval}`, {
anchor: formatAnchor(interval, moment.unix(anchor))
})
},
cancelSubscription() {
const subscriptionId = this.get('subscription.id');
this.set('updating', true);
ajax('/donate/charges/cancel-subscription', {
data: {
subscription_id: subscriptionId
},
method: 'put'
}).then(result => {
if (result.success) {
this.set('subscription', result.subscription);
}
}).catch(popupAjaxError).finally(() => {
this.set('updating', false);
});
},
actions: {
cancelSubscription() {
showModal('cancel-subscription', {
model: {
currency: this.get('currency'),
amount: this.get('amount'),
period: this.get('period'),
confirm: () => this.cancelSubscription()
}
});
}
}
})
@@ -175,7 +175,7 @@ export default Ember.Component.extend({
const transactionFeeEnabled = settings.discourse_donations_enable_transaction_fee;
let amount = transactionFeeEnabled ? this.get('totalAmount') : this.get('amount');
if (zeroDecimalCurrencies.indexOf(setting.discourse_donations_currency) === -1) {
if (zeroDecimalCurrencies.indexOf(settings.discourse_donations_currency) === -1) {
amount = amount * 100;
}
@@ -189,22 +189,26 @@ export default Ember.Component.extend({
};
if(!self.get('paymentSuccess')) {
ajax('/donate/charges', { data: params, method: 'post' }).then(d => {
let donation = d.donation;
if (donation) {
if (donation.object === 'subscription') {
let subscriptions = this.get('subscriptions') || [];
subscriptions.push(donation);
this.set('subscriptions', subscriptions);
} else if (donation.object === 'charge') {
let charges = this.get('charges') || [];
charges.push(donation);
this.set('charges', charges);
}
ajax('/donate/charges', {
data: params,
method: 'post'
}).then(result => {
if (result.subscription) {
let subscription = $.extend({}, result.subscription, {
new: true
});
this.get('subscriptions').unshiftObject(subscription);
}
self.concatMessages(d.messages);
if (result.charge) {
let charge = $.extend({}, result.charge, {
new: true
});
this.get('charges').unshiftObject(charge);
}
self.concatMessages(result.messages);
self.endTranscation();
});
}
@@ -0,0 +1,12 @@
export default Ember.Controller.extend({
actions: {
confirm() {
this.get('model.confirm')();
this.send('closeModal');
},
cancel() {
this.send('closeModal');
}
}
})
@@ -1,11 +1,53 @@
import { default as computed } from 'ember-addons/ember-computed-decorators';
import { popupAjaxError } from 'discourse/lib/ajax-error';
import { ajax } from 'discourse/lib/ajax';
import { getOwner } from 'discourse-common/lib/get-owner';
export default Ember.Controller.extend({
loadingDonations: false,
@computed('charges', 'subscriptions')
loadDonationsDisabled: Ember.computed.not('emailVaild'),
@computed('charges.[]', 'subscriptions.[]')
hasDonations(charges, subscriptions) {
return (charges && charges.length > 0) ||
(subscriptions && subscriptions.length > 0);
},
@computed('email')
emailVaild(email) {
return emailValid(email);
},
actions: {
loadDonations() {
let email = this.get('email');
this.set('loadingDonations', true);
ajax('/donate/charges', {
data: { email },
type: 'GET'
}).then((result) => {
this.setProperties({
charges: Ember.A(result.charges),
subscriptions: Ember.A(result.subscriptions),
customer: result.customer
});
}).catch(popupAjaxError).finally(() => {
this.setProperties({
loadingDonations: false,
hasEmailResult: true
});
Ember.run.later(() => {
this.set('hasEmailResult', false);
}, 6000)
})
},
showLogin() {
const controller = getOwner(this).lookup('route:application');
controller.send('showLogin');
}
}
})
@@ -1,56 +0,0 @@
import { registerHelper } from "discourse-common/lib/helpers";
import { formatAnchor, formatAmount } from '../lib/donation-utilities';
registerHelper("donation-subscription", function([subscription]) {
let currency = subscription.plan.currency.toUpperCase();
let html = currency;
html += ` ${formatAmount(subscription.plan.amount, currency)} `;
html += I18n.t(`discourse_donations.period.${subscription.plan.interval}`, {
anchor: formatAnchor(subscription.plan.interval, moment.unix(subscription.billing_cycle_anchor))
});
return new Handlebars.SafeString(html);
});
registerHelper("donation-invoice", function([invoice]) {
let details = invoice.lines.data[0];
let html = I18n.t('discourse_donations.invoice_prefix');
let currency = details.currency.toUpperCase();
html += ` ${currency}`;
html += ` ${formatAmount(details.amount, currency)} `;
html += I18n.t(`discourse_donations.period.once`, {
anchor: formatAnchor('once', moment.unix(invoice.date))
});
if (invoice.invoice_pdf) {
html += ` (<a href='${invoice.invoice_pdf}' target='_blank'>${I18n.t('discourse_donations.invoice')}</a>)`;
}
return new Handlebars.SafeString(html);
});
registerHelper("donation-charge", function([charge]) {
let html = I18n.t('discourse_donations.invoice_prefix');
let currency = charge.currency.toUpperCase();
html += ` ${currency}`;
html += ` ${formatAmount(charge.amount, currency)} `;
html += I18n.t(`discourse_donations.period.once`, {
anchor: formatAnchor('once', moment.unix(charge.created))
});
if (charge.receipt_email) {
html += `. ${I18n.t('discourse_donations.receipt', {
email: charge.receipt_email
})}`;
}
return new Handlebars.SafeString(html);
});
@@ -4,15 +4,24 @@ import { ajax } from 'discourse/lib/ajax';
export default DiscourseRoute.extend({
setupController(controller) {
let charges = [];
let subscriptions = [];
let customer = {};
controller.set('loadingDonations', true);
ajax('/donate/charges').then((result) => {
if (result && (result.charges || result.subscriptions)) {
controller.setProperties({
charges: result.charges,
subscriptions: result.subscriptions
});
ajax('/donate/charges').then((result) => {
if (result) {
charges = result.charges;
subscriptions = result.subscriptions;
customer = result.customer;
}
controller.setProperties({
charges: Ember.A(charges),
subscriptions: Ember.A(subscriptions),
customer
});
}).catch(popupAjaxError).finally(() => {
controller.set('loadingDonations', false);
})
@@ -3,12 +3,11 @@
<div class="underline">{{i18n 'discourse_donations.donations.subscriptions'}}</div>
<ul>
{{#each subscriptions as |s|}}
<li>{{donation-subscription s.subscription}}</li>
<li>{{donation-row subscription=s.subscription customer=customer new=s.new}}</li>
{{#if s.invoices}}
<ul>
{{#each s.invoices as |invoice|}}
<li>{{donation-invoice invoice}}</li>
<li>{{donation-row invoice=invoice customer=customer new=s.new}}</li>
{{/each}}
</ul>
{{/if}}
@@ -22,7 +21,7 @@
<div class='underline'>{{i18n 'discourse_donations.donations.charges'}}</div>
<ul>
{{#each charges as |charge|}}
<li>{{donation-charge charge}}</li>
<li>{{donation-row charge=charge customer=customer new=charge.new}}</li>
{{/each}}
</ul>
</div>
@@ -0,0 +1,39 @@
{{#if includePrefix}}
<span>{{i18n 'discourse_donations.invoice_prefix'}}</span>
{{/if}}
<span>{{currency}}</span>
<span>{{amount}}</span>
<span>{{period}}</span>
{{#if invoice}}
<a href='{{data.invoiceLink}}' target='_blank'>({{i18n 'discourse_donations.invoice'}})</a>
{{/if}}
{{#if currentUser}}
{{#if subscription}}
{{#if updating}}
{{loading-spinner size='small'}}
{{else}}
{{#unless canceled}}
<a {{action 'cancelSubscription'}}>
{{i18n 'cancel'}}
</a>
{{/unless}}
{{/if}}
{{/if}}
{{/if}}
{{#if receiptSent}}
<span></span>
<span>{{i18n 'discourse_donations.receipt' email=customer.email}}</span>
{{/if}}
{{#if new}}
<span class="new-flag">
{{d-icon 'circle'}}
<span>{{i18n 'new_item'}}</span>
</span>
{{/if}}
@@ -33,6 +33,7 @@
</div>
</div>
</div>
<div class="control-group">
<label class='control-label'>
{{i18n 'discourse_donations.transaction_fee.total'}}
@@ -8,17 +8,29 @@
{{stripe-card charges=charges subscriptions=subscriptions}}
</div>
{{#if currentUser}}
<div class="donations-page-donations">
<h3>{{i18n 'discourse_donations.donations.title'}}</h3>
{{#if loadingDonations}}
{{loading-spinner size='small'}}
{{else}}
<div class="donations-page-donations">
<h3>{{i18n 'discourse_donations.donations.title'}}</h3>
{{#if loadingDonations}}
<span>{{i18n 'discourse_donations.donations.loading'}}</span>
{{loading-spinner size='small'}}
{{else}}
{{#if currentUser}}
{{#if hasDonations}}
{{donation-list charges=charges subscriptions=subscriptions}}
{{donation-list charges=charges subscriptions=subscriptions customer=customer}}
{{else}}
{{i18n 'discourse_donations.donations.none'}}
{{/if}}
{{else}}
{{#if hasDonations}}
{{donation-list charges=charges subscriptions=subscriptions customer=customer}}
{{else}}
{{#if hasEmailResult}}
{{i18n 'discourse_donations.donations.none_email' email=email}}
{{else}}
{{input value=email placeholder=(i18n 'email')}}
{{d-button action='loadDonations' label='discourse_donations.donations.load' disabled=loadDonationsDisabled}}
{{/if}}
{{/if}}
{{/if}}
</div>
{{/if}}
{{/if}}
</div>
@@ -0,0 +1,11 @@
{{#d-modal-body title='discourse_donations.subscription.cancel.title'}}
{{i18n 'discourse_donations.subscription.cancel.description' site=siteSettings.title
currency=model.currency
amount=model.amount
period=model.period}}
{{/d-modal-body}}
<div class="modal-footer">
{{d-button action='confirm' label='yes_value' class='btn-primary'}}
{{d-button action='cancel' label='no_value'}}
</div>