// 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 (
{dateString}
{number}
{this.props.transaction.Description}
{accountName}
{status}
{amount}
$??.??
);
}
});
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 = (
);
}
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 = (
);
}
splits.push((
{deleteSplitButton}
));
}
return (
{headerText} Transaction
{deleteButton}
);
}
});
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((
));
}
register = (