[guadec-web-regcfp/develop] Multi-currency support
- From: Patrick Uiterwijk <puiterwijk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [guadec-web-regcfp/develop] Multi-currency support
- Date: Tue, 4 Aug 2015 19:58:05 +0000 (UTC)
commit eea49cab3239d3673222d52346366e3194915f49
Author: Patrick Uiterwijk <puiterwijk redhat com>
Date: Tue Aug 4 20:00:46 2015 +0200
Multi-currency support
app.js | 5 ++
bin/payment-status-update | 2 +-
config/config.json.example | 29 +++++++--
models/registration.js | 106 ++++++++++++++++++++++++++++---
models/registrationpayment.js | 1 +
routes/desk.js | 1 +
routes/registration.js | 42 +++++++++----
views/desk/main.hbs | 50 +++++++++------
views/index/index.hbs | 6 +-
views/layouts/main.hbs | 1 +
views/partials/currency_selector.hbs | 5 ++
views/partials/registration/payment.hbs | 3 +-
views/registration/pay.hbs | 4 +-
views/registration/receipt.hbs | 2 +-
views/registration/register.hbs | 8 +-
15 files changed, 204 insertions(+), 61 deletions(-)
---
diff --git a/app.js b/app.js
index 0517514..3f933df 100644
--- a/app.js
+++ b/app.js
@@ -33,6 +33,9 @@ var hbs = handlebars.create({
text = text.replace(/(\r\n|\n|\r)/gm, '<br>');
return new handlebars.handlebars.SafeString(text);
},
+ currency_symbol: function(currency) {
+ return config['registration']['currencies'][currency]['symbol'];
+ },
has_permission: utils.has_permission,
ifEqual: function(v1, v2, options) {
if(v1 == v2) {
@@ -78,6 +81,8 @@ app.use(session({
app.use(function(req, res, next) {
res.locals.session = req.session;
res.locals.config = config;
+ res.locals.req = { body: req.body,
+ query: req.query };
res.locals.development = env == 'development';
next();
});
diff --git a/bin/payment-status-update b/bin/payment-status-update
index 62735a1..cb6fd68 100755
--- a/bin/payment-status-update
+++ b/bin/payment-status-update
@@ -30,7 +30,7 @@ RegistrationPayment.findAll({
console.log("\tPaid: " + val['paid'] + ' (' + val['amount'] + ')');
console.log("\tPayPal state: " + payment.state + ' (' +
payment['transactions'][0]['amount']['currency'] + payment['transactions'][0]['amount']['total'] + ')');
- if(payment['transactions'][0]['amount']['currency'] !=
config['registration']['currency_value']) {
+ if(payment['transactions'][0]['amount']['currency'] != val['currency']) {
console.log('\tINVALID CURRENCY');
val.paid = false;
val.save();
diff --git a/config/config.json.example b/config/config.json.example
index e5740c8..a720e79 100644
--- a/config/config.json.example
+++ b/config/config.json.example
@@ -4,7 +4,10 @@
"database": {
"database": "database.sqlite",
"dialect": "sqlite",
- "storage": "database.sqlite"
+ "storage": "database.sqlite",
+ "define": {
+ "paranoid": true
+ }
},
"persona_audience": "http://localhost:3000",
@@ -28,7 +31,8 @@
"view_public": ["*authenticated*"],
"view_all": ["puiterwijk fedoraproject org"],
"add_payment": ["puiterwijk fedoraproject org"],
- "print_badge": ["puiterwijk fedoraproject org"]
+ "print_badge": ["puiterwijk fedoraproject org"],
+ "desk": ["puiterwijk fedoraproject org"],
}
},
@@ -44,10 +48,23 @@
"registration": {
"enabled": false,
- "currency_symbol": "€",
- "currency_value": "EUR",
- "min_amount_for_receipt": 20,
- "default_amount": 40
+ "currencies": {
+ "EUR": {
+ "symbol": "€",
+ "min_amount_for_receipt": 20,
+ "default_amount": 40,
+ "conversion_rate": 1
+ },
+ "SEK": {
+ "symbol": "kr",
+ "min_amount_for_receipt": 190,
+ "default_amount": 380,
+ "conversion_rate": 0.11
+ }
+ },
+ "main_currency": "EUR",
+ "paypal_experience_profile": "",
+ "desk_word": "something"
}
}
}
diff --git a/models/registration.js b/models/registration.js
index 04eff71..1de5ff7 100644
--- a/models/registration.js
+++ b/models/registration.js
@@ -1,5 +1,21 @@
"use strict";
+var env = process.env.NODE_ENV || "development";
+var config = require('../config/config.json')[env];
+
+function get_amount_string(amounts) {
+ var amount = "";
+ console.log("amount str: " + amounts);
+ for(var cur in amounts) {
+ if(amount != "") {
+ amount += ", ";
+ }
+ amount += config['registration']['currencies'][cur]['symbol'];
+ amount += amounts[cur];
+ }
+ return amount;
+}
+
module.exports = function(sequelize, DataTypes) {
var Registration = sequelize.define("Registration", {
irc: DataTypes.STRING,
@@ -19,35 +35,105 @@ module.exports = function(sequelize, DataTypes) {
display_id: function() {
return this.id;
},
- paid: function() {
- var amount = 0;
+
+ left_for_receipt: function() {
+ // This is quite a difficult function, and probably could use comments
+ var main_cur = config['registration']['main_currency'];
+ var main_cur_amount = 0;
+ var amounts = {};
+ var needed = {};
+ for(var currency in config['registration']['currencies']) {
+ amounts[currency] = 0;
+ needed[currency] = config['registration']['currencies'][currency]['min_amount_for_receipt'];
+ }
for(var payment in this.RegistrationPayments) {
payment = this.RegistrationPayments[payment];
if(payment.paid) {
- amount += payment.amount;
+ amounts[payment.currency] += payment.amount;
+ needed[payment.currency] -= payment.amount;
+ }
+ }
+ var amount_in_main_currency = 0;
+ for(var cur in amounts) {
+ console.log("Cur: " + cur + ", needed: " + needed[cur]);
+ if(needed[cur] <= 0) {
+ // Easy case: we have a currency which passed the threshold
+ return {};
+ }
+ amount_in_main_currency += (amounts[cur] *
config['registration']['currencies'][cur]['conversion_rate']);
+ if(amount_in_main_currency >=
config['registration']['currencies'][main_cur]['min_amount_for_receipt']) {
+ // After conversion, they paid enough
+ return {};
}
}
- return amount;
+ // It wasn't enough. Let's calculate the amounts needed to satisfy
+ var still_needed_main_currency =
config['registration']['currencies'][main_cur]['min_amount_for_receipt'] - amount_in_main_currency;
+
+ for(var cur in amounts) {
+ needed[cur] = still_needed_main_currency /
config['registration']['currencies'][cur]['conversion_rate'];
+ }
+ return needed;
+ },
+
+ eligible_for_receipt: function() {
+ return Object.keys(this.left_for_receipt).length === 0;
+ },
+ needed_for_receipt: function() {
+ return get_amount_string(this.left_for_receipt);
+ },
+ paid_amounts: function() {
+ var amounts = {};
+ for(var payment in this.RegistrationPayments) {
+ payment = this.RegistrationPayments[payment];
+ if(payment.paid) {
+ if(payment.currency in amounts) {
+ amounts[payment.currency] += payment.amount;
+ } else {
+ amounts[payment.currency] = payment.amount;
+ }
+ }
+ }
+ return amounts;
+ },
+ paid: function() {
+ return get_amount_string(this.paid_amounts);;
},
outstanding_onsite: function() {
- var amount = 0;
+ var amounts = {};
for(var payment in this.RegistrationPayments) {
payment = this.RegistrationPayments[payment];
if(!payment.paid && payment.type == 'onsite') {
- amount += payment.amount;
+ if(payment.currency in amounts) {
+ amounts[payment.currency] += payment.amount;
+ } else {
+ amounts[payment.currency] = payment.amount;
+ }
}
}
- return amount;
+ return get_amount_string(amounts);
},
outstanding_paypal: function() {
- var amount = 0;
+ var amounts = {};
for(var payment in this.RegistrationPayments) {
payment = this.RegistrationPayments[payment];
if(!payment.paid && payment.type == 'paypal') {
- amount += payment.amount;
+ if(payment.currency in amounts) {
+ amounts[payment.currency] += payment.amount;
+ } else {
+ amounts[payment.currency] = payment.amount;
+ }
+ }
+ }
+ return get_amount_string(amounts);
+ },
+ has_outstanding_onsite: function() {
+ for(var payment in this.RegistrationPayments) {
+ payment = this.RegistrationPayments[payment];
+ if(!payment.paid && payment.type == 'onsite') {
+ return true;
}
}
- return amount;
+ return false;
}
}
});
diff --git a/models/registrationpayment.js b/models/registrationpayment.js
index ce2e9a2..9ff94f9 100644
--- a/models/registrationpayment.js
+++ b/models/registrationpayment.js
@@ -2,6 +2,7 @@
module.exports = function(sequelize, DataTypes) {
var RegistrationPayment = sequelize.define("RegistrationPayment", {
+ currency: DataTypes.STRING(3),
amount: DataTypes.FLOAT,
paid: DataTypes.BOOLEAN,
type: DataTypes.ENUM('paypal', 'onsite'),
diff --git a/routes/desk.js b/routes/desk.js
index 8d54a3b..4474465 100644
--- a/routes/desk.js
+++ b/routes/desk.js
@@ -146,6 +146,7 @@ router.post('/payment/add', function(req, res, next) {
Registration.findOne({where: {id:regid}})
.then(function(registration) {
var payment_info = {
+ currency: req.body.currency,
amount: req.body.amount,
paid: true,
type: 'onsite',
diff --git a/routes/registration.js b/routes/registration.js
index aa1b2bf..3700731 100644
--- a/routes/registration.js
+++ b/routes/registration.js
@@ -14,6 +14,12 @@ var config = require('../config/config.json')[env];
var paypal = require('paypal-rest-sdk');
paypal.configure(config['paypal']);
+function get_min_main() {
+ // Get the minimum amount for receipt in local currency
+ var main_currency = config['registration']['main_currency'];
+ return config['registration']['currencies'][main_currency]['min_amount_for_receipt'];
+}
+
router.all('/', utils.require_feature("registration"));
router.all('/list', utils.require_permission('registration/view_public'));
@@ -37,12 +43,13 @@ router.get('/pay', function(req, res, next) {
});
router.post('/pay', function(req, res, next) {
+ var currency = req.body.currency;
var regfee = req.body.regfee.trim();
if(regfee == null) {
res.render('registration/pay');
} else {
- res.render('registration/pay_do', {regfee: regfee});
+ res.render('registration/pay_do', {currency: currency, regfee: regfee});
}
});
@@ -75,6 +82,7 @@ router.post('/pay/paypal/execute', function(req, res, next) {
console.log('Response: ');
console.log(JSON.stringify(payment));
var info = {
+ currency: payment[transactions[0]['amount']['currency']
amount: payment.transactions[0]['amount']['total'],
paid: payment.state == 'approved',
type: 'paypal',
@@ -111,7 +119,7 @@ router.post('/pay/paypal/execute', function(req, res, next) {
});
});
-function create_payment(req, res, next, amount) {
+function create_payment(req, res, next, currency, amount) {
var create_payment = {
'intent': 'sale',
"experience_profile_id": config['registration']['paypal_experience_profile'],
@@ -128,12 +136,12 @@ function create_payment(req, res, next, amount) {
'name': 'GUADEC Registration fee',
'sku': 'regfee:' + req.user.email,
'price': amount.toString(),
- 'currency': config['registration']['currency_value'],
+ 'currency': currency,
'quantity': 1
}]
},
'amount': {
- 'currency': config['registration']['currency_value'],
+ 'currency': currency,
'total': amount.toString()
},
'description': 'GUADEC Registration fee for ' + req.user.email
@@ -166,11 +174,13 @@ router.all('/pay/do', utils.require_user);
router.all('/pay/do', utils.require_permission('registration/pay_extra'));
router.post('/pay/do', function(req, res, next) {
var method = req.body.method;
+ req.body.regfee = Math.abs(req.body.regfee);
if(req.body.regfee == 0 || req.body.regfee == null) {
method = 'onsite';
}
if(method == 'onsite') {
var info = {
+ currency: req.body.currency,
amount: req.body.regfee,
paid: false,
type: 'onsite',
@@ -190,7 +200,7 @@ router.post('/pay/do', function(req, res, next) {
console.log('Error attaching payment to reg: ' + err);
res.status(500).send('Error attaching payment');
} else {
- res.render('registration/payment_onsite_registered', {amount: info.amount});
+ res.render('registration/payment_onsite_registered', {currency: info.currency, amount:
info.amount});
}
});
});
@@ -198,7 +208,7 @@ router.post('/pay/do', function(req, res, next) {
});
} else if(method == 'paypal') {
req.session.regfee = req.body.regfee;
- create_payment(req, res, next, req.body.regfee);
+ create_payment(req, res, next, req.body.currency, req.body.regfee);
} else {
res.status(402).send('Invalid payment method selected');
}
@@ -211,7 +221,7 @@ router.get('/receipt', function(req, res, next) {
.complete(function(err, reg) {
if(!!err) {
res.status(500).send('Error retrieving your registration');
- } else if(reg.paid < config.registration.min_amount_for_receipt) {
+ } else if(!reg.eligible_for_receipt) {
res.status(401).send('Not enough paid for receipt');
} else {
res.render('registration/receipt', { registration: reg , layout:false });
@@ -225,10 +235,12 @@ router.get('/register', function(req, res, next) {
req.user.getRegistration()
.complete(function(err, reg) {
res.render('registration/register', { registration: reg,
- ask_regfee: reg == null });
+ ask_regfee: reg == null,
+ min_amount_main_currency: get_min_main() });
});
} else {
- res.render('registration/register', { registration: {is_public: true}, ask_regfee: true });
+ res.render('registration/register', { registration: {is_public: true}, ask_regfee: true,
+ min_amount_main_currency: get_min_main()});
};
});
@@ -236,7 +248,8 @@ router.post('/register', function(req, res, next) {
if(!req.user) {
// Create user object and set as req.user
if(req.body.name.trim() == '') {
- res.render('registration/register', { registration: null, submission_error: true, ask_regfee: true} );
+ res.render('registration/register', { registration: null, submission_error: true, ask_regfee: true,
+ min_amount_main_currency: get_min_main()} );
} else {
var user_info = {
email: req.session.currentUser,
@@ -270,12 +283,14 @@ function handle_registration(req, res, next) {
receipt_sent: false,
UserId: req.user.Id
};
+ var currency = req.body.currency;
var regfee = req.body.regfee;
reg_info.UserId = req.user.Id;
if((reg == null && regfee == null)) {
res.render('registration/register', { registration: reg_info,
- submission_error: true, ask_regfee: reg == null});
+ submission_error: true, ask_regfee: reg == null,
+ min_amount_main_currency: get_min_main()});
} else {
// Form OK
if(reg == null) {
@@ -292,7 +307,7 @@ function handle_registration(req, res, next) {
console.log('Error adding reg to user: ' + err);
res.status(500).send('Error attaching registration to your user');
} else {
- res.render('registration/registration_success', {regfee: regfee});
+ res.render('registration/registration_success', {currency: currency, regfee: regfee});
}
});
}
@@ -306,7 +321,8 @@ function handle_registration(req, res, next) {
reg.save().complete(function (err, reg){
if(!!err) {
res.render('registration/register', { registration: reg_info,
- save_error: true });
+ save_error: true,
+ min_amount_main_currency: get_min_main() });
} else {
res.render('registration/update_success');
}
diff --git a/views/desk/main.hbs b/views/desk/main.hbs
index 27ca999..c94f850 100644
--- a/views/desk/main.hbs
+++ b/views/desk/main.hbs
@@ -41,7 +41,7 @@
{{#if this.badge_printed}}
BADGE PRINTED (<a href="/desk/badge?regid={{this.id}}" target="_blank">reprint</a>)
{{else}}
- {{#ifGT this.outstanding_onsite 0}}
+ {{#if this.has_outstanding_onsite}}
Outstanding: {{this.outstanding_onsite}}<br />
<form method="post" action="/desk/payment/markpaid" data-message="Really mark
'{{this.User.name}}' as having paid {{this.outstanding_onsite}}?">
<input type="hidden" name="regid" value="{{this.id}}">
@@ -52,25 +52,41 @@
<input type="submit" value="Clear">
</form>
{{else}}
- <form class="payment_add_form" method="post" action="/desk/payment/add"
data-name="{{this.User.name}}">
- <input type="hidden" name="regid" value="{{this.id}}">
+ <form class="payment_add_form" data-name="{{this.User.name}}" data-regid="{{this.id}}">
<input type="submit" value="Add payment">
</form>
- <form class="finish_reg_form" method="post" action="/desk/finish" data-message="Really
finish registration for '{{this.User.name}}' and print badge?" data-amount={{this.paid}}>
+ <form class="finish_reg_form" method="post" action="/desk/finish"
+ data-message="Really finish registration for '{{this.User.name}}' and print badge?"
+ data-needed="{{this.needed_for_receipt}}"
+ data-receipt_eligible="{{this.eligible_for_receipt}}">
<input type="hidden" name="regid" value="{{this.id}}">
<input type="submit" value="Print badge">
</form>
- {{/ifGT}}
+ {{/if}}
{{/if}}
</td>
</tr>
{{/each}}
</table>
-<script type="text/javascript">
-var min_for_receipt = {{config.registration.min_amount_for_receipt}};
+<div id="add_payment_dialog">
+Adding payment for <span id="add_payment_dialog_name"></span>:
+ <form method="post" action="/desk/payment/add">
+ <input type="hidden" name="regid" id="add_payment_dialog_regid">
+ {{>currency_selector}}
+ <input type="text" name="amount">
+ <input type="submit" value="Add">
+ </form>
+</div>
+
+
+<script type="text/javascript">
$(function() {
+ $('#add_payment_dialog').dialog({
+ autoOpen: false
+ });
+
$('form').submit(function(event) {
if($(event.target).data('message') === undefined) {
return true;
@@ -80,23 +96,17 @@ $(function() {
});
$('.finish_reg_form').submit(function(event) {
- var amount = $(event.target).data('amount');
- if(amount < min_for_receipt) {
- return !window.confirm('CAUTION: User did not pay enough for receipt (paid: ' + amount + ',
needed: ' + min_for_receipt + '). Do you want to cancel?');
+ var eligible = $(event.target).data('receipt_eligible');
+ if(eligible != 'true') {
+ return !window.confirm('CAUTION: User did not pay enough for receipt (needed: ' +
$(event.target).data('needed') + '). Do you want to cancel?');
}
});
$('.payment_add_form').submit(function(event) {
- var name = $(event.target).data('name');
- var amount = window.prompt("What amount has '" + name + "' paid?", "0.00");
- if(amount != null && parseFloat(amount) != 0 && !isNaN(parseFloat(amount))) {
- $(event.target).append('<input type="hidden" name="amount" value="' + amount + '">');
- $(event.target).off('submit');
- $(event.target).submit();
- return false;
- } else {
- return false;
- }
+ $('#add_payment_dialog_name').html($(event.target).data('name'));
+ $('#add_payment_dialog_regid').val($(event.target).data('regid'));
+ $('#add_payment_dialog').dialog('open');
+ return false;
});
});
</script>
diff --git a/views/index/index.hbs b/views/index/index.hbs
index d9b4587..9378e01 100644
--- a/views/index/index.hbs
+++ b/views/index/index.hbs
@@ -45,11 +45,11 @@ Welcome, {{name}}<br />
{{#if registration}}
<h3>Registration ID: {{registration.display_id}}</h3>
<div class="button"><a href="/registration/register">Update registration</a></div><br/>
-{{#ifGTE registration.paid config.registration.min_amount_for_receipt}}
+{{#if registration.eligible_for_receipt}}
<div class="button"><a href="/registration/receipt" target="_blank">Get receipt</a></div>
{{else}}
-Not enough paid for receipt (Paid {{config.registration.currency_symbol}}{{registration.paid}}, outstanding
for onsite payment: {{config.registration.currency_symbol}}{{registration.outstanding_onsite}}, PayPal
outstanding: {{config.registration.currency_symbol}}{{registration.outstanding_paypal}})<br/>
-{{/ifGTE}}
+Not enough paid for receipt (Paid {{registration.paid}}, outstanding for onsite payment:
{{registration.outstanding_onsite}}, PayPal outstanding: {{registration.outstanding_paypal}}. Any of these
needed: {{registration.needed_for_receipt}})<br/>
+{{/if}}
{{#has_permission "registration/pay_extra"}}
<div class="button"><a href="/registration/pay">Pay more</a></div>
{{/has_permission}}
diff --git a/views/layouts/main.hbs b/views/layouts/main.hbs
index ced82b1..07387cd 100644
--- a/views/layouts/main.hbs
+++ b/views/layouts/main.hbs
@@ -4,6 +4,7 @@
<title>Event registration</title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
+ <link href="https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.min.css"
rel="stylesheet">
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
<script type="text/javascript" src="https://login.persona.org/include.js"></script>
diff --git a/views/partials/currency_selector.hbs b/views/partials/currency_selector.hbs
new file mode 100644
index 0000000..6f5303f
--- /dev/null
+++ b/views/partials/currency_selector.hbs
@@ -0,0 +1,5 @@
+<select name="currency">
+ {{#each config.registration.currencies}}
+ <option value="{{ key}}">{{this.symbol}}</option>
+ {{/each}}
+</select>
diff --git a/views/partials/registration/payment.hbs b/views/partials/registration/payment.hbs
index ad985c9..ac840db 100644
--- a/views/partials/registration/payment.hbs
+++ b/views/partials/registration/payment.hbs
@@ -1,5 +1,6 @@
-To complete your registration, choose a payment for {{config.registration.currency_symbol}}{{regfee}}
below:<br/><br/>
+To complete your registration, choose a payment for {{currency_symbol currency}}{{regfee}} below:<br/><br/>
<form class="submission-form" action="/registration/pay/do" method="POST">
+<input type="hidden" name="currency" value="{{currency}}">
<input type="hidden" name="regfee" value="{{regfee}}">
<input type="radio" name="method" value="paypal" style="vertical-align: top;" checked="checked"> <div
style="display: inline-block;">Pay using PayPal<p class="note">No PayPal account required</p></div><br/>
<input type="radio" name="method" value="onsite" style="vertical-align: top;"> <div style="display:
inline-block;">Pay at the conference<p class="note">If you select this option, you can pay at the
registration desk at GUADEC</p></div><br/><br/>
diff --git a/views/registration/pay.hbs b/views/registration/pay.hbs
index 1e0dfde..075535c 100644
--- a/views/registration/pay.hbs
+++ b/views/registration/pay.hbs
@@ -2,9 +2,9 @@
<table class="submission-form">
<tr><td>Your name:</td><td><input type="text" name="submitter_name" value="{{user.name}}" disabled
/></td></tr>
<tr><td>Amount:</td><td>
-{{config.registration.currency_symbol}} <input type="text" name="regfee" class="reg-fee"
value="{{config.registration.default_amount}}">
+{{>currency_selector}} <input type="text" name="regfee" class="reg-fee">
<p class="note">Feel free to support us by donating as much as you're able to.<br />
-We can only provide receipts for payments over
{{config.registration.currency_symbol}}{{config.registration.min_amount_for_receipt}}.
+We can only provide receipts for payments over {{currency_symbol
config.registration.main_currency}}{{min_amount_main_currency}} or an equivalent value in another currency.
</td></tr>
<tr><td> </td>
diff --git a/views/registration/receipt.hbs b/views/registration/receipt.hbs
index e6cfc16..d723607 100644
--- a/views/registration/receipt.hbs
+++ b/views/registration/receipt.hbs
@@ -37,7 +37,7 @@ body {
<h1>Receipt</h1>
<h3>Thank you, {{user.name}}, for registering to GUADEC 2015!</h3>
-<p>We received your payment of {{config.registration.currency_symbol}}{{registration.paid}} to the GNOME
Foundation, as a registration fee for GUADEC 2015.</p>
+<p>We received your payment of {{registration.paid}} to the GNOME Foundation, as a registration fee for
GUADEC 2015.</p>
<p>See you in Sweden!</p>
</div>
diff --git a/views/registration/register.hbs b/views/registration/register.hbs
index 2300f55..09660be 100644
--- a/views/registration/register.hbs
+++ b/views/registration/register.hbs
@@ -13,15 +13,15 @@
{{#unless ask_regfee}}
Registered
{{else}}
-{{config.registration.currency_symbol}} <input type="text" name="regfee" class="reg-fee"
value="{{config.registration.default_amount}}">
+{{>currency_selector}} <input type="text" name="regfee" class="reg-fee"
value="{{config.registration.default_amount}}">
<p class="note">Feel free to support us by donating as much as you're able to.<br />
-Please note that we can only provide receipts for payments over
{{config.registration.currency_symbol}}{{config.registration.min_amount_for_receipt}}.
+We can only provide receipts for payments over {{currency_symbol
config.registration.main_currency}}{{min_amount_main_currency}} or an equivalent value in another currency.
{{/unless}}</p>
</tr>
--<tr><td>Gender</td><td><input type="text" name="gender" value="{{registration.gender}}"
placeholder="(optional: male, female, genderqueer, etc.)"><br/><p class="note">We will not publish gender
data.<br/> It will only be used for attendee statistics and for an invitation to the women's
dinner.</p></td></tr>
+<tr><td>Gender</td><td><input type="text" name="gender" value="{{registration.gender}}"
placeholder="(optional: male, female, genderqueer, etc.)"><br/><p class="note">We will not publish gender
data.<br/> It will only be used for attendee statistics and for an invitation to the women's
dinner.</p></td></tr>
--<tr><td>Country</td><td><input type="text" name="country" value="{{registration.country}}"
placeholder="(optional)"><br/><p class="note">We will not publish country data.<br/> It will only be used for
attendee statistics.</p></td></tr>
+<tr><td>Country</td><td><input type="text" name="country" value="{{registration.country}}"
placeholder="(optional)"><br/><p class="note">We will not publish country data.<br/> It will only be used for
attendee statistics.</p></td></tr>
<tr><td> </td><td><input type="checkbox" value="false" name="is_public"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]