1
0
mirror of https://github.com/aclindsa/moneygo.git synced 2025-06-23 08:58:39 -04:00

Add Initial Gnucash importing

There are still a number of bugs, but the basic functionality is there
This commit is contained in:
2016-02-15 11:28:44 -05:00
parent fcf6b2f1a4
commit 9e26b30bdc
9 changed files with 571 additions and 162 deletions

@ -9,6 +9,7 @@ module.exports = React.createClass({
getDefaultProps: function() {
return {
includeRoot: true,
disabled: false,
rootName: "New Top-level Account"
};
},
@ -33,6 +34,7 @@ module.exports = React.createClass({
defaultValue={this.props.value}
onChange={this.handleAccountChange}
ref="account"
disabled={this.props.disabled}
className={className} />
);
}

@ -20,8 +20,10 @@ var ButtonToolbar = ReactBootstrap.ButtonToolbar;
var ProgressBar = ReactBootstrap.ProgressBar;
var Glyphicon = ReactBootstrap.Glyphicon;
var DateTimePicker = require('react-widgets').DateTimePicker;
var Combobox = require('react-widgets').Combobox;
var ReactWidgets = require('react-widgets')
var DateTimePicker = ReactWidgets.DateTimePicker;
var Combobox = ReactWidgets.Combobox;
var DropdownList = ReactWidgets.DropdownList;
var Big = require('big.js');
@ -455,29 +457,39 @@ const AddEditTransactionModal = React.createClass({
}
});
const ImportType = {
OFX: 1,
Gnucash: 2
};
var ImportTypeList = [];
for (var type in ImportType) {
if (ImportType.hasOwnProperty(type)) {
var name = ImportType[type] == ImportType.OFX ? "OFX/QFX" : type; //QFX is a special snowflake
ImportTypeList.push({'TypeId': ImportType[type], 'Name': name});
}
}
const ImportTransactionsModal = React.createClass({
getInitialState: function() {
return {
importing: false,
imported: false,
importFile: "",
importType: ImportType.Gnucash,
uploadProgress: -1,
error: null};
},
handleCancel: function() {
this.setState({
importing: false,
imported: false,
importFile: "",
uploadProgress: -1,
error: null
});
this.setState(this.getInitialState());
if (this.props.onCancel != null)
this.props.onCancel();
},
onImportChanged: function() {
handleImportChange: function() {
this.setState({importFile: this.refs.importfile.getValue()});
},
handleTypeChange: function(type) {
this.setState({importType: type.TypeId});
},
handleSubmit: function() {
if (this.props.onSubmit != null)
this.props.onSubmit(this.props.account);
@ -493,11 +505,18 @@ const ImportTransactionsModal = React.createClass({
handleImportTransactions: function() {
var file = this.refs.importfile.getInputDOMNode().files[0];
var formData = new FormData();
this.setState({importing: true});
formData.append('importfile', file, this.state.importFile);
var url = ""
if (this.state.importType == ImportType.OFX)
url = "account/"+this.props.account.AccountId+"/import/ofx";
else if (this.state.importType == ImportType.Gnucash)
url = "import/gnucash";
this.setState({importing: true});
$.ajax({
type: "POST",
url: "account/"+this.props.account.AccountId+"/import",
url: url,
data: formData,
xhr: function() {
var xhrObject = $.ajaxSettings.xhr();
@ -514,7 +533,7 @@ const ImportTransactionsModal = React.createClass({
if (e.isError()) {
var errString = e.ErrorString;
if (e.ErrorId == 3 /* Invalid Request */) {
errString = "Please check that the file you uploaded is a valid OFX file for this account and try again.";
errString = "Please check that the file you uploaded is valid and try again.";
}
this.setState({
importing: false,
@ -540,9 +559,11 @@ const ImportTransactionsModal = React.createClass({
});
},
render: function() {
var accountNameLabel = ""
if (this.props.account != null )
var accountNameLabel = "Performing global import:"
if (this.props.account != null && this.state.importType != ImportType.Gnucash)
accountNameLabel = "Importing to '" + getAccountDisplayName(this.props.account, this.props.account_map) + "' account:";
// Display the progress bar if an upload/import is in progress
var progressBar = [];
if (this.state.importing && this.state.uploadProgress == 100) {
progressBar = (<ProgressBar now={this.state.uploadProgress} active label="Importing transactions..." />);
@ -550,6 +571,7 @@ const ImportTransactionsModal = React.createClass({
progressBar = (<ProgressBar now={this.state.uploadProgress} active label="Uploading... %(percent)s%" />);
}
// Create panel, possibly displaying error or success messages
var panel = [];
if (this.state.error != null) {
panel = (<Panel header="Error Importing Transactions" bsStyle="danger">{this.state.error}</Panel>);
@ -557,16 +579,22 @@ const ImportTransactionsModal = React.createClass({
panel = (<Panel header="Successfully Imported Transactions" bsStyle="success">Your import is now complete.</Panel>);
}
var buttonsDisabled = (this.state.importing) ? true : false;
// Display proper buttons, possibly disabling them if an import is in progress
var button1 = [];
var button2 = [];
if (!this.state.imported && this.state.error == null) {
button1 = (<Button onClick={this.handleCancel} disabled={buttonsDisabled} bsStyle="warning">Cancel</Button>);
button2 = (<Button onClick={this.handleImportTransactions} disabled={buttonsDisabled} bsStyle="success">Import</Button>);
button1 = (<Button onClick={this.handleCancel} disabled={this.state.importing} bsStyle="warning">Cancel</Button>);
button2 = (<Button onClick={this.handleImportTransactions} disabled={this.state.importing || this.state.importFile == ""} bsStyle="success">Import</Button>);
} else {
button1 = (<Button onClick={this.handleCancel} disabled={buttonsDisabled} bsStyle="success">OK</Button>);
button1 = (<Button onClick={this.handleCancel} disabled={this.state.importing} bsStyle="success">OK</Button>);
}
var inputDisabled = (this.state.importing || this.state.error != null || this.state.imported) ? true : false;
// Disable OFX/QFX imports if no account is selected
var disabledTypes = false;
if (this.props.account == null)
disabledTypes = [ImportTypeList[ImportType.OFX - 1]];
return (
<Modal show={this.props.show} onHide={this.handleCancel} bsSize="small">
<Modal.Header closeButton>
@ -576,13 +604,21 @@ const ImportTransactionsModal = React.createClass({
<form onSubmit={this.handleImportTransactions}
encType="multipart/form-data"
ref="importform">
<DropdownList
data={ImportTypeList}
valueField='TypeId'
textField='Name'
onSelect={this.handleTypeChange}
defaultValue={this.state.importType}
disabled={disabledTypes}
ref="importtype" />
<Input type="file"
ref="importfile"
disabled={inputDisabled}
value={this.state.importFile}
label={accountNameLabel}
help="Select an OFX/QFX file to upload."
onChange={this.onImportChanged} />
onChange={this.handleImportChange} />
</form>
{progressBar}
{panel}
@ -897,8 +933,7 @@ module.exports = React.createClass({
</Button>
<Button
onClick={this.handleImportClicked}
bsStyle="primary"
disabled={disabled}>
bsStyle="primary">
<Glyphicon glyph='import' /> Import
</Button>
</ButtonGroup>