mirror of
				https://github.com/aclindsa/moneygo.git
				synced 2025-10-31 01:43:26 -04:00 
			
		
		
		
	Reduxify CRUD actions for transactions
This commit is contained in:
		
							
								
								
									
										219
									
								
								js/actions/TransactionActions.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								js/actions/TransactionActions.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,219 @@ | |||||||
|  | var TransactionConstants = require('../constants/TransactionConstants'); | ||||||
|  |  | ||||||
|  | var ErrorActions = require('./ErrorActions'); | ||||||
|  |  | ||||||
|  | var models = require('../models.js'); | ||||||
|  | var Account = models.Account; | ||||||
|  | var Transaction = models.Transaction; | ||||||
|  | var Error = models.Error; | ||||||
|  |  | ||||||
|  | var Big = require('big.js'); | ||||||
|  |  | ||||||
|  | function fetchTransactionPage(account, pageSize, page) { | ||||||
|  | 	return { | ||||||
|  | 		type: TransactionConstants.FETCH_TRANSACTION_PAGE, | ||||||
|  | 		account: account, | ||||||
|  | 		pageSize: pageSize, | ||||||
|  | 		page: page | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function transactionPageFetched(account, pageSize, page, numPages, | ||||||
|  | 		transactions, endingBalance) { | ||||||
|  | 	return { | ||||||
|  | 		type: TransactionConstants.TRANSACTION_PAGE_FETCHED, | ||||||
|  | 		account: account, | ||||||
|  | 		pageSize: pageSize, | ||||||
|  | 		page: page, | ||||||
|  | 		numPages: numPages, | ||||||
|  | 		transactions: transactions, | ||||||
|  | 		endingBalance: endingBalance | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function createTransaction() { | ||||||
|  | 	return { | ||||||
|  | 		type: TransactionConstants.CREATE_TRANSACTION | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function transactionCreated(transaction) { | ||||||
|  | 	return { | ||||||
|  | 		type: TransactionConstants.TRANSACTION_CREATED, | ||||||
|  | 		transaction: transaction | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function updateTransaction() { | ||||||
|  | 	return { | ||||||
|  | 		type: TransactionConstants.UPDATE_TRANSACTION | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function transactionUpdated(transaction) { | ||||||
|  | 	return { | ||||||
|  | 		type: TransactionConstants.TRANSACTION_UPDATED, | ||||||
|  | 		transaction: transaction | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function removeTransaction() { | ||||||
|  | 	return { | ||||||
|  | 		type: TransactionConstants.REMOVE_TRANSACTION | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function transactionRemoved(transactionId) { | ||||||
|  | 	return { | ||||||
|  | 		type: TransactionConstants.TRANSACTION_REMOVED, | ||||||
|  | 		transactionId: transactionId | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function transactionSelected(transactionId) { | ||||||
|  | 	return { | ||||||
|  | 		type: TransactionConstants.TRANSACTION_SELECTED, | ||||||
|  | 		transactionId: transactionId | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function selectionCleared() { | ||||||
|  | 	return { | ||||||
|  | 		type: TransactionConstants.SELECTION_CLEARED | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function fetchPage(account, pageSize, page) { | ||||||
|  | 	return function (dispatch) { | ||||||
|  | 		dispatch(fetchTransactionPage(account, pageSize, page)); | ||||||
|  |  | ||||||
|  | 		$.ajax({ | ||||||
|  | 			type: "GET", | ||||||
|  | 			dataType: "json", | ||||||
|  | 			url: "account/"+account.AccountId+"/transactions?sort=date-desc&limit="+pageSize+"&page="+page, | ||||||
|  | 			success: function(data, status, jqXHR) { | ||||||
|  | 				var e = new Error(); | ||||||
|  | 				e.fromJSON(data); | ||||||
|  | 				if (e.isError()) { | ||||||
|  | 					dispatch(ErrorActions.serverError(e)); | ||||||
|  | 					return; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				var transactions = []; | ||||||
|  | 				var balance = new Big(data.EndingBalance); | ||||||
|  |  | ||||||
|  | 				for (var i = 0; i < data.Transactions.length; i++) { | ||||||
|  | 					var t = new Transaction(); | ||||||
|  | 					t.fromJSON(data.Transactions[i]); | ||||||
|  |  | ||||||
|  | 					t.Balance = balance.plus(0); // Make a copy of the current balance | ||||||
|  | 					// Keep a talley of the running balance of these transactions | ||||||
|  | 					for (var j = 0; j < data.Transactions[i].Splits.length; j++) { | ||||||
|  | 						var split = data.Transactions[i].Splits[j]; | ||||||
|  | 						if (account.AccountId == split.AccountId) { | ||||||
|  | 							balance = balance.minus(split.Amount); | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 					transactions.push(t); | ||||||
|  | 				} | ||||||
|  | 				var a = new Account(); | ||||||
|  | 				a.fromJSON(data.Account); | ||||||
|  |  | ||||||
|  | 				var numPages = Math.ceil(data.TotalTransactions / pageSize); | ||||||
|  |  | ||||||
|  | 				dispatch(transactionPageFetched(account, pageSize, page, | ||||||
|  | 					numPages, transactions, new Big(data.EndingBalance))); | ||||||
|  | 			}, | ||||||
|  | 			error: function(jqXHR, status, error) { | ||||||
|  | 				dispatch(ErrorActions.ajaxError(error)); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function create(transaction) { | ||||||
|  | 	return function (dispatch) { | ||||||
|  | 		dispatch(createTransaction()); | ||||||
|  |  | ||||||
|  | 		$.ajax({ | ||||||
|  | 			type: "POST", | ||||||
|  | 			dataType: "json", | ||||||
|  | 			url: "transaction/", | ||||||
|  | 			data: {transaction: transaction.toJSON()}, | ||||||
|  | 			success: function(data, status, jqXHR) { | ||||||
|  | 				var e = new Error(); | ||||||
|  | 				e.fromJSON(data); | ||||||
|  | 				if (e.isError()) { | ||||||
|  | 					dispatch(ErrorActions.serverError(e)); | ||||||
|  | 				} else { | ||||||
|  | 					var t = new Transaction(); | ||||||
|  | 					t.fromJSON(data); | ||||||
|  | 					dispatch(transactionCreated(t)); | ||||||
|  | 				} | ||||||
|  | 			}, | ||||||
|  | 			error: function(jqXHR, status, error) { | ||||||
|  | 				dispatch(ErrorActions.ajaxError(error)); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function update(transaction) { | ||||||
|  | 	return function (dispatch) { | ||||||
|  | 		dispatch(updateTransaction()); | ||||||
|  |  | ||||||
|  | 		$.ajax({ | ||||||
|  | 			type: "PUT", | ||||||
|  | 			dataType: "json", | ||||||
|  | 			url: "transaction/"+transaction.TransactionId+"/", | ||||||
|  | 			data: {transaction: transaction.toJSON()}, | ||||||
|  | 			success: function(data, status, jqXHR) { | ||||||
|  | 				var e = new Error(); | ||||||
|  | 				e.fromJSON(data); | ||||||
|  | 				if (e.isError()) { | ||||||
|  | 					dispatch(ErrorActions.serverError(e)); | ||||||
|  | 				} else { | ||||||
|  | 					var t = new Transaction(); | ||||||
|  | 					t.fromJSON(data); | ||||||
|  | 					dispatch(transactionUpdated(t)); | ||||||
|  | 				} | ||||||
|  | 			}, | ||||||
|  | 			error: function(jqXHR, status, error) { | ||||||
|  | 				dispatch(ErrorActions.ajaxError(error)); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function remove(transaction) { | ||||||
|  | 	return function(dispatch) { | ||||||
|  | 		dispatch(removeTransaction()); | ||||||
|  |  | ||||||
|  | 		$.ajax({ | ||||||
|  | 			type: "DELETE", | ||||||
|  | 			dataType: "json", | ||||||
|  | 			url: "transaction/"+transaction.TransactionId+"/", | ||||||
|  | 			success: function(data, status, jqXHR) { | ||||||
|  | 				var e = new Error(); | ||||||
|  | 				e.fromJSON(data); | ||||||
|  | 				if (e.isError()) { | ||||||
|  | 					dispatch(ErrorActions.serverError(e)); | ||||||
|  | 				} else { | ||||||
|  | 					dispatch(transactionRemoved(transaction.TransactionId)); | ||||||
|  | 				} | ||||||
|  | 			}, | ||||||
|  | 			error: function(jqXHR, status, error) { | ||||||
|  | 				dispatch(ErrorActions.ajaxError(error)); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = { | ||||||
|  | 	fetchPage: fetchPage, | ||||||
|  | 	create: create, | ||||||
|  | 	update: update, | ||||||
|  | 	remove: remove, | ||||||
|  | 	select: transactionSelected, | ||||||
|  | 	unselect: selectionCleared | ||||||
|  | }; | ||||||
| @@ -1,84 +0,0 @@ | |||||||
| var TransactionPageConstants = require('../constants/TransactionPageConstants'); |  | ||||||
|  |  | ||||||
| var ErrorActions = require('./ErrorActions'); |  | ||||||
|  |  | ||||||
| var models = require('../models.js'); |  | ||||||
| var Account = models.Account; |  | ||||||
| var Transaction = models.Transaction; |  | ||||||
| var Error = models.Error; |  | ||||||
|  |  | ||||||
| var Big = require('big.js'); |  | ||||||
|  |  | ||||||
| function fetchTransactionPage(account, pageSize, page) { |  | ||||||
| 	return { |  | ||||||
| 		type: TransactionPageConstants.FETCH_TRANSACTION_PAGE, |  | ||||||
| 		account: account, |  | ||||||
| 		pageSize: pageSize, |  | ||||||
| 		page: page |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function transactionPageFetched(account, pageSize, page, numPages, |  | ||||||
| 		transactions, endingBalance) { |  | ||||||
| 	return { |  | ||||||
| 		type: TransactionPageConstants.TRANSACTION_PAGE_FETCHED, |  | ||||||
| 		account: account, |  | ||||||
| 		pageSize: pageSize, |  | ||||||
| 		page: page, |  | ||||||
| 		numPages: numPages, |  | ||||||
| 		transactions: transactions, |  | ||||||
| 		endingBalance: endingBalance |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function fetch(account, pageSize, page) { |  | ||||||
| 	return function (dispatch) { |  | ||||||
| 		dispatch(fetchTransactionPage(account, pageSize, page)); |  | ||||||
|  |  | ||||||
| 		$.ajax({ |  | ||||||
| 			type: "GET", |  | ||||||
| 			dataType: "json", |  | ||||||
| 			url: "account/"+account.AccountId+"/transactions?sort=date-desc&limit="+pageSize+"&page="+page, |  | ||||||
| 			success: function(data, status, jqXHR) { |  | ||||||
| 				var e = new Error(); |  | ||||||
| 				e.fromJSON(data); |  | ||||||
| 				if (e.isError()) { |  | ||||||
| 					dispatch(ErrorActions.serverError(e)); |  | ||||||
| 					return; |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				var transactions = []; |  | ||||||
| 				var balance = new Big(data.EndingBalance); |  | ||||||
|  |  | ||||||
| 				for (var i = 0; i < data.Transactions.length; i++) { |  | ||||||
| 					var t = new Transaction(); |  | ||||||
| 					t.fromJSON(data.Transactions[i]); |  | ||||||
|  |  | ||||||
| 					t.Balance = balance.plus(0); // Make a copy of the current balance |  | ||||||
| 					// Keep a talley of the running balance of these transactions |  | ||||||
| 					for (var j = 0; j < data.Transactions[i].Splits.length; j++) { |  | ||||||
| 						var split = data.Transactions[i].Splits[j]; |  | ||||||
| 						if (account.AccountId == split.AccountId) { |  | ||||||
| 							balance = balance.minus(split.Amount); |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 					transactions.push(t); |  | ||||||
| 				} |  | ||||||
| 				var a = new Account(); |  | ||||||
| 				a.fromJSON(data.Account); |  | ||||||
|  |  | ||||||
| 				var numPages = Math.ceil(data.TotalTransactions / pageSize); |  | ||||||
|  |  | ||||||
| 				dispatch(transactionPageFetched(account, pageSize, page, |  | ||||||
| 					numPages, transactions, new Big(data.EndingBalance))); |  | ||||||
| 			}, |  | ||||||
| 			error: function(jqXHR, status, error) { |  | ||||||
| 				dispatch(ErrorActions.ajaxError(error)); |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
| 	}; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| module.exports = { |  | ||||||
| 	fetch: fetch |  | ||||||
| }; |  | ||||||
| @@ -51,7 +51,7 @@ const TransactionRow = React.createClass({ | |||||||
| 		const refs = ["date", "number", "description", "account", "status", "amount"]; | 		const refs = ["date", "number", "description", "account", "status", "amount"]; | ||||||
| 		for (var ref in refs) { | 		for (var ref in refs) { | ||||||
| 			if (this.refs[refs[ref]] == e.target) { | 			if (this.refs[refs[ref]] == e.target) { | ||||||
| 				this.props.onEdit(this.props.transaction, refs[ref]); | 				this.props.onSelect(this.props.transaction.TransactionId, refs[ref]); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -63,6 +63,7 @@ const TransactionRow = React.createClass({ | |||||||
| 		var accountName = ""; | 		var accountName = ""; | ||||||
| 		var status = ""; | 		var status = ""; | ||||||
| 		var security = this.props.securities[this.props.account.SecurityId]; | 		var security = this.props.securities[this.props.account.SecurityId]; | ||||||
|  | 		var balance = security.Symbol + " " + "?" | ||||||
|  |  | ||||||
| 		if (this.props.transaction.isTransaction()) { | 		if (this.props.transaction.isTransaction()) { | ||||||
| 			var thisAccountSplit; | 			var thisAccountSplit; | ||||||
| @@ -86,12 +87,12 @@ const TransactionRow = React.createClass({ | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			var amount = security.Symbol + " " + thisAccountSplit.Amount.toFixed(security.Precision); | 			var amount = security.Symbol + " " + thisAccountSplit.Amount.toFixed(security.Precision); | ||||||
| 			var balance = security.Symbol + " " + this.props.transaction.Balance.toFixed(security.Precision); | 			if (this.props.transaction.hasOwnProperty("Balance")) | ||||||
|  | 				balance = security.Symbol + " " + this.props.transaction.Balance.toFixed(security.Precision); | ||||||
| 			status = TransactionStatusMap[this.props.transaction.Status]; | 			status = TransactionStatusMap[this.props.transaction.Status]; | ||||||
| 			number = thisAccountSplit.Number; | 			number = thisAccountSplit.Number; | ||||||
| 		} else { | 		} else { | ||||||
| 			var amount = security.Symbol + " " + (new Big(0.0)).toFixed(security.Precision); | 			var amount = security.Symbol + " " + (new Big(0.0)).toFixed(security.Precision); | ||||||
| 			var balance = security.Symbol + " " + (new Big(0.0)).toFixed(security.Precision); |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return ( | 		return ( | ||||||
| @@ -650,8 +651,7 @@ module.exports = React.createClass({ | |||||||
| 	getInitialState: function() { | 	getInitialState: function() { | ||||||
| 		return { | 		return { | ||||||
| 			importingTransactions: false, | 			importingTransactions: false, | ||||||
| 			editingTransaction: false, | 			newTransaction: null, | ||||||
| 			selectedTransaction: new Transaction(), |  | ||||||
| 			height: 0 | 			height: 0 | ||||||
| 		}; | 		}; | ||||||
| 	}, | 	}, | ||||||
| @@ -659,21 +659,24 @@ module.exports = React.createClass({ | |||||||
| 		var div = ReactDOM.findDOMNode(this); | 		var div = ReactDOM.findDOMNode(this); | ||||||
| 		this.setState({height: div.parentElement.clientHeight - 64}); | 		this.setState({height: div.parentElement.clientHeight - 64}); | ||||||
| 	}, | 	}, | ||||||
|  | 	componentWillReceiveProps: function(nextProps) { | ||||||
|  | 		if (!nextProps.transactionPage.upToDate && nextProps.selectedAccount != -1) { | ||||||
|  | 			nextProps.onFetchTransactionPage(nextProps.accounts[nextProps.selectedAccount], nextProps.transactionPage.pageSize, nextProps.transactionPage.page); | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
| 	componentDidMount: function() { | 	componentDidMount: function() { | ||||||
| 		this.resize(); | 		this.resize(); | ||||||
| 		var self = this; | 		var self = this; | ||||||
| 		$(window).resize(function() {self.resize();}); | 		$(window).resize(function() {self.resize();}); | ||||||
| 	}, | 	}, | ||||||
| 	handleEditTransaction: function(transaction) { | 	handleEditTransaction: function(transaction) { | ||||||
| 		this.setState({ | 		this.props.onSelectTransaction(transaction.TransactionId); | ||||||
| 			selectedTransaction: transaction, |  | ||||||
| 			editingTransaction: true |  | ||||||
| 		}); |  | ||||||
| 	}, | 	}, | ||||||
| 	handleEditingCancel: function() { | 	handleEditingCancel: function() { | ||||||
| 		this.setState({ | 		this.setState({ | ||||||
| 			editingTransaction: false | 			newTransaction: null | ||||||
| 		}); | 		}); | ||||||
|  | 		this.props.onUnselectTransaction(); | ||||||
| 	}, | 	}, | ||||||
| 	handleNewTransactionClicked: function() { | 	handleNewTransactionClicked: function() { | ||||||
| 		var newTransaction = new Transaction(); | 		var newTransaction = new Transaction(); | ||||||
| @@ -684,8 +687,7 @@ module.exports = React.createClass({ | |||||||
| 		newTransaction.Splits[0].AccountId = this.props.accounts[this.props.selectedAccount].AccountId; | 		newTransaction.Splits[0].AccountId = this.props.accounts[this.props.selectedAccount].AccountId; | ||||||
|  |  | ||||||
| 		this.setState({ | 		this.setState({ | ||||||
| 			editingTransaction: true, | 			newTransaction: newTransaction | ||||||
| 			selectedTransaction: newTransaction |  | ||||||
| 		}); | 		}); | ||||||
| 	}, | 	}, | ||||||
| 	handleImportClicked: function() { | 	handleImportClicked: function() { | ||||||
| @@ -717,94 +719,24 @@ module.exports = React.createClass({ | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	}, | 	}, | ||||||
| 	onNewTransaction: function() { |  | ||||||
| 		this.props.onFetchTransactionPage(this.props.accounts[this.props.selectedAccount], this.props.pageSize, this.props.transactionPage.page); |  | ||||||
| 	}, |  | ||||||
| 	onUpdatedTransaction: function() { |  | ||||||
| 		this.props.onFetchTransactionPage(this.props.accounts[this.props.selectedAccount], this.props.pageSize, this.props.transactionPage.page); |  | ||||||
| 	}, |  | ||||||
| 	onDeletedTransaction: function() { |  | ||||||
| 		this.props.onFetchTransactionPage(this.props.accounts[this.props.selectedAccount], this.props.pageSize, this.props.transactionPage.page); |  | ||||||
| 	}, |  | ||||||
| 	createNewTransaction: function(transaction) { |  | ||||||
| 		$.ajax({ |  | ||||||
| 			type: "POST", |  | ||||||
| 			dataType: "json", |  | ||||||
| 			url: "transaction/", |  | ||||||
| 			data: {transaction: transaction.toJSON()}, |  | ||||||
| 			success: function(data, status, jqXHR) { |  | ||||||
| 				var e = new Error(); |  | ||||||
| 				e.fromJSON(data); |  | ||||||
| 				if (e.isError()) { |  | ||||||
| 					this.setState({error: e}); |  | ||||||
| 				} else { |  | ||||||
| 					this.onNewTransaction(); |  | ||||||
| 				} |  | ||||||
| 			}.bind(this), |  | ||||||
| 			error: this.ajaxError |  | ||||||
| 		}); |  | ||||||
| 	}, |  | ||||||
| 	updateTransaction: function(transaction) { |  | ||||||
| 		$.ajax({ |  | ||||||
| 			type: "PUT", |  | ||||||
| 			dataType: "json", |  | ||||||
| 			url: "transaction/"+transaction.TransactionId+"/", |  | ||||||
| 			data: {transaction: transaction.toJSON()}, |  | ||||||
| 			success: function(data, status, jqXHR) { |  | ||||||
| 				var e = new Error(); |  | ||||||
| 				e.fromJSON(data); |  | ||||||
| 				if (e.isError()) { |  | ||||||
| 					this.setState({error: e}); |  | ||||||
| 				} else { |  | ||||||
| 					this.onUpdatedTransaction(); |  | ||||||
| 				} |  | ||||||
| 			}.bind(this), |  | ||||||
| 			error: this.ajaxError |  | ||||||
| 		}); |  | ||||||
| 	}, |  | ||||||
| 	deleteTransaction: function(transaction) { |  | ||||||
| 		$.ajax({ |  | ||||||
| 			type: "DELETE", |  | ||||||
| 			dataType: "json", |  | ||||||
| 			url: "transaction/"+transaction.TransactionId+"/", |  | ||||||
| 			success: function(data, status, jqXHR) { |  | ||||||
| 				var e = new Error(); |  | ||||||
| 				e.fromJSON(data); |  | ||||||
| 				if (e.isError()) { |  | ||||||
| 					this.setState({error: e}); |  | ||||||
| 				} else { |  | ||||||
| 					this.onDeletedTransaction(); |  | ||||||
| 				} |  | ||||||
| 			}.bind(this), |  | ||||||
| 			error: this.ajaxError |  | ||||||
| 		}); |  | ||||||
| 	}, |  | ||||||
| 	handleImportComplete: function() { | 	handleImportComplete: function() { | ||||||
| 		this.setState({importingTransactions: false}); | 		this.setState({importingTransactions: false}); | ||||||
| 		this.props.onFetchTransactionPage(this.props.accounts[this.props.selectedAccount], this.props.pageSize, this.props.transactionPage.page); | 		this.props.onFetchTransactionPage(this.props.accounts[this.props.selectedAccount], this.props.pageSize, this.props.transactionPage.page); | ||||||
| 	}, | 	}, | ||||||
| 	handleDeleteTransaction: function(transaction) { | 	handleDeleteTransaction: function(transaction) { | ||||||
| 		this.setState({ | 		this.props.onDeleteTransaction(transaction); | ||||||
| 			editingTransaction: false | 		this.props.onUnselectTransaction(); | ||||||
| 		}); |  | ||||||
| 		this.deleteTransaction(transaction); |  | ||||||
| 	}, | 	}, | ||||||
| 	handleUpdateTransaction: function(transaction) { | 	handleUpdateTransaction: function(transaction) { | ||||||
| 		this.setState({ |  | ||||||
| 			editingTransaction: false |  | ||||||
| 		}); |  | ||||||
| 		if (transaction.TransactionId != -1) { | 		if (transaction.TransactionId != -1) { | ||||||
| 			this.updateTransaction(transaction); | 			this.props.onUpdateTransaction(transaction); | ||||||
| 		} else { | 		} else { | ||||||
| 			this.createNewTransaction(transaction); | 			this.props.onCreateTransaction(transaction); | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	componentWillReceiveProps: function(nextProps) { |  | ||||||
| 		if (nextProps.selectedAccount != this.props.selectedAccount) { |  | ||||||
| 			this.setState({ |  | ||||||
| 				selectedTransaction: new Transaction(), |  | ||||||
| 			}); |  | ||||||
| 		} | 		} | ||||||
|  | 		this.props.onUnselectTransaction(); | ||||||
|  | 		this.setState({ | ||||||
|  | 			newTransaction: null | ||||||
|  | 		}); | ||||||
| 	}, | 	}, | ||||||
| 	render: function() { | 	render: function() { | ||||||
| 		var name = "Please select an account"; | 		var name = "Please select an account"; | ||||||
| @@ -815,15 +747,16 @@ module.exports = React.createClass({ | |||||||
|  |  | ||||||
| 			var transactionRows = []; | 			var transactionRows = []; | ||||||
| 			for (var i = 0; i < this.props.transactionPage.transactions.length; i++) { | 			for (var i = 0; i < this.props.transactionPage.transactions.length; i++) { | ||||||
| 				var t = this.props.transactionPage.transactions[i]; | 				var transactionId = this.props.transactionPage.transactions[i]; | ||||||
|  | 				var transaction = this.props.transactions[transactionId]; | ||||||
| 				transactionRows.push(( | 				transactionRows.push(( | ||||||
| 					<TransactionRow | 					<TransactionRow | ||||||
| 						key={t.TransactionId} | 						key={transactionId} | ||||||
| 						transaction={t} | 						transaction={transaction} | ||||||
| 						account={this.props.accounts[this.props.selectedAccount]} | 						account={this.props.accounts[this.props.selectedAccount]} | ||||||
| 						accounts={this.props.accounts} | 						accounts={this.props.accounts} | ||||||
| 						securities={this.props.securities} | 						securities={this.props.securities} | ||||||
| 						onEdit={this.handleEditTransaction}/> | 						onSelect={this.props.onSelectTransaction}/> | ||||||
| 				)); | 				)); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -850,11 +783,21 @@ module.exports = React.createClass({ | |||||||
|  |  | ||||||
| 		var disabled = (this.props.selectedAccount == -1) ? true : false; | 		var disabled = (this.props.selectedAccount == -1) ? true : false; | ||||||
|  |  | ||||||
|  | 		var transactionSelected = false; | ||||||
|  | 		var selectedTransaction = new Transaction(); | ||||||
|  | 		if (this.state.newTransaction != null) { | ||||||
|  | 			selectedTransaction = this.state.newTransaction; | ||||||
|  | 			transactionSelected = true; | ||||||
|  | 		} else if (this.props.transactionPage.selection != -1) { | ||||||
|  | 			selectedTransaction = this.props.transactions[this.props.transactionPage.selection]; | ||||||
|  | 			transactionSelected = true; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		return ( | 		return ( | ||||||
| 			<div className="transactions-container"> | 			<div className="transactions-container"> | ||||||
| 				<AddEditTransactionModal | 				<AddEditTransactionModal | ||||||
| 					show={this.state.editingTransaction} | 					show={transactionSelected} | ||||||
| 					transaction={this.state.selectedTransaction} | 					transaction={selectedTransaction} | ||||||
| 					accounts={this.props.accounts} | 					accounts={this.props.accounts} | ||||||
| 					accountChildren={this.props.accountChildren} | 					accountChildren={this.props.accountChildren} | ||||||
| 					onCancel={this.handleEditingCancel} | 					onCancel={this.handleEditingCancel} | ||||||
|   | |||||||
| @@ -482,7 +482,13 @@ module.exports = React.createClass({ | |||||||
| 						accounts={this.props.accounts} | 						accounts={this.props.accounts} | ||||||
| 						accountChildren={this.props.accountChildren} | 						accountChildren={this.props.accountChildren} | ||||||
| 						securities={this.props.securities} | 						securities={this.props.securities} | ||||||
|  | 						transactions={this.props.transactions} | ||||||
| 						transactionPage={this.props.transactionPage} | 						transactionPage={this.props.transactionPage} | ||||||
|  | 						onCreateTransaction={this.props.onCreateTransaction} | ||||||
|  | 						onUpdateTransaction={this.props.onUpdateTransaction} | ||||||
|  | 						onDeleteTransaction={this.props.onDeleteTransaction} | ||||||
|  | 						onSelectTransaction={this.props.onSelectTransaction} | ||||||
|  | 						onUnselectTransaction={this.props.onUnselectTransaction} | ||||||
| 						onFetchTransactionPage={this.props.onFetchTransactionPage}/> | 						onFetchTransactionPage={this.props.onFetchTransactionPage}/> | ||||||
| 				</Col> | 				</Col> | ||||||
| 			</Row></Grid> | 			</Row></Grid> | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								js/constants/TransactionConstants.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								js/constants/TransactionConstants.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | var keyMirror = require('keymirror'); | ||||||
|  |  | ||||||
|  | module.exports = keyMirror({ | ||||||
|  | 	FETCH_TRANSACTION_PAGE: null, | ||||||
|  | 	TRANSACTION_PAGE_FETCHED: null, | ||||||
|  | 	CREATE_TRANSACTION: null, | ||||||
|  | 	TRANSACTION_CREATED: null, | ||||||
|  | 	UPDATE_TRANSACTION: null, | ||||||
|  | 	TRANSACTION_UPDATED: null, | ||||||
|  | 	REMOVE_TRANSACTION: null, | ||||||
|  | 	SELECT_TRANSACTION: null, | ||||||
|  | 	TRANSACTION_REMOVED: null, | ||||||
|  | 	TRANSACTION_SELECTED: null, | ||||||
|  | 	SELECTION_CLEARED: null | ||||||
|  | }); | ||||||
| @@ -1,6 +0,0 @@ | |||||||
| var keyMirror = require('keymirror'); |  | ||||||
|  |  | ||||||
| module.exports = keyMirror({ |  | ||||||
| 	FETCH_TRANSACTION_PAGE: null, |  | ||||||
| 	TRANSACTION_PAGE_FETCHED: null |  | ||||||
| }); |  | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| var connect = require('react-redux').connect; | var connect = require('react-redux').connect; | ||||||
|  |  | ||||||
| var AccountActions = require('../actions/AccountActions'); | var AccountActions = require('../actions/AccountActions'); | ||||||
| var TransactionPageActions = require('../actions/TransactionPageActions'); | var TransactionActions = require('../actions/TransactionActions'); | ||||||
|  |  | ||||||
| var AccountsTab = require('../components/AccountsTab'); | var AccountsTab = require('../components/AccountsTab'); | ||||||
|  |  | ||||||
| @@ -17,6 +17,7 @@ function mapStateToProps(state) { | |||||||
| 		securities: state.securities, | 		securities: state.securities, | ||||||
| 		security_list: security_list, | 		security_list: security_list, | ||||||
| 		selectedAccount: state.selectedAccount, | 		selectedAccount: state.selectedAccount, | ||||||
|  | 		transactions: state.transactions, | ||||||
| 		transactionPage: state.transactionPage | 		transactionPage: state.transactionPage | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -25,9 +26,14 @@ function mapDispatchToProps(dispatch) { | |||||||
| 	return { | 	return { | ||||||
| 		onCreateAccount: function(account) {dispatch(AccountActions.create(account))}, | 		onCreateAccount: function(account) {dispatch(AccountActions.create(account))}, | ||||||
| 		onUpdateAccount: function(account) {dispatch(AccountActions.update(account))}, | 		onUpdateAccount: function(account) {dispatch(AccountActions.update(account))}, | ||||||
| 		onDeleteAccount: function(accountId) {dispatch(AccountActions.remove(accountId))}, | 		onDeleteAccount: function(account) {dispatch(AccountActions.remove(account))}, | ||||||
| 		onSelectAccount: function(accountId) {dispatch(AccountActions.select(accountId))}, | 		onSelectAccount: function(accountId) {dispatch(AccountActions.select(accountId))}, | ||||||
| 		onFetchTransactionPage: function(account, pageSize, page) {dispatch(TransactionPageActions.fetch(account, pageSize, page))}, | 		onCreateTransaction: function(transaction) {dispatch(TransactionActions.create(transaction))}, | ||||||
|  | 		onUpdateTransaction: function(transaction) {dispatch(TransactionActions.update(transaction))}, | ||||||
|  | 		onDeleteTransaction: function(transaction) {dispatch(TransactionActions.remove(transaction))}, | ||||||
|  | 		onSelectTransaction: function(transactionId) {dispatch(TransactionActions.select(transactionId))}, | ||||||
|  | 		onUnselectTransaction: function() {dispatch(TransactionActions.unselect())}, | ||||||
|  | 		onFetchTransactionPage: function(account, pageSize, page) {dispatch(TransactionActions.fetchPage(account, pageSize, page))}, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ var SelectedAccountReducer = require('./SelectedAccountReducer'); | |||||||
| var SelectedSecurityReducer = require('./SelectedSecurityReducer'); | var SelectedSecurityReducer = require('./SelectedSecurityReducer'); | ||||||
| var ReportReducer = require('./ReportReducer'); | var ReportReducer = require('./ReportReducer'); | ||||||
| var SelectedReportReducer = require('./SelectedReportReducer'); | var SelectedReportReducer = require('./SelectedReportReducer'); | ||||||
|  | var TransactionReducer = require('./TransactionReducer'); | ||||||
| var TransactionPageReducer = require('./TransactionPageReducer'); | var TransactionPageReducer = require('./TransactionPageReducer'); | ||||||
| var ErrorReducer = require('./ErrorReducer'); | var ErrorReducer = require('./ErrorReducer'); | ||||||
|  |  | ||||||
| @@ -22,6 +23,7 @@ module.exports = Redux.combineReducers({ | |||||||
| 	selectedSecurity: SelectedSecurityReducer, | 	selectedSecurity: SelectedSecurityReducer, | ||||||
| 	reports: ReportReducer, | 	reports: ReportReducer, | ||||||
| 	selectedReport: SelectedReportReducer, | 	selectedReport: SelectedReportReducer, | ||||||
|  | 	transactions: TransactionReducer, | ||||||
| 	transactionPage: TransactionPageReducer, | 	transactionPage: TransactionPageReducer, | ||||||
| 	error: ErrorReducer | 	error: ErrorReducer | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -1,30 +1,34 @@ | |||||||
| var assign = require('object-assign'); | var assign = require('object-assign'); | ||||||
|  |  | ||||||
| var TransactionPageConstants = require('../constants/TransactionPageConstants'); | var TransactionConstants = require('../constants/TransactionConstants'); | ||||||
| var UserConstants = require('../constants/UserConstants'); | var UserConstants = require('../constants/UserConstants'); | ||||||
|  | var AccountConstants = require('../constants/AccountConstants'); | ||||||
|  |  | ||||||
| var Account = require('../models').Account; | var Account = require('../models').Account; | ||||||
|  |  | ||||||
| module.exports = function(state = {account: new Account(), pageSize: 1, page: 0, numPages: 0, transactions: [], endingBalance: "0" }, action) { | module.exports = function(state = {account: new Account(), pageSize: 1, page: 0, numPages: 0, transactions: [], endingBalance: "0", selection: -1, upToDate: false }, action) { | ||||||
| 	switch (action.type) { | 	switch (action.type) { | ||||||
| 		case TransactionPageConstants.FETCH_TRANSACTION_PAGE: | 		case AccountConstants.ACCOUNT_SELECTED: | ||||||
| 			return { | 		case TransactionConstants.FETCH_TRANSACTION_PAGE: | ||||||
|  | 			return assign({}, state, { | ||||||
| 				account: action.account, | 				account: action.account, | ||||||
| 				pageSize: action.pageSize, | 				pageSize: action.pageSize, | ||||||
| 				page: action.page, | 				page: action.page, | ||||||
| 				numPages: 0, | 				numPages: 0, | ||||||
| 				transactions: [], | 				transactions: [], | ||||||
| 				endingBalance: "0" | 				endingBalance: "0", | ||||||
| 			}; | 				upToDate: true | ||||||
| 		case TransactionPageConstants.TRANSACTION_PAGE_FETCHED: | 			}); | ||||||
| 			return { | 		case TransactionConstants.TRANSACTION_PAGE_FETCHED: | ||||||
|  | 			return assign({}, state, { | ||||||
| 				account: action.account, | 				account: action.account, | ||||||
| 				pageSize: action.pageSize, | 				pageSize: action.pageSize, | ||||||
| 				page: action.page, | 				page: action.page, | ||||||
| 				numPages: action.numPages, | 				numPages: action.numPages, | ||||||
| 				transactions: action.transactions, | 				transactions: action.transactions.map(function(t) {return t.TransactionId}), | ||||||
| 				endingBalance: action.endingBalance | 				endingBalance: action.endingBalance, | ||||||
| 			}; | 				upToDate: true | ||||||
|  | 			}); | ||||||
| 		case UserConstants.USER_LOGGEDOUT: | 		case UserConstants.USER_LOGGEDOUT: | ||||||
| 			return { | 			return { | ||||||
| 				account: new Account(), | 				account: new Account(), | ||||||
| @@ -32,8 +36,28 @@ module.exports = function(state = {account: new Account(), pageSize: 1, page: 0, | |||||||
| 				page: 0, | 				page: 0, | ||||||
| 				numPages: 0, | 				numPages: 0, | ||||||
| 				transactions: [], | 				transactions: [], | ||||||
| 				endingBalance: "0" | 				endingBalance: "0", | ||||||
|  | 				selection: -1, | ||||||
|  | 				upToDate: false | ||||||
| 			}; | 			}; | ||||||
|  | 		case TransactionConstants.TRANSACTION_CREATED: | ||||||
|  | 		case TransactionConstants.TRANSACTION_UPDATED: | ||||||
|  | 			return assign({}, state, { | ||||||
|  | 				upToDate: false | ||||||
|  | 			}); | ||||||
|  | 		case TransactionConstants.TRANSACTION_REMOVED: | ||||||
|  | 			return assign({}, state, { | ||||||
|  | 				transactions: state.transactions.filter(function(t) {return t != action.transactionId}), | ||||||
|  | 				upToDate: false | ||||||
|  | 			}); | ||||||
|  | 		case TransactionConstants.TRANSACTION_SELECTED: | ||||||
|  | 			return assign({}, state, { | ||||||
|  | 				selection: action.transactionId | ||||||
|  | 			}); | ||||||
|  | 		case TransactionConstants.SELECTION_CLEARED: | ||||||
|  | 			return assign({}, state, { | ||||||
|  | 				selection: -1 | ||||||
|  | 			}); | ||||||
| 		default: | 		default: | ||||||
| 			return state; | 			return state; | ||||||
| 	} | 	} | ||||||
|   | |||||||
							
								
								
									
										32
									
								
								js/reducers/TransactionReducer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								js/reducers/TransactionReducer.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | var assign = require('object-assign'); | ||||||
|  |  | ||||||
|  | var TransactionConstants = require('../constants/TransactionConstants'); | ||||||
|  | var UserConstants = require('../constants/UserConstants'); | ||||||
|  |  | ||||||
|  | module.exports = function(state = {}, action) { | ||||||
|  | 	switch (action.type) { | ||||||
|  | 		case TransactionConstants.TRANSACTION_PAGE_FETCHED: | ||||||
|  | 			var transactions = assign({}, state); | ||||||
|  | 			for (var tidx in action.transactions) { | ||||||
|  | 				var t = action.transactions[tidx]; | ||||||
|  | 				transactions = assign({}, transactions, { | ||||||
|  | 					[t.TransactionId]: t | ||||||
|  | 				}); | ||||||
|  | 			} | ||||||
|  | 			return transactions; | ||||||
|  | 		case TransactionConstants.TRANSACTION_CREATED: | ||||||
|  | 		case TransactionConstants.TRANSACTION_UPDATED: | ||||||
|  | 			var transaction = action.transaction; | ||||||
|  | 			return assign({}, state, { | ||||||
|  | 				[transaction.TransactionId]: transaction | ||||||
|  | 			}); | ||||||
|  | 		case TransactionConstants.TRANSACTION_REMOVED: | ||||||
|  | 			var transactions = assign({}, state); | ||||||
|  | 			delete transactions[action.transactionId]; | ||||||
|  | 			return transactions; | ||||||
|  | 		case UserConstants.USER_LOGGEDOUT: | ||||||
|  | 			return {}; | ||||||
|  | 		default: | ||||||
|  | 			return state; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
| @@ -508,7 +508,12 @@ func TransactionHandler(w http.ResponseWriter, r *http.Request) { | |||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		WriteSuccess(w) | 		err = transaction.Write(w) | ||||||
|  | 		if err != nil { | ||||||
|  | 			WriteError(w, 999 /*Internal Error*/) | ||||||
|  | 			log.Print(err) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
| 	} else if r.Method == "GET" { | 	} else if r.Method == "GET" { | ||||||
| 		transactionid, err := GetURLID(r.URL.Path) | 		transactionid, err := GetURLID(r.URL.Path) | ||||||
|  |  | ||||||
| @@ -590,7 +595,12 @@ func TransactionHandler(w http.ResponseWriter, r *http.Request) { | |||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			WriteSuccess(w) | 			err = transaction.Write(w) | ||||||
|  | 			if err != nil { | ||||||
|  | 				WriteError(w, 999 /*Internal Error*/) | ||||||
|  | 				log.Print(err) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
| 		} else if r.Method == "DELETE" { | 		} else if r.Method == "DELETE" { | ||||||
| 			transactionid, err := GetURLID(r.URL.Path) | 			transactionid, err := GetURLID(r.URL.Path) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user