mirror of
				https://github.com/aclindsa/moneygo.git
				synced 2025-11-03 18:13:27 -05:00 
			
		
		
		
	Add per-user default currency
This commit is contained in:
		@@ -5,6 +5,7 @@ var ErrorActions = require('./ErrorActions');
 | 
				
			|||||||
var models = require('../models.js');
 | 
					var models = require('../models.js');
 | 
				
			||||||
var Security = models.Security;
 | 
					var Security = models.Security;
 | 
				
			||||||
var Error = models.Error;
 | 
					var Error = models.Error;
 | 
				
			||||||
 | 
					var SecurityType = models.SecurityType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function searchSecurityTemplates(searchString, searchType) {
 | 
					function searchSecurityTemplates(searchString, searchType) {
 | 
				
			||||||
	return {
 | 
						return {
 | 
				
			||||||
@@ -23,6 +24,19 @@ function securityTemplatesSearched(searchString, searchType, securities) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function fetchCurrencyTemplates() {
 | 
				
			||||||
 | 
						return {
 | 
				
			||||||
 | 
							type: SecurityTemplateConstants.FETCH_CURRENCIES
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function currencyTemplatesFetched(currencies) {
 | 
				
			||||||
 | 
						return {
 | 
				
			||||||
 | 
							type: SecurityTemplateConstants.CURRENCIES_FETCHED,
 | 
				
			||||||
 | 
							currencies: currencies
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function search(searchString, searchType, limit) {
 | 
					function search(searchString, searchType, limit) {
 | 
				
			||||||
	return function (dispatch) {
 | 
						return function (dispatch) {
 | 
				
			||||||
		dispatch(searchSecurityTemplates(searchString, searchType));
 | 
							dispatch(searchSecurityTemplates(searchString, searchType));
 | 
				
			||||||
@@ -57,6 +71,38 @@ function search(searchString, searchType, limit) {
 | 
				
			|||||||
	};
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function fetchCurrencies() {
 | 
				
			||||||
 | 
						return function (dispatch) {
 | 
				
			||||||
 | 
							dispatch(fetchCurrencyTemplates());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							$.ajax({
 | 
				
			||||||
 | 
								type: "GET",
 | 
				
			||||||
 | 
								dataType: "json",
 | 
				
			||||||
 | 
								url: "securitytemplate/?search=&type=currency",
 | 
				
			||||||
 | 
								success: function(data, status, jqXHR) {
 | 
				
			||||||
 | 
									var e = new Error();
 | 
				
			||||||
 | 
									e.fromJSON(data);
 | 
				
			||||||
 | 
									if (e.isError()) {
 | 
				
			||||||
 | 
										dispatch(ErrorActions.serverError(e));
 | 
				
			||||||
 | 
									} else if (data.securities == null) {
 | 
				
			||||||
 | 
										dispatch(currencyTemplatesFetched(new Array()));
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										dispatch(currencyTemplatesFetched(
 | 
				
			||||||
 | 
												data.securities.map(function(json) {
 | 
				
			||||||
 | 
											var s = new Security();
 | 
				
			||||||
 | 
											s.fromJSON(json);
 | 
				
			||||||
 | 
											return s;
 | 
				
			||||||
 | 
										})));
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								error: function(jqXHR, status, error) {
 | 
				
			||||||
 | 
									dispatch(ErrorActions.ajaxError(error));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
	search: search
 | 
						search: search,
 | 
				
			||||||
 | 
						fetchCurrencies: fetchCurrencies
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,8 @@ var FormControl = ReactBootstrap.FormControl;
 | 
				
			|||||||
var ControlLabel = ReactBootstrap.ControlLabel;
 | 
					var ControlLabel = ReactBootstrap.ControlLabel;
 | 
				
			||||||
var Col = ReactBootstrap.Col;
 | 
					var Col = ReactBootstrap.Col;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var Combobox = require('react-widgets').Combobox;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var models = require('../models');
 | 
					var models = require('../models');
 | 
				
			||||||
var User = models.User;
 | 
					var User = models.User;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -22,6 +24,7 @@ class AccountSettingsModal extends React.Component {
 | 
				
			|||||||
			name: props ? props.user.Name: "",
 | 
								name: props ? props.user.Name: "",
 | 
				
			||||||
			username: props ? props.user.Username : "",
 | 
								username: props ? props.user.Username : "",
 | 
				
			||||||
			email: props ? props.user.Email : "",
 | 
								email: props ? props.user.Email : "",
 | 
				
			||||||
 | 
								defaultCurrency: props ? props.user.DefaultCurrency : "",
 | 
				
			||||||
			password: models.BogusPassword,
 | 
								password: models.BogusPassword,
 | 
				
			||||||
			confirm_password: models.BogusPassword,
 | 
								confirm_password: models.BogusPassword,
 | 
				
			||||||
			passwordChanged: false,
 | 
								passwordChanged: false,
 | 
				
			||||||
@@ -33,6 +36,7 @@ class AccountSettingsModal extends React.Component {
 | 
				
			|||||||
		this.state = this._getInitialState();
 | 
							this.state = this._getInitialState();
 | 
				
			||||||
		this.onCancel = this.handleCancel.bind(this);
 | 
							this.onCancel = this.handleCancel.bind(this);
 | 
				
			||||||
		this.onChange = this.handleChange.bind(this);
 | 
							this.onChange = this.handleChange.bind(this);
 | 
				
			||||||
 | 
							this.onSelectCurrency = this.handleSelectCurrency.bind(this);
 | 
				
			||||||
		this.onSubmit = this.handleSubmit.bind(this);
 | 
							this.onSubmit = this.handleSubmit.bind(this);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	componentWillReceiveProps(nextProps) {
 | 
						componentWillReceiveProps(nextProps) {
 | 
				
			||||||
@@ -73,6 +77,13 @@ class AccountSettingsModal extends React.Component {
 | 
				
			|||||||
			confirm_password: ReactDOM.findDOMNode(this.refs.confirm_password).value
 | 
								confirm_password: ReactDOM.findDOMNode(this.refs.confirm_password).value
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						handleSelectCurrency(security) {
 | 
				
			||||||
 | 
							if (security.hasOwnProperty('SecurityId')) {
 | 
				
			||||||
 | 
								this.setState({
 | 
				
			||||||
 | 
									defaultCurrency: security.SecurityId
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	handleSubmit(e) {
 | 
						handleSubmit(e) {
 | 
				
			||||||
		var u = new User();
 | 
							var u = new User();
 | 
				
			||||||
		e.preventDefault();
 | 
							e.preventDefault();
 | 
				
			||||||
@@ -81,6 +92,7 @@ class AccountSettingsModal extends React.Component {
 | 
				
			|||||||
		u.Name = this.state.name;
 | 
							u.Name = this.state.name;
 | 
				
			||||||
		u.Username = this.state.username;
 | 
							u.Username = this.state.username;
 | 
				
			||||||
		u.Email = this.state.email;
 | 
							u.Email = this.state.email;
 | 
				
			||||||
 | 
							u.DefaultCurrency = this.state.defaultCurrency;
 | 
				
			||||||
		if (this.state.passwordChanged) {
 | 
							if (this.state.passwordChanged) {
 | 
				
			||||||
			u.Password = this.state.password;
 | 
								u.Password = this.state.password;
 | 
				
			||||||
			if (u.Password != this.state.confirm_password) {
 | 
								if (u.Password != this.state.confirm_password) {
 | 
				
			||||||
@@ -130,6 +142,20 @@ class AccountSettingsModal extends React.Component {
 | 
				
			|||||||
							ref="email"/>
 | 
												ref="email"/>
 | 
				
			||||||
						</Col>
 | 
											</Col>
 | 
				
			||||||
					</FormGroup>
 | 
										</FormGroup>
 | 
				
			||||||
 | 
										<FormGroup>
 | 
				
			||||||
 | 
											<Col componentClass={ControlLabel} xs={2}>Default Currency</Col>
 | 
				
			||||||
 | 
											<Col xs={10}>
 | 
				
			||||||
 | 
											<Combobox
 | 
				
			||||||
 | 
												data={this.props.currencies}
 | 
				
			||||||
 | 
												valueField='SecurityId'
 | 
				
			||||||
 | 
												textField={item => item == undefined || typeof item === 'string' ? item : item.Name + " - " + item.Description}
 | 
				
			||||||
 | 
												defaultValue={this.state.defaultCurrency}
 | 
				
			||||||
 | 
												onChange={this.onSelectCurrency}
 | 
				
			||||||
 | 
												suggest
 | 
				
			||||||
 | 
												filter='contains'
 | 
				
			||||||
 | 
												ref="security" />
 | 
				
			||||||
 | 
											</Col>
 | 
				
			||||||
 | 
										</FormGroup>
 | 
				
			||||||
					<FormGroup validationState={this.passwordValidationState()}>
 | 
										<FormGroup validationState={this.passwordValidationState()}>
 | 
				
			||||||
						<Col componentClass={ControlLabel} xs={2}>Password</Col>
 | 
											<Col componentClass={ControlLabel} xs={2}>Password</Col>
 | 
				
			||||||
						<Col xs={10}>
 | 
											<Col xs={10}>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,6 +27,7 @@ class MoneyGoApp extends React.Component {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	componentDidMount() {
 | 
						componentDidMount() {
 | 
				
			||||||
		this.props.tryResumingSession();
 | 
							this.props.tryResumingSession();
 | 
				
			||||||
 | 
							this.props.fetchCurrencies();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	handleShowSettings() {
 | 
						handleShowSettings() {
 | 
				
			||||||
		this.setState({showAccountSettingsModal: true});
 | 
							this.setState({showAccountSettingsModal: true});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,8 @@ var Col = ReactBootstrap.Col;
 | 
				
			|||||||
var Button = ReactBootstrap.Button;
 | 
					var Button = ReactBootstrap.Button;
 | 
				
			||||||
var ButtonGroup = ReactBootstrap.ButtonGroup;
 | 
					var ButtonGroup = ReactBootstrap.ButtonGroup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var Combobox = require('react-widgets').Combobox;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var models = require('../models');
 | 
					var models = require('../models');
 | 
				
			||||||
var User = models.User;
 | 
					var User = models.User;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -22,6 +24,7 @@ class NewUserModal extends React.Component {
 | 
				
			|||||||
			name: "",
 | 
								name: "",
 | 
				
			||||||
			username: "",
 | 
								username: "",
 | 
				
			||||||
			email: "",
 | 
								email: "",
 | 
				
			||||||
 | 
								defaultCurrency: '840', // ISO4217 code for USD
 | 
				
			||||||
			password: "",
 | 
								password: "",
 | 
				
			||||||
			confirm_password: "",
 | 
								confirm_password: "",
 | 
				
			||||||
			passwordChanged: false,
 | 
								passwordChanged: false,
 | 
				
			||||||
@@ -29,6 +32,7 @@ class NewUserModal extends React.Component {
 | 
				
			|||||||
		};
 | 
							};
 | 
				
			||||||
		this.onCancel = this.handleCancel.bind(this);
 | 
							this.onCancel = this.handleCancel.bind(this);
 | 
				
			||||||
		this.onChange = this.handleChange.bind(this);
 | 
							this.onChange = this.handleChange.bind(this);
 | 
				
			||||||
 | 
							this.onSelectCurrency = this.handleSelectCurrency.bind(this);
 | 
				
			||||||
		this.onSubmit = this.handleSubmit.bind(this);
 | 
							this.onSubmit = this.handleSubmit.bind(this);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	passwordValidationState() {
 | 
						passwordValidationState() {
 | 
				
			||||||
@@ -64,6 +68,13 @@ class NewUserModal extends React.Component {
 | 
				
			|||||||
			confirm_password: ReactDOM.findDOMNode(this.refs.confirm_password).value
 | 
								confirm_password: ReactDOM.findDOMNode(this.refs.confirm_password).value
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						handleSelectCurrency(security) {
 | 
				
			||||||
 | 
							if (security.hasOwnProperty('SecurityId')) {
 | 
				
			||||||
 | 
								this.setState({
 | 
				
			||||||
 | 
									defaultCurrency: security.AlternateId
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	handleSubmit(e) {
 | 
						handleSubmit(e) {
 | 
				
			||||||
		var u = new User();
 | 
							var u = new User();
 | 
				
			||||||
		var error = "";
 | 
							var error = "";
 | 
				
			||||||
@@ -72,6 +83,7 @@ class NewUserModal extends React.Component {
 | 
				
			|||||||
		u.Name = this.state.name;
 | 
							u.Name = this.state.name;
 | 
				
			||||||
		u.Username = this.state.username;
 | 
							u.Username = this.state.username;
 | 
				
			||||||
		u.Email = this.state.email;
 | 
							u.Email = this.state.email;
 | 
				
			||||||
 | 
							u.DefaultCurrency = Number.parseInt(this.state.defaultCurrency);
 | 
				
			||||||
		u.Password = this.state.password;
 | 
							u.Password = this.state.password;
 | 
				
			||||||
		if (u.Password != this.state.confirm_password) {
 | 
							if (u.Password != this.state.confirm_password) {
 | 
				
			||||||
			this.setState({error: "Error: passwords do not match"});
 | 
								this.setState({error: "Error: passwords do not match"});
 | 
				
			||||||
@@ -118,6 +130,20 @@ class NewUserModal extends React.Component {
 | 
				
			|||||||
							ref="email"/>
 | 
												ref="email"/>
 | 
				
			||||||
						</Col>
 | 
											</Col>
 | 
				
			||||||
					</FormGroup>
 | 
										</FormGroup>
 | 
				
			||||||
 | 
										<FormGroup>
 | 
				
			||||||
 | 
											<Col componentClass={ControlLabel} xs={2}>Default Currency</Col>
 | 
				
			||||||
 | 
											<Col xs={10}>
 | 
				
			||||||
 | 
											<Combobox
 | 
				
			||||||
 | 
												data={this.props.currencies}
 | 
				
			||||||
 | 
												valueField='AlternateId'
 | 
				
			||||||
 | 
												textField={item => typeof item === 'string' ? item : item.Name + " - " + item.Description}
 | 
				
			||||||
 | 
												defaultValue={this.state.defaultCurrency}
 | 
				
			||||||
 | 
												onChange={this.onSelectCurrency}
 | 
				
			||||||
 | 
												suggest
 | 
				
			||||||
 | 
												filter='contains'
 | 
				
			||||||
 | 
												ref="security" />
 | 
				
			||||||
 | 
											</Col>
 | 
				
			||||||
 | 
										</FormGroup>
 | 
				
			||||||
					<FormGroup validationState={this.passwordValidationState()}>
 | 
										<FormGroup validationState={this.passwordValidationState()}>
 | 
				
			||||||
						<Col componentClass={ControlLabel} xs={2}>Password</Col>
 | 
											<Col componentClass={ControlLabel} xs={2}>Password</Col>
 | 
				
			||||||
						<Col xs={10}>
 | 
											<Col xs={10}>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,8 @@
 | 
				
			|||||||
var keyMirror = require('keymirror');
 | 
					var keyMirror = require('keymirror');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = keyMirror({
 | 
					module.exports = keyMirror({
 | 
				
			||||||
 | 
						FETCH_CURRENCIES: null,
 | 
				
			||||||
 | 
						CURRENCIES_FETCHED: null,
 | 
				
			||||||
	SEARCH_SECURITY_TEMPLATES: null,
 | 
						SEARCH_SECURITY_TEMPLATES: null,
 | 
				
			||||||
	SECURITY_TEMPLATES_SEARCHED: null
 | 
						SECURITY_TEMPLATES_SEARCHED: null
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,13 @@
 | 
				
			|||||||
var connect = require('react-redux').connect;
 | 
					var connect = require('react-redux').connect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var UserActions = require('../actions/UserActions');
 | 
					var UserActions = require('../actions/UserActions');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var AccountSettingsModal = require('../components/AccountSettingsModal');
 | 
					var AccountSettingsModal = require('../components/AccountSettingsModal');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function mapStateToProps(state) {
 | 
					function mapStateToProps(state) {
 | 
				
			||||||
	return {
 | 
						return {
 | 
				
			||||||
		user: state.user
 | 
							user: state.user,
 | 
				
			||||||
 | 
							currencies: state.securities.currency_list
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
var connect = require('react-redux').connect;
 | 
					var connect = require('react-redux').connect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var UserActions = require('../actions/UserActions');
 | 
					var UserActions = require('../actions/UserActions');
 | 
				
			||||||
 | 
					var SecurityTemplateActions = require('../actions/SecurityTemplateActions');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var MoneyGoApp = require('../components/MoneyGoApp');
 | 
					var MoneyGoApp = require('../components/MoneyGoApp');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -13,6 +14,7 @@ function mapStateToProps(state) {
 | 
				
			|||||||
function mapDispatchToProps(dispatch) {
 | 
					function mapDispatchToProps(dispatch) {
 | 
				
			||||||
	return {
 | 
						return {
 | 
				
			||||||
		tryResumingSession: function() {dispatch(UserActions.tryResumingSession())},
 | 
							tryResumingSession: function() {dispatch(UserActions.tryResumingSession())},
 | 
				
			||||||
 | 
							fetchCurrencies: function() {dispatch(SecurityTemplateActions.fetchCurrencies())},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,9 @@ var UserActions = require('../actions/UserActions');
 | 
				
			|||||||
var NewUserModal = require('../components/NewUserModal');
 | 
					var NewUserModal = require('../components/NewUserModal');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function mapStateToProps(state) {
 | 
					function mapStateToProps(state) {
 | 
				
			||||||
	return {}
 | 
						return {
 | 
				
			||||||
 | 
							currencies: state.securityTemplates.currencies
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function mapDispatchToProps(dispatch) {
 | 
					function mapDispatchToProps(dispatch) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,6 +13,7 @@ function getJSONObj(json_input) {
 | 
				
			|||||||
class User {
 | 
					class User {
 | 
				
			||||||
	constructor() {
 | 
						constructor() {
 | 
				
			||||||
		this.UserId = -1;
 | 
							this.UserId = -1;
 | 
				
			||||||
 | 
							this.DefaultCurrency = -1;
 | 
				
			||||||
		this.Name = "";
 | 
							this.Name = "";
 | 
				
			||||||
		this.Username = "";
 | 
							this.Username = "";
 | 
				
			||||||
		this.Password = "";
 | 
							this.Password = "";
 | 
				
			||||||
@@ -21,6 +22,7 @@ class User {
 | 
				
			|||||||
	toJSON() {
 | 
						toJSON() {
 | 
				
			||||||
		var json_obj = {};
 | 
							var json_obj = {};
 | 
				
			||||||
		json_obj.UserId = this.UserId;
 | 
							json_obj.UserId = this.UserId;
 | 
				
			||||||
 | 
							json_obj.DefaultCurrency = this.DefaultCurrency;
 | 
				
			||||||
		json_obj.Name = this.Name;
 | 
							json_obj.Name = this.Name;
 | 
				
			||||||
		json_obj.Username = this.Username;
 | 
							json_obj.Username = this.Username;
 | 
				
			||||||
		json_obj.Password = this.Password;
 | 
							json_obj.Password = this.Password;
 | 
				
			||||||
@@ -32,6 +34,8 @@ class User {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		if (json_obj.hasOwnProperty("UserId"))
 | 
							if (json_obj.hasOwnProperty("UserId"))
 | 
				
			||||||
			this.UserId = json_obj.UserId;
 | 
								this.UserId = json_obj.UserId;
 | 
				
			||||||
 | 
							if (json_obj.hasOwnProperty("DefaultCurrency"))
 | 
				
			||||||
 | 
								this.DefaultCurrency = json_obj.DefaultCurrency;
 | 
				
			||||||
		if (json_obj.hasOwnProperty("Name"))
 | 
							if (json_obj.hasOwnProperty("Name"))
 | 
				
			||||||
			this.Name = json_obj.Name;
 | 
								this.Name = json_obj.Name;
 | 
				
			||||||
		if (json_obj.hasOwnProperty("Username"))
 | 
							if (json_obj.hasOwnProperty("Username"))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,30 +3,37 @@ var assign = require('object-assign');
 | 
				
			|||||||
var SecurityTemplateConstants = require('../constants/SecurityTemplateConstants');
 | 
					var SecurityTemplateConstants = require('../constants/SecurityTemplateConstants');
 | 
				
			||||||
var UserConstants = require('../constants/UserConstants');
 | 
					var UserConstants = require('../constants/UserConstants');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var SecurityType = require('../models').SecurityType;
 | 
					const initialState = {
 | 
				
			||||||
 | 
						search: "",
 | 
				
			||||||
 | 
						type: 0,
 | 
				
			||||||
 | 
						templates: [],
 | 
				
			||||||
 | 
						currencies: []
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = function(state = {search: "", type: 0, templates: [], searchNumber: 0}, action) {
 | 
					module.exports = function(state = initialState, action) {
 | 
				
			||||||
	switch (action.type) {
 | 
						switch (action.type) {
 | 
				
			||||||
		case SecurityTemplateConstants.SEARCH_SECURITY_TEMPLATES:
 | 
							case SecurityTemplateConstants.SEARCH_SECURITY_TEMPLATES:
 | 
				
			||||||
			return {
 | 
								return assign({}, state, {
 | 
				
			||||||
				search: action.searchString,
 | 
									search: action.searchString,
 | 
				
			||||||
				type: action.searchType,
 | 
									type: action.searchType,
 | 
				
			||||||
				templates: []
 | 
									templates: []
 | 
				
			||||||
			};
 | 
								});
 | 
				
			||||||
		case SecurityTemplateConstants.SECURITY_TEMPLATES_SEARCHED:
 | 
							case SecurityTemplateConstants.SECURITY_TEMPLATES_SEARCHED:
 | 
				
			||||||
			if ((action.searchString != state.search) || (action.searchType != state.type))
 | 
								if ((action.searchString != state.search) || (action.searchType != state.type))
 | 
				
			||||||
				return state;
 | 
									return state;
 | 
				
			||||||
			return {
 | 
								return assign({}, state, {
 | 
				
			||||||
				search: action.searchString,
 | 
									search: action.searchString,
 | 
				
			||||||
				type: action.searchType,
 | 
									type: action.searchType,
 | 
				
			||||||
				templates: action.securities
 | 
									templates: action.securities
 | 
				
			||||||
			};
 | 
								});
 | 
				
			||||||
 | 
							case SecurityTemplateConstants.CURRENCIES_FETCHED:
 | 
				
			||||||
 | 
								return assign({}, state, {
 | 
				
			||||||
 | 
									currencies: action.currencies
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
		case UserConstants.USER_LOGGEDOUT:
 | 
							case UserConstants.USER_LOGGEDOUT:
 | 
				
			||||||
			return {
 | 
								return assign({}, initialState, {
 | 
				
			||||||
				search: "",
 | 
									currencies: state.currencies
 | 
				
			||||||
				type: 0,
 | 
								});
 | 
				
			||||||
				templates: []
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			return state;
 | 
								return state;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,7 +36,7 @@ type Security struct {
 | 
				
			|||||||
	// security is precise to
 | 
						// security is precise to
 | 
				
			||||||
	Precision int
 | 
						Precision int
 | 
				
			||||||
	Type      int64
 | 
						Type      int64
 | 
				
			||||||
	// AlternateId is CUSIP for Type=Stock
 | 
						// AlternateId is CUSIP for Type=Stock, ISO4217 for Type=Currency
 | 
				
			||||||
	AlternateId string
 | 
						AlternateId string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -86,6 +86,16 @@ func FindSecurityTemplate(name string, _type int64) *Security {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func FindCurrencyTemplate(iso4217 int64) *Security {
 | 
				
			||||||
 | 
						iso4217string := strconv.FormatInt(iso4217, 10)
 | 
				
			||||||
 | 
						for _, security := range SecurityTemplates {
 | 
				
			||||||
 | 
							if security.Type == Currency && security.AlternateId == iso4217string {
 | 
				
			||||||
 | 
								return &security
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetSecurity(securityid int64, userid int64) (*Security, error) {
 | 
					func GetSecurity(securityid int64, userid int64) (*Security, error) {
 | 
				
			||||||
	var s Security
 | 
						var s Security
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -171,6 +181,15 @@ func DeleteSecurity(s *Security) error {
 | 
				
			|||||||
		return errors.New("One or more accounts still use this security")
 | 
							return errors.New("One or more accounts still use this security")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						user, err := GetUserTx(transaction, s.UserId)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							transaction.Rollback()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						} else if user.DefaultCurrency == s.SecurityId {
 | 
				
			||||||
 | 
							transaction.Rollback()
 | 
				
			||||||
 | 
							return errors.New("Cannot delete security which is user's default currency")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	count, err := transaction.Delete(s)
 | 
						count, err := transaction.Delete(s)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		transaction.Rollback()
 | 
							transaction.Rollback()
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										93
									
								
								users.go
									
									
									
									
									
								
							
							
						
						
									
										93
									
								
								users.go
									
									
									
									
									
								
							@@ -3,7 +3,9 @@ package main
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"crypto/sha256"
 | 
						"crypto/sha256"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"gopkg.in/gorp.v1"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
@@ -11,12 +13,13 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type User struct {
 | 
					type User struct {
 | 
				
			||||||
	UserId       int64
 | 
						UserId          int64
 | 
				
			||||||
	Name         string
 | 
						DefaultCurrency int64 // SecurityId of default currency, or ISO4217 code for it if creating new user
 | 
				
			||||||
	Username     string
 | 
						Name            string
 | 
				
			||||||
	Password     string `db:"-"`
 | 
						Username        string
 | 
				
			||||||
	PasswordHash string `json:"-"`
 | 
						Password        string `db:"-"`
 | 
				
			||||||
	Email        string
 | 
						PasswordHash    string `json:"-"`
 | 
				
			||||||
 | 
						Email           string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const BogusPassword = "password"
 | 
					const BogusPassword = "password"
 | 
				
			||||||
@@ -54,6 +57,16 @@ func GetUser(userid int64) (*User, error) {
 | 
				
			|||||||
	return &u, nil
 | 
						return &u, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GetUserTx(transaction *gorp.Transaction, userid int64) (*User, error) {
 | 
				
			||||||
 | 
						var u User
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err := transaction.SelectOne(&u, "SELECT * from users where UserId=?", userid)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &u, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetUserByUsername(username string) (*User, error) {
 | 
					func GetUserByUsername(username string) (*User, error) {
 | 
				
			||||||
	var u User
 | 
						var u User
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -70,6 +83,12 @@ func InsertUser(u *User) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						security_template := FindCurrencyTemplate(u.DefaultCurrency)
 | 
				
			||||||
 | 
						if security_template == nil {
 | 
				
			||||||
 | 
							transaction.Rollback()
 | 
				
			||||||
 | 
							return errors.New("Invalid ISO4217 Default Currency")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	existing, err := transaction.SelectInt("SELECT count(*) from users where Username=?", u.Username)
 | 
						existing, err := transaction.SelectInt("SELECT count(*) from users where Username=?", u.Username)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		transaction.Rollback()
 | 
							transaction.Rollback()
 | 
				
			||||||
@@ -86,6 +105,28 @@ func InsertUser(u *User) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Copy the security template and give it our new UserId
 | 
				
			||||||
 | 
						var security Security
 | 
				
			||||||
 | 
						security = *security_template
 | 
				
			||||||
 | 
						security.UserId = u.UserId
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = InsertSecurityTx(transaction, &security)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							transaction.Rollback()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Update the user's DefaultCurrency to our new SecurityId
 | 
				
			||||||
 | 
						u.DefaultCurrency = security.SecurityId
 | 
				
			||||||
 | 
						count, err := transaction.Update(u)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							transaction.Rollback()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						} else if count != 1 {
 | 
				
			||||||
 | 
							transaction.Rollback()
 | 
				
			||||||
 | 
							return errors.New("Would have updated more than one user")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = transaction.Commit()
 | 
						err = transaction.Commit()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		transaction.Rollback()
 | 
							transaction.Rollback()
 | 
				
			||||||
@@ -103,6 +144,42 @@ func GetUserFromSession(r *http.Request) (*User, error) {
 | 
				
			|||||||
	return GetUser(s.UserId)
 | 
						return GetUser(s.UserId)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func UpdateUser(u *User) error {
 | 
				
			||||||
 | 
						transaction, err := DB.Begin()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						security, err := GetSecurityTx(transaction, u.DefaultCurrency, u.UserId)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							transaction.Rollback()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						} else if security.UserId != u.UserId || security.SecurityId != u.DefaultCurrency {
 | 
				
			||||||
 | 
							transaction.Rollback()
 | 
				
			||||||
 | 
							return errors.New("UserId and DefaultCurrency don't match the fetched security")
 | 
				
			||||||
 | 
						} else if security.Type != Currency {
 | 
				
			||||||
 | 
							transaction.Rollback()
 | 
				
			||||||
 | 
							return errors.New("New DefaultCurrency security is not a currency")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						count, err := transaction.Update(u)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							transaction.Rollback()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						} else if count != 1 {
 | 
				
			||||||
 | 
							transaction.Rollback()
 | 
				
			||||||
 | 
							return errors.New("Would have updated more than one user")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = transaction.Commit()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							transaction.Rollback()
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func UserHandler(w http.ResponseWriter, r *http.Request) {
 | 
					func UserHandler(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
	if r.Method == "POST" {
 | 
						if r.Method == "POST" {
 | 
				
			||||||
		user_json := r.PostFormValue("user")
 | 
							user_json := r.PostFormValue("user")
 | 
				
			||||||
@@ -187,8 +264,8 @@ func UserHandler(w http.ResponseWriter, r *http.Request) {
 | 
				
			|||||||
				user.PasswordHash = old_pwhash
 | 
									user.PasswordHash = old_pwhash
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			count, err := DB.Update(user)
 | 
								err = UpdateUser(user)
 | 
				
			||||||
			if count != 1 || err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				WriteError(w, 999 /*Internal Error*/)
 | 
									WriteError(w, 999 /*Internal Error*/)
 | 
				
			||||||
				log.Print(err)
 | 
									log.Print(err)
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user