2019-08-27 20:37:20 +10:00
|
|
|
import { ajax } from "discourse/lib/ajax";
|
|
|
|
import { formatAnchor, zeroDecimalCurrencies } from "../lib/donation-utilities";
|
|
|
|
import { default as computed } from "ember-addons/ember-computed-decorators";
|
2018-09-22 14:03:30 +10:00
|
|
|
import { emailValid as emailValidHelper } from "discourse/lib/utilities";
|
2017-02-22 10:21:42 +11:00
|
|
|
|
2017-02-21 10:25:31 +11:00
|
|
|
export default Ember.Component.extend({
|
2017-05-03 15:13:41 +10:00
|
|
|
result: [],
|
2017-02-28 12:39:07 +11:00
|
|
|
stripe: null,
|
2017-03-06 11:12:22 +11:00
|
|
|
transactionInProgress: null,
|
2017-03-07 15:21:51 +11:00
|
|
|
settings: null,
|
2018-02-02 17:43:54 +08:00
|
|
|
showTransactionFeeDescription: false,
|
2018-06-28 13:46:02 +10:00
|
|
|
includeTransactionFee: true,
|
2017-02-27 14:22:52 +11:00
|
|
|
|
2017-02-28 12:39:07 +11:00
|
|
|
init() {
|
|
|
|
this._super();
|
2019-08-27 20:37:20 +10:00
|
|
|
const user = this.get("currentUser");
|
2018-06-25 18:14:50 +10:00
|
|
|
const settings = Discourse.SiteSettings;
|
2018-06-21 19:00:43 +10:00
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
this.set(
|
|
|
|
"create_accounts",
|
|
|
|
!user && settings.discourse_donations_enable_create_accounts
|
|
|
|
);
|
|
|
|
this.set("stripe", Stripe(settings.discourse_donations_public_key));
|
2018-06-25 18:14:50 +10:00
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
const types = settings.discourse_donations_types.split("|") || [];
|
|
|
|
const amounts = this.get("donateAmounts");
|
2018-06-22 11:55:16 +10:00
|
|
|
|
|
|
|
this.setProperties({
|
|
|
|
types,
|
|
|
|
type: types[0],
|
|
|
|
amount: amounts[0].value
|
|
|
|
});
|
2018-06-21 19:00:43 +10:00
|
|
|
},
|
|
|
|
|
2018-09-22 14:03:30 +10:00
|
|
|
@computed
|
|
|
|
causes() {
|
2019-08-27 20:37:20 +10:00
|
|
|
const categoryEnabled =
|
|
|
|
Discourse.SiteSettings.discourse_donations_cause_category;
|
2018-09-22 14:03:30 +10:00
|
|
|
|
|
|
|
if (categoryEnabled) {
|
2019-08-27 20:37:20 +10:00
|
|
|
let categoryIds = Discourse.SiteSettings.discourse_donations_causes_categories.split(
|
|
|
|
"|"
|
|
|
|
);
|
2018-09-22 14:03:30 +10:00
|
|
|
|
|
|
|
if (categoryIds.length) {
|
|
|
|
categoryIds = categoryIds.map(Number);
|
|
|
|
return this.site
|
|
|
|
.get("categoriesList")
|
|
|
|
.filter(c => {
|
|
|
|
return categoryIds.indexOf(c.id) > -1;
|
2019-08-27 20:37:20 +10:00
|
|
|
})
|
|
|
|
.map(c => {
|
2018-09-22 14:03:30 +10:00
|
|
|
return {
|
|
|
|
id: c.id,
|
|
|
|
name: c.name
|
|
|
|
};
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const causes = Discourse.SiteSettings.discourse_donations_causes;
|
2019-08-27 20:37:20 +10:00
|
|
|
return causes ? causes.split("|") : [];
|
2018-09-22 14:03:30 +10:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
@computed("types")
|
2018-06-21 19:00:43 +10:00
|
|
|
donationTypes(types) {
|
2019-08-27 20:37:20 +10:00
|
|
|
return types.map(type => {
|
2018-06-21 19:00:43 +10:00
|
|
|
return {
|
|
|
|
id: type,
|
|
|
|
name: I18n.t(`discourse_donations.types.${type}`)
|
2018-06-28 13:46:02 +10:00
|
|
|
};
|
|
|
|
});
|
2018-06-21 19:00:43 +10:00
|
|
|
},
|
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
@computed("type")
|
2018-06-21 19:00:43 +10:00
|
|
|
period(type) {
|
2019-08-27 20:37:20 +10:00
|
|
|
return I18n.t(`discourse_donations.period.${type}`, {
|
|
|
|
anchor: formatAnchor(type)
|
|
|
|
});
|
2017-02-28 12:39:07 +11:00
|
|
|
},
|
2017-02-22 10:21:42 +11:00
|
|
|
|
2018-02-02 19:49:58 +08:00
|
|
|
@computed
|
|
|
|
donateAmounts() {
|
2019-08-27 20:37:20 +10:00
|
|
|
const setting = Discourse.SiteSettings.discourse_donations_amounts.split(
|
|
|
|
"|"
|
|
|
|
);
|
2018-02-02 19:49:58 +08:00
|
|
|
if (setting.length) {
|
2019-08-27 20:37:20 +10:00
|
|
|
return setting.map(amount => {
|
2018-02-02 19:49:58 +08:00
|
|
|
return {
|
|
|
|
value: parseInt(amount, 10),
|
|
|
|
name: `${amount}.00`
|
|
|
|
};
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
@computed("stripe")
|
2018-02-02 17:43:54 +08:00
|
|
|
card(stripe) {
|
|
|
|
let elements = stripe.elements();
|
2019-08-27 20:37:20 +10:00
|
|
|
let card = elements.create("card", {
|
2018-06-25 18:14:50 +10:00
|
|
|
hidePostalCode: !Discourse.SiteSettings.discourse_donations_zip_code
|
|
|
|
});
|
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
card.addEventListener("change", event => {
|
2018-06-25 18:14:50 +10:00
|
|
|
if (event.error) {
|
2019-08-27 20:37:20 +10:00
|
|
|
this.set("stripeError", event.error.message);
|
2018-06-25 18:14:50 +10:00
|
|
|
} else {
|
2019-08-27 20:37:20 +10:00
|
|
|
this.set("stripeError", "");
|
2018-06-25 18:14:50 +10:00
|
|
|
}
|
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
if (event.elementType === "card" && event.complete) {
|
|
|
|
this.set("stripeReady", true);
|
2018-06-25 18:14:50 +10:00
|
|
|
}
|
2017-03-07 15:21:51 +11:00
|
|
|
});
|
2018-06-25 18:14:50 +10:00
|
|
|
|
|
|
|
return card;
|
2018-02-02 17:43:54 +08:00
|
|
|
},
|
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
@computed("amount")
|
2018-02-02 17:43:54 +08:00
|
|
|
transactionFee(amount) {
|
2019-08-27 20:37:20 +10:00
|
|
|
const fixed =
|
|
|
|
Discourse.SiteSettings.discourse_donations_transaction_fee_fixed;
|
|
|
|
const percent =
|
|
|
|
Discourse.SiteSettings.discourse_donations_transaction_fee_percent;
|
|
|
|
const fee = (amount + fixed) / (1 - percent) - amount;
|
2018-02-02 17:43:54 +08:00
|
|
|
return Math.round(fee * 100) / 100;
|
|
|
|
},
|
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
@computed("amount", "transactionFee", "includeTransactionFee")
|
2018-02-02 17:43:54 +08:00
|
|
|
totalAmount(amount, fee, include) {
|
|
|
|
if (include) return amount + fee;
|
|
|
|
return amount;
|
|
|
|
},
|
2017-02-21 10:25:31 +11:00
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
@computed("email")
|
2018-06-25 18:37:55 +10:00
|
|
|
emailValid(email) {
|
2018-09-22 14:03:30 +10:00
|
|
|
return emailValidHelper(email);
|
2018-06-25 18:37:55 +10:00
|
|
|
},
|
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
@computed("email", "emailValid")
|
2018-06-25 18:37:55 +10:00
|
|
|
showEmailError(email, emailValid) {
|
|
|
|
return email && email.length > 3 && !emailValid;
|
|
|
|
},
|
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
@computed("currentUser", "emailValid")
|
2018-06-25 18:37:55 +10:00
|
|
|
userReady(currentUser, emailValid) {
|
|
|
|
return currentUser || emailValid;
|
2018-06-25 18:14:50 +10:00
|
|
|
},
|
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
@computed("cause")
|
2018-09-22 14:03:30 +10:00
|
|
|
causeValid(cause) {
|
|
|
|
return cause || !Discourse.SiteSettings.discourse_donations_cause_required;
|
|
|
|
},
|
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
@computed("userReady", "stripeReady", "causeValid")
|
2018-09-22 14:03:30 +10:00
|
|
|
formIncomplete(userReady, stripeReady, causeValid) {
|
|
|
|
return !userReady || !stripeReady || !causeValid;
|
2018-06-25 18:14:50 +10:00
|
|
|
},
|
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
@computed("transactionInProgress", "formIncomplete")
|
2018-06-25 18:14:50 +10:00
|
|
|
disableSubmit(transactionInProgress, formIncomplete) {
|
|
|
|
return transactionInProgress || formIncomplete;
|
|
|
|
},
|
|
|
|
|
2017-02-21 10:25:31 +11:00
|
|
|
didInsertElement() {
|
2017-02-23 09:30:40 +11:00
|
|
|
this._super();
|
2019-08-27 20:37:20 +10:00
|
|
|
this.get("card").mount("#card-element");
|
|
|
|
Ember.$(document).on("click", Ember.run.bind(this, this.documentClick));
|
2018-06-22 11:55:16 +10:00
|
|
|
},
|
|
|
|
|
|
|
|
willDestroyElement() {
|
2019-08-27 20:37:20 +10:00
|
|
|
Ember.$(document).off("click", Ember.run.bind(this, this.documentClick));
|
2018-06-22 11:55:16 +10:00
|
|
|
},
|
|
|
|
|
|
|
|
documentClick(e) {
|
2019-08-27 20:37:20 +10:00
|
|
|
let $element = this.$(".transaction-fee-description");
|
2018-06-22 11:55:16 +10:00
|
|
|
let $target = $(e.target);
|
2019-08-27 20:37:20 +10:00
|
|
|
if ($target.closest($element).length < 1 && this._state !== "destroying") {
|
|
|
|
this.set("showTransactionFeeDescription", false);
|
2018-06-22 11:55:16 +10:00
|
|
|
}
|
2017-02-21 10:25:31 +11:00
|
|
|
},
|
|
|
|
|
2017-04-03 11:05:22 +10:00
|
|
|
setSuccess() {
|
2019-08-27 20:37:20 +10:00
|
|
|
this.set("paymentSuccess", true);
|
2017-04-03 11:05:22 +10:00
|
|
|
},
|
|
|
|
|
|
|
|
endTranscation() {
|
2019-08-27 20:37:20 +10:00
|
|
|
this.set("transactionInProgress", false);
|
2017-04-03 11:05:22 +10:00
|
|
|
},
|
|
|
|
|
2017-05-03 15:13:41 +10:00
|
|
|
concatMessages(messages) {
|
2019-08-27 20:37:20 +10:00
|
|
|
this.set("result", this.get("result").concat(messages));
|
2017-05-03 15:13:41 +10:00
|
|
|
},
|
|
|
|
|
2017-02-21 10:25:31 +11:00
|
|
|
actions: {
|
2018-02-02 17:43:54 +08:00
|
|
|
toggleTransactionFeeDescription() {
|
2019-08-27 20:37:20 +10:00
|
|
|
this.toggleProperty("showTransactionFeeDescription");
|
2018-02-02 17:43:54 +08:00
|
|
|
},
|
|
|
|
|
2017-02-21 10:25:31 +11:00
|
|
|
submitStripeCard() {
|
2017-03-13 11:19:10 +11:00
|
|
|
let self = this;
|
2019-08-27 20:37:20 +10:00
|
|
|
this.set("transactionInProgress", true);
|
2017-02-23 09:30:40 +11:00
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
this.get("stripe")
|
|
|
|
.createToken(this.get("card"))
|
|
|
|
.then(data => {
|
|
|
|
self.set("result", []);
|
2018-06-25 18:14:50 +10:00
|
|
|
|
2019-08-27 20:37:20 +10:00
|
|
|
if (data.error) {
|
|
|
|
this.setProperties({
|
|
|
|
stripeError: data.error.message,
|
|
|
|
stripeReady: false
|
2017-04-03 12:49:23 +10:00
|
|
|
});
|
2019-08-27 20:37:20 +10:00
|
|
|
self.endTranscation();
|
|
|
|
} else {
|
|
|
|
const settings = Discourse.SiteSettings;
|
|
|
|
|
|
|
|
const transactionFeeEnabled =
|
|
|
|
settings.discourse_donations_enable_transaction_fee;
|
|
|
|
let amount = transactionFeeEnabled
|
|
|
|
? this.get("totalAmount")
|
|
|
|
: this.get("amount");
|
|
|
|
|
|
|
|
if (
|
|
|
|
zeroDecimalCurrencies.indexOf(
|
|
|
|
settings.discourse_donations_currency
|
|
|
|
) === -1
|
|
|
|
) {
|
|
|
|
amount = amount * 100;
|
|
|
|
}
|
|
|
|
|
|
|
|
let params = {
|
|
|
|
stripeToken: data.token.id,
|
|
|
|
cause: self.get("cause"),
|
|
|
|
type: self.get("type"),
|
|
|
|
amount,
|
|
|
|
email: self.get("email"),
|
|
|
|
username: self.get("username"),
|
|
|
|
create_account: self.get("create_accounts")
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!self.get("paymentSuccess")) {
|
|
|
|
ajax("/donate/charges", {
|
|
|
|
data: params,
|
|
|
|
method: "post"
|
|
|
|
}).then(result => {
|
|
|
|
if (result.subscription) {
|
|
|
|
let subscription = $.extend({}, result.subscription, {
|
|
|
|
new: true
|
|
|
|
});
|
|
|
|
this.get("subscriptions").unshiftObject(subscription);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result.charge) {
|
|
|
|
let charge = $.extend({}, result.charge, {
|
|
|
|
new: true
|
|
|
|
});
|
|
|
|
this.get("charges").unshiftObject(charge);
|
|
|
|
}
|
|
|
|
|
|
|
|
self.concatMessages(result.messages);
|
|
|
|
|
|
|
|
self.endTranscation();
|
|
|
|
});
|
|
|
|
}
|
2017-04-03 12:49:23 +10:00
|
|
|
}
|
2019-08-27 20:37:20 +10:00
|
|
|
});
|
2017-02-21 10:25:31 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|