mirror of
				https://github.com/aclindsa/moneygo.git
				synced 2025-11-04 02:23:26 -05:00 
			
		
		
		
	Add basic transaction register support
This commit is contained in:
		@@ -31,7 +31,7 @@ type Account struct {
 | 
				
			|||||||
	// monotonically-increasing account transaction version number. Used for
 | 
						// monotonically-increasing account transaction version number. Used for
 | 
				
			||||||
	// allowing a client to ensure they have a consistent version when paging
 | 
						// allowing a client to ensure they have a consistent version when paging
 | 
				
			||||||
	// through transactions.
 | 
						// through transactions.
 | 
				
			||||||
	Version int64
 | 
						AccountVersion int64 `json:"Version"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type AccountList struct {
 | 
					type AccountList struct {
 | 
				
			||||||
@@ -127,7 +127,7 @@ func insertUpdateAccount(a *Account, insert bool) error {
 | 
				
			|||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		a.Version = oldacct.Version + 1
 | 
							a.AccountVersion = oldacct.AccountVersion + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		count, err := transaction.Update(a)
 | 
							count, err := transaction.Update(a)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@@ -227,7 +227,7 @@ func AccountHandler(w http.ResponseWriter, r *http.Request) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		account.AccountId = -1
 | 
							account.AccountId = -1
 | 
				
			||||||
		account.UserId = user.UserId
 | 
							account.UserId = user.UserId
 | 
				
			||||||
		account.Version = 0
 | 
							account.AccountVersion = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if GetSecurity(account.SecurityId) == nil {
 | 
							if GetSecurity(account.SecurityId) == nil {
 | 
				
			||||||
			WriteError(w, 3 /*Invalid Request*/)
 | 
								WriteError(w, 3 /*Invalid Request*/)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										489
									
								
								static/account_register.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										489
									
								
								static/account_register.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,489 @@
 | 
				
			|||||||
 | 
					// Import all the objects we want to use from ReactBootstrap
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var Modal = ReactBootstrap.Modal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var Label = ReactBootstrap.Label;
 | 
				
			||||||
 | 
					var Table = ReactBootstrap.Table;
 | 
				
			||||||
 | 
					var Grid = ReactBootstrap.Grid;
 | 
				
			||||||
 | 
					var Row = ReactBootstrap.Row;
 | 
				
			||||||
 | 
					var Col = ReactBootstrap.Col;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var DateTimePicker = ReactWidgets.DateTimePicker;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const TransactionRow = React.createClass({
 | 
				
			||||||
 | 
						handleClick: function(e) {
 | 
				
			||||||
 | 
							const refs = ["date", "number", "description", "account", "status", "amount"];
 | 
				
			||||||
 | 
							for (var ref in refs) {
 | 
				
			||||||
 | 
								if (this.refs[refs[ref]].getDOMNode() == e.target) {
 | 
				
			||||||
 | 
									this.props.onEdit(this.props.transaction, refs[ref]);
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						render: function() {
 | 
				
			||||||
 | 
							var date = this.props.transaction.Date;
 | 
				
			||||||
 | 
							var dateString = date.getFullYear() + "/" + (date.getMonth()+1) + "/" + date.getDate();
 | 
				
			||||||
 | 
							var number = ""
 | 
				
			||||||
 | 
							var accountName = "";
 | 
				
			||||||
 | 
							var status = "";
 | 
				
			||||||
 | 
							var security = this.props.security_map[this.props.account.SecurityId];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (this.props.transaction.isTransaction()) {
 | 
				
			||||||
 | 
								var thisAccountSplit;
 | 
				
			||||||
 | 
								for (var i = 0; i < this.props.transaction.Splits.length; i++) {
 | 
				
			||||||
 | 
									if (this.props.transaction.Splits[i].AccountId == this.props.account.AccountId) {
 | 
				
			||||||
 | 
										thisAccountSplit = this.props.transaction.Splits[i];
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (this.props.transaction.Splits.length == 2) {
 | 
				
			||||||
 | 
									var otherSplit = this.props.transaction.Splits[0];
 | 
				
			||||||
 | 
									if (otherSplit.AccountId == this.props.account.AccountId)
 | 
				
			||||||
 | 
										var otherSplit = this.props.transaction.Splits[1];
 | 
				
			||||||
 | 
									var accountName = getAccountDisplayName(this.props.account_map[otherSplit.AccountId], this.props.account_map);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									accountName = "--Split Transaction--";
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var amount = "$" + thisAccountSplit.Amount.toFixed(security.Precision);
 | 
				
			||||||
 | 
								status = TransactionStatusMap[this.props.transaction.Status];
 | 
				
			||||||
 | 
								number = thisAccountSplit.Number;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								var amount = "$" + (new Big(0.0)).toFixed(security.Precision);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return (
 | 
				
			||||||
 | 
								<tr>
 | 
				
			||||||
 | 
									<td ref="date" onClick={this.handleClick}>{dateString}</td>
 | 
				
			||||||
 | 
									<td ref="number" onClick={this.handleClick}>{number}</td>
 | 
				
			||||||
 | 
									<td ref="description" onClick={this.handleClick}>{this.props.transaction.Description}</td>
 | 
				
			||||||
 | 
									<td ref="account" onClick={this.handleClick}>{accountName}</td>
 | 
				
			||||||
 | 
									<td ref="status" onClick={this.handleClick}>{status}</td>
 | 
				
			||||||
 | 
									<td ref="amount" onClick={this.handleClick}>{amount}</td>
 | 
				
			||||||
 | 
									<td>$??.??</td>
 | 
				
			||||||
 | 
								</tr>);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const AddEditTransactionModal = React.createClass({
 | 
				
			||||||
 | 
						_getInitialState: function(props) {
 | 
				
			||||||
 | 
							// Ensure we can edit this without screwing up other copies of it
 | 
				
			||||||
 | 
							var t = props.transaction.deepCopy();
 | 
				
			||||||
 | 
							return {transaction: t};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						getInitialState: function() {
 | 
				
			||||||
 | 
							 return this._getInitialState(this.props);
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						handleCancel: function() {
 | 
				
			||||||
 | 
							if (this.props.onCancel != null)
 | 
				
			||||||
 | 
								this.props.onCancel();
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						handleDescriptionChange: function() {
 | 
				
			||||||
 | 
							var transaction = this.state.transaction.deepCopy();
 | 
				
			||||||
 | 
							transaction.Description = this.refs.description.getValue();
 | 
				
			||||||
 | 
							this.setState({
 | 
				
			||||||
 | 
								transaction: transaction
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						handleDateChange: function(date, string) {
 | 
				
			||||||
 | 
							if (date == null)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							var transaction = this.state.transaction.deepCopy();
 | 
				
			||||||
 | 
							transaction.Date = date;
 | 
				
			||||||
 | 
							this.setState({
 | 
				
			||||||
 | 
								transaction: transaction
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						handleStatusChange: function(status) {
 | 
				
			||||||
 | 
							if (status.hasOwnProperty('StatusId')) {
 | 
				
			||||||
 | 
								var transaction = this.state.transaction.deepCopy();
 | 
				
			||||||
 | 
								transaction.Status = status.StatusId;
 | 
				
			||||||
 | 
								this.setState({
 | 
				
			||||||
 | 
									transaction: transaction
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						handleDeleteSplit: function(split) {
 | 
				
			||||||
 | 
							var transaction = this.state.transaction.deepCopy();
 | 
				
			||||||
 | 
							transaction.Splits.splice(split, 1);
 | 
				
			||||||
 | 
							this.setState({
 | 
				
			||||||
 | 
								transaction: transaction
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						handleUpdateNumber: function(split) {
 | 
				
			||||||
 | 
							var transaction = this.state.transaction.deepCopy();
 | 
				
			||||||
 | 
							transaction.Splits[split].Number = this.refs['number-'+split].getValue();
 | 
				
			||||||
 | 
							this.setState({
 | 
				
			||||||
 | 
								transaction: transaction
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						handleUpdateMemo: function(split) {
 | 
				
			||||||
 | 
							var transaction = this.state.transaction.deepCopy();
 | 
				
			||||||
 | 
							transaction.Splits[split].Memo = this.refs['memo-'+split].getValue();
 | 
				
			||||||
 | 
							this.setState({
 | 
				
			||||||
 | 
								transaction: transaction
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						handleUpdateAccount: function(account, split) {
 | 
				
			||||||
 | 
							var transaction = this.state.transaction.deepCopy();
 | 
				
			||||||
 | 
							transaction.Splits[split].AccountId = account.AccountId;
 | 
				
			||||||
 | 
							this.setState({
 | 
				
			||||||
 | 
								transaction: transaction
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						handleUpdateAmount: function(split) {
 | 
				
			||||||
 | 
							var transaction = this.state.transaction.deepCopy();
 | 
				
			||||||
 | 
							transaction.Splits[split].Amount = new Big(this.refs['amount-'+split].getValue());
 | 
				
			||||||
 | 
							this.setState({
 | 
				
			||||||
 | 
								transaction: transaction
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						handleSubmit: function() {
 | 
				
			||||||
 | 
							if (this.props.onSubmit != null)
 | 
				
			||||||
 | 
								this.props.onSubmit(this.state.transaction);
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						handleDelete: function() {
 | 
				
			||||||
 | 
							if (this.props.onDelete != null)
 | 
				
			||||||
 | 
								this.props.onDelete(this.state.transaction);
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						componentWillReceiveProps: function(nextProps) {
 | 
				
			||||||
 | 
							if (nextProps.show && !this.props.show) {
 | 
				
			||||||
 | 
								this.setState(this._getInitialState(nextProps));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						render: function() {
 | 
				
			||||||
 | 
							var editing = this.props.transaction != null && this.props.transaction.isTransaction();
 | 
				
			||||||
 | 
							var headerText = editing ? "Edit" : "Create New";
 | 
				
			||||||
 | 
							var buttonText = editing ? "Save Changes" : "Create Transaction";
 | 
				
			||||||
 | 
							var deleteButton = [];
 | 
				
			||||||
 | 
							if (editing) {
 | 
				
			||||||
 | 
								deleteButton = (
 | 
				
			||||||
 | 
									<Button onClick={this.handleDelete} bsStyle="danger">Delete Transaction</Button>
 | 
				
			||||||
 | 
							   );
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							splits = [];
 | 
				
			||||||
 | 
							for (var i = 0; i < this.state.transaction.Splits.length; i++) {
 | 
				
			||||||
 | 
								var self = this;
 | 
				
			||||||
 | 
								var s = this.state.transaction.Splits[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Define all closures for calling split-updating functions
 | 
				
			||||||
 | 
								var deleteSplitFn = (function() {
 | 
				
			||||||
 | 
									var j = i;
 | 
				
			||||||
 | 
									return function() {self.handleDeleteSplit(j);};
 | 
				
			||||||
 | 
								})();
 | 
				
			||||||
 | 
								var updateNumberFn = (function() {
 | 
				
			||||||
 | 
									var j = i;
 | 
				
			||||||
 | 
									return function() {self.handleUpdateNumber(j);};
 | 
				
			||||||
 | 
								})();
 | 
				
			||||||
 | 
								var updateMemoFn = (function() {
 | 
				
			||||||
 | 
									var j = i;
 | 
				
			||||||
 | 
									return function() {self.handleUpdateMemo(j);};
 | 
				
			||||||
 | 
								})();
 | 
				
			||||||
 | 
								var updateAccountFn = (function() {
 | 
				
			||||||
 | 
									var j = i;
 | 
				
			||||||
 | 
									return function(account) {self.handleUpdateAccount(account, j);};
 | 
				
			||||||
 | 
								})();
 | 
				
			||||||
 | 
								var updateAmountFn = (function() {
 | 
				
			||||||
 | 
									var j = i;
 | 
				
			||||||
 | 
									return function() {self.handleUpdateAmount(j);};
 | 
				
			||||||
 | 
								})();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var deleteSplitButton = [];
 | 
				
			||||||
 | 
								if (this.state.transaction.Splits.length > 2) {
 | 
				
			||||||
 | 
									deleteSplitButton = (
 | 
				
			||||||
 | 
										<Col xs={1}><Button onClick={deleteSplitFn}
 | 
				
			||||||
 | 
												bsStyle="danger">
 | 
				
			||||||
 | 
												<Glyphicon glyph='trash' /></Button></Col>
 | 
				
			||||||
 | 
									);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								splits.push((
 | 
				
			||||||
 | 
									<Row>
 | 
				
			||||||
 | 
									<Col xs={1}><Input
 | 
				
			||||||
 | 
										type="text"
 | 
				
			||||||
 | 
										value={s.Number}
 | 
				
			||||||
 | 
										onChange={updateNumberFn}
 | 
				
			||||||
 | 
										ref={"number-"+i} /></Col>
 | 
				
			||||||
 | 
									<Col xs={5}><Input
 | 
				
			||||||
 | 
										type="text"
 | 
				
			||||||
 | 
										value={s.Memo}
 | 
				
			||||||
 | 
										onChange={updateMemoFn}
 | 
				
			||||||
 | 
										ref={"memo-"+i} /></Col>
 | 
				
			||||||
 | 
									<Col xs={3}><AccountCombobox
 | 
				
			||||||
 | 
										accounts={this.props.accounts}
 | 
				
			||||||
 | 
										account_map={this.props.account_map}
 | 
				
			||||||
 | 
										value={s.AccountId}
 | 
				
			||||||
 | 
										includeRoot={false}
 | 
				
			||||||
 | 
										onSelect={updateAccountFn}
 | 
				
			||||||
 | 
										ref={"account-"+i} /></Col>
 | 
				
			||||||
 | 
									<Col xs={2}><Input type="text"
 | 
				
			||||||
 | 
										value={s.Amount}
 | 
				
			||||||
 | 
										onChange={updateAmountFn}
 | 
				
			||||||
 | 
										ref={"amount-"+i} /></Col>
 | 
				
			||||||
 | 
									{deleteSplitButton}
 | 
				
			||||||
 | 
									</Row>
 | 
				
			||||||
 | 
								));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return (
 | 
				
			||||||
 | 
								<Modal show={this.props.show} onHide={this.handleCancel} bsSize="large">
 | 
				
			||||||
 | 
									<Modal.Header closeButton>
 | 
				
			||||||
 | 
										<Modal.Title>{headerText} Transaction</Modal.Title>
 | 
				
			||||||
 | 
									</Modal.Header>
 | 
				
			||||||
 | 
									<Modal.Body>
 | 
				
			||||||
 | 
									<form onSubmit={this.handleSubmit}
 | 
				
			||||||
 | 
											className="form-horizontal">
 | 
				
			||||||
 | 
										<Input wrapperClassName="wrapper"
 | 
				
			||||||
 | 
											label="Date"
 | 
				
			||||||
 | 
											labelClassName="col-xs-2"
 | 
				
			||||||
 | 
											wrapperClassName="col-xs-10">
 | 
				
			||||||
 | 
										<DateTimePicker
 | 
				
			||||||
 | 
											time={false}
 | 
				
			||||||
 | 
											defaultValue={this.state.transaction.Date}
 | 
				
			||||||
 | 
											onChange={this.handleDateChange} />
 | 
				
			||||||
 | 
										</Input>
 | 
				
			||||||
 | 
										<Input type="text"
 | 
				
			||||||
 | 
											label="Description"
 | 
				
			||||||
 | 
											value={this.state.transaction.Description}
 | 
				
			||||||
 | 
											onChange={this.handleDescriptionChange}
 | 
				
			||||||
 | 
											ref="description"
 | 
				
			||||||
 | 
											labelClassName="col-xs-2"
 | 
				
			||||||
 | 
											wrapperClassName="col-xs-10"/>
 | 
				
			||||||
 | 
										<Input wrapperClassName="wrapper"
 | 
				
			||||||
 | 
											label="Status"
 | 
				
			||||||
 | 
											labelClassName="col-xs-2"
 | 
				
			||||||
 | 
											wrapperClassName="col-xs-10">
 | 
				
			||||||
 | 
										<Combobox
 | 
				
			||||||
 | 
											data={TransactionStatusList}
 | 
				
			||||||
 | 
											valueField='StatusId'
 | 
				
			||||||
 | 
											textField='Name'
 | 
				
			||||||
 | 
											value={this.state.transaction.Status}
 | 
				
			||||||
 | 
											onSelect={this.handleStatusChange}
 | 
				
			||||||
 | 
											ref="status" />
 | 
				
			||||||
 | 
										</Input>
 | 
				
			||||||
 | 
										<Grid fluid={true}><Row>
 | 
				
			||||||
 | 
										<span className="split-header col-xs-1">#</span>
 | 
				
			||||||
 | 
										<span className="split-header col-xs-5">Memo</span>
 | 
				
			||||||
 | 
										<span className="split-header col-xs-3">Account</span>
 | 
				
			||||||
 | 
										<span className="split-header col-xs-2">Amount</span>
 | 
				
			||||||
 | 
										</Row>
 | 
				
			||||||
 | 
										{splits}
 | 
				
			||||||
 | 
										</Grid>
 | 
				
			||||||
 | 
									</form>
 | 
				
			||||||
 | 
									</Modal.Body>
 | 
				
			||||||
 | 
									<Modal.Footer>
 | 
				
			||||||
 | 
										<ButtonGroup className="pull-right">
 | 
				
			||||||
 | 
											<Button onClick={this.handleCancel} bsStyle="warning">Cancel</Button>
 | 
				
			||||||
 | 
											{deleteButton}
 | 
				
			||||||
 | 
											<Button onClick={this.handleSubmit} bsStyle="success">{buttonText}</Button>
 | 
				
			||||||
 | 
										</ButtonGroup>
 | 
				
			||||||
 | 
									</Modal.Footer>
 | 
				
			||||||
 | 
								</Modal>
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const AccountRegister = React.createClass({
 | 
				
			||||||
 | 
						getInitialState: function() {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								editingTransaction: false,
 | 
				
			||||||
 | 
								selectedTransaction: new Transaction(),
 | 
				
			||||||
 | 
								transactions: []
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						handleEditTransaction: function(transaction, fieldName) {
 | 
				
			||||||
 | 
							//TODO select fieldName first when editing
 | 
				
			||||||
 | 
							this.setState({
 | 
				
			||||||
 | 
								selectedTransaction: transaction,
 | 
				
			||||||
 | 
								editingTransaction: true
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						handleEditingCancel: function() {
 | 
				
			||||||
 | 
							this.setState({
 | 
				
			||||||
 | 
								editingTransaction: false
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						ajaxError: function(jqXHR, status, error) {
 | 
				
			||||||
 | 
							var e = new Error();
 | 
				
			||||||
 | 
							e.ErrorId = 5;
 | 
				
			||||||
 | 
							e.ErrorString = "Request Failed: " + status + error;
 | 
				
			||||||
 | 
							this.setState({error: e});
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						getTransactionPage: function(account, page) {
 | 
				
			||||||
 | 
							$.ajax({
 | 
				
			||||||
 | 
								type: "GET",
 | 
				
			||||||
 | 
								dataType: "json",
 | 
				
			||||||
 | 
								url: "account/"+account.AccountId+"/transactions?sort=date-desc&limit=50&page="+page,
 | 
				
			||||||
 | 
								success: function(data, status, jqXHR) {
 | 
				
			||||||
 | 
									var e = new Error();
 | 
				
			||||||
 | 
									var transactions = [];
 | 
				
			||||||
 | 
									e.fromJSON(data);
 | 
				
			||||||
 | 
									if (e.isError()) {
 | 
				
			||||||
 | 
										this.setState({error: e});
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										for (var i = 0; i < data.transactions.length; i++) {
 | 
				
			||||||
 | 
											var t = new Transaction();
 | 
				
			||||||
 | 
											t.fromJSON(data.transactions[i]);
 | 
				
			||||||
 | 
											transactions.push(t);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									var a = new Account();
 | 
				
			||||||
 | 
									a.fromJSON(data.account);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									this.setState({transactions: transactions});
 | 
				
			||||||
 | 
								}.bind(this),
 | 
				
			||||||
 | 
								error: this.ajaxError
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						onNewTransaction: function() {
 | 
				
			||||||
 | 
							this.getTransactionPage(this.props.selectedAccount, 0);
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						onUpdatedTransaction: function() {
 | 
				
			||||||
 | 
							this.getTransactionPage(this.props.selectedAccount, 0);
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						onDeletedTransaction: function() {
 | 
				
			||||||
 | 
							this.getTransactionPage(this.props.selectedAccount, 0);
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						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) {
 | 
				
			||||||
 | 
							console.log("handleDeleteTransaction", 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
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						handleDeleteTransaction: function(transaction) {
 | 
				
			||||||
 | 
							this.setState({
 | 
				
			||||||
 | 
								editingTransaction: false
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
							this.deleteTransaction(transaction);
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						handleUpdateTransaction: function(transaction) {
 | 
				
			||||||
 | 
							this.setState({
 | 
				
			||||||
 | 
								editingTransaction: false
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
							if (transaction.TransactionId != -1) {
 | 
				
			||||||
 | 
								this.updateTransaction(transaction);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								this.createNewTransaction(transaction);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						componentWillReceiveProps: function(nextProps) {
 | 
				
			||||||
 | 
							if (nextProps.selectedAccount != this.props.selectedAccount) {
 | 
				
			||||||
 | 
								this.getTransactionPage(nextProps.selectedAccount, 0);
 | 
				
			||||||
 | 
								console.log("TODO begin fetching transactions for new account");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						render: function() {
 | 
				
			||||||
 | 
							var name = "Please select an account";
 | 
				
			||||||
 | 
							if (this.props.selectedAccount != null)
 | 
				
			||||||
 | 
								name = this.props.selectedAccount.Name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							register = [];
 | 
				
			||||||
 | 
							if (this.props.selectedAccount != null) {
 | 
				
			||||||
 | 
								var newTransaction = new Transaction();
 | 
				
			||||||
 | 
								newTransaction.Description = "Create New Transaction...";
 | 
				
			||||||
 | 
								newTransaction.Status = TransactionStatus.Entered;
 | 
				
			||||||
 | 
								newTransaction.Date = new Date();
 | 
				
			||||||
 | 
								newTransaction.Splits.push(new Split());
 | 
				
			||||||
 | 
								newTransaction.Splits.push(new Split());
 | 
				
			||||||
 | 
								newTransaction.Splits[0].AccountId = this.props.selectedAccount.AccountId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var transactionRows = [];
 | 
				
			||||||
 | 
								var allTransactions = [newTransaction].concat(this.state.transactions);
 | 
				
			||||||
 | 
								for (var i = 0; i < allTransactions.length; i++) {
 | 
				
			||||||
 | 
									var t = allTransactions[i];
 | 
				
			||||||
 | 
									transactionRows.push((
 | 
				
			||||||
 | 
										<TransactionRow
 | 
				
			||||||
 | 
											transaction={t}
 | 
				
			||||||
 | 
											account={this.props.selectedAccount}
 | 
				
			||||||
 | 
											accounts={this.props.accounts}
 | 
				
			||||||
 | 
											account_map={this.props.account_map}
 | 
				
			||||||
 | 
											securities={this.props.securities}
 | 
				
			||||||
 | 
											security_map={this.props.security_map}
 | 
				
			||||||
 | 
											onEdit={this.handleEditTransaction}/>
 | 
				
			||||||
 | 
									));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								register = (
 | 
				
			||||||
 | 
									<Table bordered striped condensed hover>
 | 
				
			||||||
 | 
										<thead><tr>
 | 
				
			||||||
 | 
											<th>Date</th>
 | 
				
			||||||
 | 
											<th>#</th>
 | 
				
			||||||
 | 
											<th>Description</th>
 | 
				
			||||||
 | 
											<th>Account</th>
 | 
				
			||||||
 | 
											<th>Status</th>
 | 
				
			||||||
 | 
											<th>Amount</th>
 | 
				
			||||||
 | 
											<th>Balance</th>
 | 
				
			||||||
 | 
										</tr></thead>
 | 
				
			||||||
 | 
										<tbody>
 | 
				
			||||||
 | 
											{transactionRows}
 | 
				
			||||||
 | 
										</tbody>
 | 
				
			||||||
 | 
										</Table>
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return (
 | 
				
			||||||
 | 
								<div>
 | 
				
			||||||
 | 
									<AddEditTransactionModal
 | 
				
			||||||
 | 
										show={this.state.editingTransaction}
 | 
				
			||||||
 | 
										transaction={this.state.selectedTransaction}
 | 
				
			||||||
 | 
										accounts={this.props.accounts}
 | 
				
			||||||
 | 
										account_map={this.props.account_map}
 | 
				
			||||||
 | 
										onCancel={this.handleEditingCancel}
 | 
				
			||||||
 | 
										onSubmit={this.handleUpdateTransaction}
 | 
				
			||||||
 | 
										onDelete={this.handleDeleteTransaction}
 | 
				
			||||||
 | 
										securities={this.props.securities}/>
 | 
				
			||||||
 | 
									{name}
 | 
				
			||||||
 | 
									{register}
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@@ -10,30 +10,10 @@ var Button = ReactBootstrap.Button;
 | 
				
			|||||||
var ButtonGroup = ReactBootstrap.ButtonGroup;
 | 
					var ButtonGroup = ReactBootstrap.ButtonGroup;
 | 
				
			||||||
var Glyphicon = ReactBootstrap.Glyphicon;
 | 
					var Glyphicon = ReactBootstrap.Glyphicon;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var Modal = ReactBootstrap.Modal;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var CollapsibleMixin = ReactBootstrap.CollapsibleMixin;
 | 
					var CollapsibleMixin = ReactBootstrap.CollapsibleMixin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var Combobox = ReactWidgets.Combobox;
 | 
					var Combobox = ReactWidgets.Combobox;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const recursiveAccountDisplayInfo = function(account, prefix) {
 | 
					 | 
				
			||||||
	var name = prefix + account.Name;
 | 
					 | 
				
			||||||
	var accounts = [{AccountId: account.AccountId, Name: name}];
 | 
					 | 
				
			||||||
	for (var i = 0; i < account.Children.length; i++)
 | 
					 | 
				
			||||||
		accounts = accounts.concat(recursiveAccountDisplayInfo(account.Children[i], name + "/"));
 | 
					 | 
				
			||||||
	return accounts
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
const getAccountDisplayList = function(account_list, includeRoot, rootName) {
 | 
					 | 
				
			||||||
	var accounts = []
 | 
					 | 
				
			||||||
	if (includeRoot)
 | 
					 | 
				
			||||||
		accounts.push({AccountId: -1, Name: rootName});
 | 
					 | 
				
			||||||
	for (var i = 0; i < account_list.length; i++) {
 | 
					 | 
				
			||||||
		if (account_list[i].isRootAccount())
 | 
					 | 
				
			||||||
			accounts = accounts.concat(recursiveAccountDisplayInfo(account_list[i], ""));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return accounts;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const AccountCombobox = React.createClass({
 | 
					const AccountCombobox = React.createClass({
 | 
				
			||||||
	getDefaultProps: function() {
 | 
						getDefaultProps: function() {
 | 
				
			||||||
		return {
 | 
							return {
 | 
				
			||||||
@@ -494,7 +474,12 @@ const AccountsTab = React.createClass({
 | 
				
			|||||||
							<Glyphicon glyph='trash' /></Button>
 | 
												<Glyphicon glyph='trash' /></Button>
 | 
				
			||||||
					</ButtonGroup>
 | 
										</ButtonGroup>
 | 
				
			||||||
				</Col><Col xs={10} className="fullheight transactions-column">
 | 
									</Col><Col xs={10} className="fullheight transactions-column">
 | 
				
			||||||
					blah
 | 
										<AccountRegister
 | 
				
			||||||
 | 
											selectedAccount={this.state.selectedAccount}
 | 
				
			||||||
 | 
											accounts={this.props.accounts}
 | 
				
			||||||
 | 
											account_map={this.props.account_map}
 | 
				
			||||||
 | 
											securities={this.props.securities}
 | 
				
			||||||
 | 
											security_map={this.props.security_map} />
 | 
				
			||||||
				</Col>
 | 
									</Col>
 | 
				
			||||||
			</Row></Grid>
 | 
								</Row></Grid>
 | 
				
			||||||
		);
 | 
							);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,7 @@
 | 
				
			|||||||
<script type="text/javascript" src="static/models.js"></script>
 | 
					<script type="text/javascript" src="static/models.js"></script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script type="text/jsx" src="static/top_bar.js"></script>
 | 
					<script type="text/jsx" src="static/top_bar.js"></script>
 | 
				
			||||||
 | 
					<script type="text/jsx" src="static/account_register.js"></script>
 | 
				
			||||||
<script type="text/jsx" src="static/accounts.js"></script>
 | 
					<script type="text/jsx" src="static/accounts.js"></script>
 | 
				
			||||||
<script type="text/jsx" src="static/ui.js"></script>
 | 
					<script type="text/jsx" src="static/ui.js"></script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -212,8 +212,6 @@ Split.prototype.toJSONobj = function() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Split.prototype.fromJSONobj = function(json_obj) {
 | 
					Split.prototype.fromJSONobj = function(json_obj) {
 | 
				
			||||||
	var json_obj = getJSONObj(json_input);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (json_obj.hasOwnProperty("SplitId"))
 | 
						if (json_obj.hasOwnProperty("SplitId"))
 | 
				
			||||||
		this.SplitId = json_obj.SplitId;
 | 
							this.SplitId = json_obj.SplitId;
 | 
				
			||||||
	if (json_obj.hasOwnProperty("TransactionId"))
 | 
						if (json_obj.hasOwnProperty("TransactionId"))
 | 
				
			||||||
@@ -243,6 +241,18 @@ const TransactionStatus = {
 | 
				
			|||||||
	Reconciled: 3,
 | 
						Reconciled: 3,
 | 
				
			||||||
	Voided: 4
 | 
						Voided: 4
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					var TransactionStatusList = [];
 | 
				
			||||||
 | 
					for (var type in TransactionStatus) {
 | 
				
			||||||
 | 
						if (TransactionStatus.hasOwnProperty(type)) {
 | 
				
			||||||
 | 
							TransactionStatusList.push({'StatusId': TransactionStatus[type], 'Name': type});
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					var TransactionStatusMap = {};
 | 
				
			||||||
 | 
					for (var status in TransactionStatus) {
 | 
				
			||||||
 | 
						if (TransactionStatus.hasOwnProperty(status)) {
 | 
				
			||||||
 | 
							TransactionStatusMap[TransactionStatus[status]] = status;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Transaction() {
 | 
					function Transaction() {
 | 
				
			||||||
	this.TransactionId = -1;
 | 
						this.TransactionId = -1;
 | 
				
			||||||
@@ -262,8 +272,8 @@ Transaction.prototype.toJSON = function() {
 | 
				
			|||||||
	json_obj.Date = this.Date.toJSON();
 | 
						json_obj.Date = this.Date.toJSON();
 | 
				
			||||||
	json_obj.Splits = [];
 | 
						json_obj.Splits = [];
 | 
				
			||||||
	for (var i = 0; i < this.Splits.length; i++)
 | 
						for (var i = 0; i < this.Splits.length; i++)
 | 
				
			||||||
		json_obj.push(this.Splits[i].toJSONobj());
 | 
							json_obj.Splits.push(this.Splits[i].toJSONobj());
 | 
				
			||||||
	return json_obj;
 | 
						return JSON.stringify(json_obj);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Transaction.prototype.fromJSON = function(json_input) {
 | 
					Transaction.prototype.fromJSON = function(json_input) {
 | 
				
			||||||
@@ -289,8 +299,11 @@ Transaction.prototype.fromJSON = function(json_input) {
 | 
				
			|||||||
			this.Date = new Date(0);
 | 
								this.Date = new Date(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (json_obj.hasOwnProperty("Splits")) {
 | 
						if (json_obj.hasOwnProperty("Splits")) {
 | 
				
			||||||
		for (var i = 0; i < json_obj.Splits.length; i++)
 | 
							for (var i = 0; i < json_obj.Splits.length; i++) {
 | 
				
			||||||
			this.Splits.push(this.Splits[i].fromJSON());
 | 
								var s = new Split();
 | 
				
			||||||
 | 
								s.fromJSONobj(json_obj.Splits[i]);
 | 
				
			||||||
 | 
								this.Splits.push(s);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -300,6 +313,12 @@ Transaction.prototype.isTransaction = function() {
 | 
				
			|||||||
		this.UserId != empty_transaction.UserId;
 | 
							this.UserId != empty_transaction.UserId;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Transaction.prototype.deepCopy = function() {
 | 
				
			||||||
 | 
						var t = new Transaction();
 | 
				
			||||||
 | 
						t.fromJSON(this.toJSON());
 | 
				
			||||||
 | 
						return t;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Error() {
 | 
					function Error() {
 | 
				
			||||||
	this.ErrorId = -1;
 | 
						this.ErrorId = -1;
 | 
				
			||||||
	this.ErrorString = "";
 | 
						this.ErrorString = "";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -75,3 +75,24 @@ div.accounttree-root div {
 | 
				
			|||||||
	padding: 15px;
 | 
						padding: 15px;
 | 
				
			||||||
	border-right: 1px solid #DDD;
 | 
						border-right: 1px solid #DDD;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.register-row-editing {
 | 
				
			||||||
 | 
						background-color: #FFFFE0 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.register-row-editing:hover {
 | 
				
			||||||
 | 
						background-color: #e8e8e8 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.register-row-editing .form-group {
 | 
				
			||||||
 | 
						margin: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.row > div > .form-group,
 | 
				
			||||||
 | 
					.row > div > .rw-combobox {
 | 
				
			||||||
 | 
						margin-right: -7px;
 | 
				
			||||||
 | 
						margin-left: -7px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.split-header {
 | 
				
			||||||
 | 
						font-weight: 700;
 | 
				
			||||||
 | 
						text-align: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								static/utils.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								static/utils.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					const recursiveAccountDisplayInfo = function(account, prefix) {
 | 
				
			||||||
 | 
						var name = prefix + account.Name;
 | 
				
			||||||
 | 
						var accounts = [{AccountId: account.AccountId, Name: name}];
 | 
				
			||||||
 | 
						for (var i = 0; i < account.Children.length; i++)
 | 
				
			||||||
 | 
							accounts = accounts.concat(recursiveAccountDisplayInfo(account.Children[i], name + "/"));
 | 
				
			||||||
 | 
						return accounts
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getAccountDisplayList = function(account_list, includeRoot, rootName) {
 | 
				
			||||||
 | 
						var accounts = []
 | 
				
			||||||
 | 
						if (includeRoot)
 | 
				
			||||||
 | 
							accounts.push({AccountId: -1, Name: rootName});
 | 
				
			||||||
 | 
						for (var i = 0; i < account_list.length; i++) {
 | 
				
			||||||
 | 
							if (account_list[i].isRootAccount())
 | 
				
			||||||
 | 
								accounts = accounts.concat(recursiveAccountDisplayInfo(account_list[i], ""));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return accounts;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getAccountDisplayName = function(account, account_map) {
 | 
				
			||||||
 | 
						var name = account.Name;
 | 
				
			||||||
 | 
						while (account.ParentAccountId >= 0) {
 | 
				
			||||||
 | 
							account = account_map[account.ParentAccountId];
 | 
				
			||||||
 | 
							name = account.Name + "/" + name;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return name;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -18,7 +18,7 @@ type Split struct {
 | 
				
			|||||||
	SplitId       int64
 | 
						SplitId       int64
 | 
				
			||||||
	TransactionId int64
 | 
						TransactionId int64
 | 
				
			||||||
	AccountId     int64
 | 
						AccountId     int64
 | 
				
			||||||
	Number        int64 // Check or reference number
 | 
						Number        string // Check or reference number
 | 
				
			||||||
	Memo          string
 | 
						Memo          string
 | 
				
			||||||
	Amount        string // String representation of decimal, suitable for passing to big.Rat.SetString()
 | 
						Amount        string // String representation of decimal, suitable for passing to big.Rat.SetString()
 | 
				
			||||||
	Debit         bool
 | 
						Debit         bool
 | 
				
			||||||
@@ -38,10 +38,8 @@ func (s *Split) Valid() bool {
 | 
				
			|||||||
	return err == nil
 | 
						return err == nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type TransactionStatus int64
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	Entered    TransactionStatus = 1
 | 
						Entered    int64 = 1
 | 
				
			||||||
	Cleared                      = 2
 | 
						Cleared                      = 2
 | 
				
			||||||
	Reconciled                   = 3
 | 
						Reconciled                   = 3
 | 
				
			||||||
	Voided                       = 4
 | 
						Voided                       = 4
 | 
				
			||||||
@@ -51,7 +49,7 @@ type Transaction struct {
 | 
				
			|||||||
	TransactionId int64
 | 
						TransactionId int64
 | 
				
			||||||
	UserId        int64
 | 
						UserId        int64
 | 
				
			||||||
	Description   string
 | 
						Description   string
 | 
				
			||||||
	Status        TransactionStatus
 | 
						Status        int64
 | 
				
			||||||
	Date          time.Time
 | 
						Date          time.Time
 | 
				
			||||||
	Splits        []*Split `db:"-"`
 | 
						Splits        []*Split `db:"-"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -118,7 +116,7 @@ func GetTransaction(transactionid int64, userid int64) (*Transaction, error) {
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = transaction.SelectOne(&t, "SELECT * from transaction where UserId=? AND TransactionId=?", userid, transactionid)
 | 
						err = transaction.SelectOne(&t, "SELECT * from transactions where UserId=? AND TransactionId=?", userid, transactionid)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -172,7 +170,7 @@ func incrementAccountVersions(transaction *gorp.Transaction, user *User, account
 | 
				
			|||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		account.Version++
 | 
							account.AccountVersion++
 | 
				
			||||||
		count, err := transaction.Update(account)
 | 
							count, err := transaction.Update(account)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user