From 4de537ce7613bea7ae2fa56987c5961af04245c4 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 19 Jul 2019 16:08:42 +0200 Subject: [PATCH] New code for edit transaction, and some tests. --- .../V1/Requests/TransactionUpdateRequest.php | 5 +- .../Transaction/CreateController.php | 9 +- .../Internal/Support/JournalServiceTrait.php | 1 + .../Internal/Update/JournalUpdateService.php | 2 +- public/v1/js/app.js | 750 +++++++++++------- .../components/transactions/AccountSelect.vue | 4 + .../transactions/CreateTransaction.vue | 63 +- .../transactions/EditTransaction.vue | 695 ++++++++++------ .../Transaction/ConvertControllerTest.php | 2 - .../Transaction/CreateControllerTest.php | 66 ++ 10 files changed, 990 insertions(+), 607 deletions(-) create mode 100644 tests/Feature/Controllers/Transaction/CreateControllerTest.php diff --git a/app/Api/V1/Requests/TransactionUpdateRequest.php b/app/Api/V1/Requests/TransactionUpdateRequest.php index 6c03276d39..603490c3a0 100644 --- a/app/Api/V1/Requests/TransactionUpdateRequest.php +++ b/app/Api/V1/Requests/TransactionUpdateRequest.php @@ -30,7 +30,7 @@ use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsDateOrTime; use FireflyIII\Validation\TransactionValidation; use Illuminate\Validation\Validator; - +use Log; /** * Class TransactionUpdateRequest @@ -275,6 +275,7 @@ class TransactionUpdateRequest extends Request */ private function getTransactionData(): array { + Log::debug('Now in getTransactionData()'); $return = []; /** * @var int $index @@ -298,8 +299,10 @@ class TransactionUpdateRequest extends Request } foreach ($this->dateFields as $fieldName) { + Log::debug(sprintf('Now at date field %s', $fieldName)); if (array_key_exists($fieldName, $transaction)) { $current[$fieldName] = $this->dateFromValue((string)$transaction[$fieldName]); + Log::debug(sprintf('New value: "%s"', (string)$transaction[$fieldName])); } } diff --git a/app/Http/Controllers/Transaction/CreateController.php b/app/Http/Controllers/Transaction/CreateController.php index 5a4e47bedb..96473e5ec8 100644 --- a/app/Http/Controllers/Transaction/CreateController.php +++ b/app/Http/Controllers/Transaction/CreateController.php @@ -36,6 +36,7 @@ class CreateController extends Controller { /** * CreateController constructor. + * @codeCoverageIgnore */ public function __construct() { @@ -91,12 +92,4 @@ class CreateController extends Controller 'optionalFields', 'preFilled', 'allowedOpposingTypes', 'accountToTypes') ); } - - public function store(Request $request) - { - echo '
';
-        print_r($request->all());
-        exit;
-    }
-
 }
\ No newline at end of file
diff --git a/app/Services/Internal/Support/JournalServiceTrait.php b/app/Services/Internal/Support/JournalServiceTrait.php
index 8c50c460ab..e769280e67 100644
--- a/app/Services/Internal/Support/JournalServiceTrait.php
+++ b/app/Services/Internal/Support/JournalServiceTrait.php
@@ -265,6 +265,7 @@ trait JournalServiceTrait
             return;
         }
         foreach ($tags as $string) {
+            $string = (string)$string;
             if ('' !== $string) {
                 $tag = $this->tagFactory->findOrCreate($string);
                 if (null !== $tag) {
diff --git a/app/Services/Internal/Update/JournalUpdateService.php b/app/Services/Internal/Update/JournalUpdateService.php
index 48bebb8690..65436f8c57 100644
--- a/app/Services/Internal/Update/JournalUpdateService.php
+++ b/app/Services/Internal/Update/JournalUpdateService.php
@@ -598,7 +598,7 @@ class JournalUpdateService
         foreach ($this->metaDate as $field) {
             if ($this->hasFields([$field])) {
                 try {
-                    $value = '' === $this->data[$field] ? null : new Carbon($this->data[$field]);
+                    $value = '' === (string)$this->data[$field] ? null : new Carbon($this->data[$field]);
                 } catch (Exception $e) {
                     Log::debug(sprintf('%s is not a valid date value: %s', $this->data[$field], $e->getMessage()));
 
diff --git a/public/v1/js/app.js b/public/v1/js/app.js
index 5f89811fe7..ce3eaade6f 100644
--- a/public/v1/js/app.js
+++ b/public/v1/js/app.js
@@ -52332,7 +52332,7 @@ exports = module.exports = __webpack_require__(0)(false);
 
 
 // module
-exports.push([module.i, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", ""]);
+exports.push([module.i, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", ""]);
 
 // exports
 
@@ -52483,9 +52483,13 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
             }
         },
         selectedItem: function selectedItem(e) {
+            console.log('selectedItem()');
             if (typeof this.name === 'undefined') {
                 return;
             }
+            if (typeof this.name === 'string') {
+                console.log('Is a string.');
+            }
             // emit the fact that the user selected a type of account
             // (influencing the destination)
             this.$emit('select:account', this.name);
@@ -54888,7 +54892,7 @@ exports = module.exports = __webpack_require__(0)(false);
 
 
 // module
-exports.push([module.i, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", ""]);
+exports.push([module.i, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", ""]);
 
 // exports
 
@@ -55160,12 +55164,12 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
             var destName = void 0;
             var date = void 0;
 
-            sourceId = this.transactions[index].source_account.id;
-            sourceName = this.transactions[index].source_account.name;
-            destId = this.transactions[index].destination_account.id;
-            destName = this.transactions[index].destination_account.name;
+            sourceId = row.source_account.id;
+            sourceName = row.source_account.name;
+            destId = row.destination_account.id;
+            destName = row.destination_account.name;
 
-            date = this.transactions[index].date;
+            date = row.date;
             if (index > 0) {
                 date = this.transactions[0].date;
             }
@@ -55180,13 +55184,13 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
                 sourceId = window.cashAccountId;
             }
 
-            // if index is over 0 and type is withdrawal or transfer, take source from key 0.
+            // if index is over 0 and type is withdrawal or transfer, take source from index 0.
             if (index > 0 && (transactionType.toLowerCase() === 'withdrawal' || transactionType.toLowerCase() === 'transfer')) {
                 sourceId = this.transactions[0].source_account.id;
                 sourceName = this.transactions[0].source_account.name;
             }
 
-            // if index is over 0 and type is deposit or transfer, take destination from key 0.
+            // if index is over 0 and type is deposit or transfer, take destination from index 0.
             if (index > 0 && (transactionType.toLowerCase() === 'deposit' || transactionType.toLowerCase() === 'transfer')) {
                 destId = this.transactions[0].destination_account.id;
                 destName = this.transactions[0].destination_account.name;
@@ -55236,9 +55240,6 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
                 destination_name: destName,
 
                 category_name: row.category,
-                //budget_id: row.budget,
-                //piggy_bank_id: row.piggy_bank,
-
 
                 interest_date: row.custom_fields.interest_date,
                 book_date: row.custom_fields.book_date,
@@ -55324,8 +55325,7 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
 
             console.log('Now incollectAttachmentData()');
             var groupId = response.data.data.id;
-            //console.log(response.data.data.attributes.transactions);
-            //
+
             // array of all files to be uploaded:
             var toBeUploaded = [];
 
@@ -55360,7 +55360,6 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
                     (function (f, i, theParent) {
                         var fileReader = new FileReader();
                         fileReader.onloadend = function (evt) {
-
                             if (evt.target.readyState === FileReader.DONE) {
                                 // DONE == 2
                                 fileData.push({
@@ -55372,20 +55371,6 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
                                     theParent.uploadFiles(fileData, groupId);
                                 }
                             }
-
-                            // // turn into binary strings.
-                            // let chars = new Uint8Array(evt.target.result);
-                            // let CHUNK_SIZE = 0x8000;
-                            // let index = 0;
-                            // let length = chars.length;
-                            // let result = '';
-                            // let slice;
-                            // while (index < length) {
-                            //     slice = chars.subarray(index, Math.min(index + CHUNK_SIZE, length));
-                            //     result += String.fromCharCode.apply(null, slice);
-                            //     index += CHUNK_SIZE;
-                            // }
-                            // console.log('Now reading file #' + key);
                         };
                         fileReader.readAsArrayBuffer(f.file);
                     })(toBeUploaded[_key3], _key3, _this2);
@@ -55603,29 +55588,6 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
             this.transactionType = type;
         },
 
-        // convert to binary stuff
-        arrayBufferToBinary: function arrayBufferToBinary(buffer) {
-            return String.fromCharCode.apply(null, Array.prototype.slice.apply(new Uint8Array(buffer)));
-        },
-
-        binaryToString: function binaryToString(binary) {
-            var error = void 0;
-
-            try {
-                return decodeURIComponent(escape(binary));
-            } catch (_error) {
-                error = _error;
-                if (error instanceof URIError) {
-                    return binary;
-                } else {
-                    throw error;
-                }
-            }
-        },
-
-        // end of convert to binary stuff
-
-
         deleteTransaction: function deleteTransaction(index, event) {
             event.preventDefault();
             for (var _key7 in this.transactions) {
@@ -56415,7 +56377,7 @@ exports = module.exports = __webpack_require__(0)(false);
 
 
 // module
-exports.push([module.i, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", ""]);
+exports.push([module.i, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", ""]);
 
 // exports
 
@@ -56647,49 +56609,45 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
             }
             return amount;
         },
-
         selectedSourceAccount: function selectedSourceAccount(index, model) {
             if (typeof model === 'string') {
                 // cant change types, only name.
+                // also clear ID
+                this.transactions[index].source_account.id = null;
                 this.transactions[index].source_account.name = model;
-            } else {
-                this.transactions[index].source_account = {
-                    id: model.id,
-                    name: model.name,
-                    type: model.type,
-                    currency_id: model.currency_id,
-                    currency_name: model.currency_name,
-                    currency_code: model.currency_code,
-                    currency_decimal_places: model.currency_decimal_places,
-                    allowed_types: this.transactions[index].source_account.allowed_types
-                };
-
-                // force types on destination selector.
-                //this.transactions[index].destination_account.allowed_types = window.allowedOpposingTypes.source[model.type];
+                return;
             }
+            this.transactions[index].source_account = {
+                id: model.id,
+                name: model.name,
+                type: model.type,
+                currency_id: model.currency_id,
+                currency_name: model.currency_name,
+                currency_code: model.currency_code,
+                currency_decimal_places: model.currency_decimal_places,
+                allowed_types: this.transactions[index].source_account.allowed_types
+            };
         },
         selectedDestinationAccount: function selectedDestinationAccount(index, model) {
             if (typeof model === 'string') {
                 // cant change types, only name.
+                // also clear ID
+                this.transactions[index].destination_account.id = null;
                 this.transactions[index].destination_account.name = model;
-            } else {
-                this.transactions[index].destination_account = {
-                    id: model.id,
-                    name: model.name,
-                    type: model.type,
-                    currency_id: model.currency_id,
-                    currency_name: model.currency_name,
-                    currency_code: model.currency_code,
-                    currency_decimal_places: model.currency_decimal_places,
-                    allowed_types: this.transactions[index].destination_account.allowed_types
-                };
-
-                // force types on destination selector.
-                //this.transactions[index].source_account.allowed_types = window.allowedOpposingTypes.destination[model.type];
+                return;
             }
+            this.transactions[index].destination_account = {
+                id: model.id,
+                name: model.name,
+                type: model.type,
+                currency_id: model.currency_id,
+                currency_name: model.currency_name,
+                currency_code: model.currency_code,
+                currency_decimal_places: model.currency_decimal_places,
+                allowed_types: this.transactions[index].destination_account.allowed_types
+            };
         },
         clearSource: function clearSource(index) {
-            console.log('clearSource(' + index + ')');
             // reset source account:
             this.transactions[index].source_account = {
                 id: 0,
@@ -56701,9 +56659,6 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
                 currency_decimal_places: 2,
                 allowed_types: this.transactions[index].source_account.allowed_types
             };
-            // reset destination allowed account types.
-            // this.transactions[index].destination_account.allowed_types = [];
-
             // if there is a destination model, reset the types of the source
             // by pretending we selected it again.
             if (this.transactions[index].destination_account) {
@@ -56716,13 +56671,17 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
         deleteTransaction: function deleteTransaction(index, event) {
             event.preventDefault();
             for (var key in this.transactions) {
-                if (this.transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {}
+                if (this.transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
+                    // TODO empty iff?
+                }
             }
 
             this.transactions.splice(index, 1);
 
             for (var _key in this.transactions) {
-                if (this.transactions.hasOwnProperty(_key) && /^0$|^[1-9]\d*$/.test(_key) && _key <= 4294967294) {}
+                if (this.transactions.hasOwnProperty(_key) && /^0$|^[1-9]\d*$/.test(_key) && _key <= 4294967294) {
+                    // TODO empty iff?
+                }
             }
         },
         clearDestination: function clearDestination(index) {
@@ -56763,102 +56722,100 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
 
             // fill in transactions array.
             axios.get(uri).then(function (response) {
-                console.log(response.data.data);
-                _this.group_title = response.data.data.attributes.group_title;
-                var transactions = response.data.data.attributes.transactions.reverse();
-                for (var key in transactions) {
-                    if (transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
-                        var transaction = transactions[key];
-                        console.log(transactions[key]);
-                        _this.transactions.push({
-                            description: transaction.description,
-                            date: transaction.date.substr(0, 10),
-                            amount: _this.positiveAmount(transaction.amount),
-                            category: transaction.category_name,
-                            errors: {
-                                source_account: [],
-                                destination_account: [],
-                                description: [],
-                                amount: [],
-                                date: [],
-                                budget_id: [],
-                                foreign_amount: [],
-                                category: [],
-                                piggy_bank: [],
-                                tags: [],
-                                // custom fields:
-                                custom_errors: {
-                                    interest_date: [],
-                                    book_date: [],
-                                    process_date: [],
-                                    due_date: [],
-                                    payment_date: [],
-                                    invoice_date: [],
-                                    internal_reference: [],
-                                    notes: [],
-                                    attachments: []
-                                }
-                            },
-                            budget: transaction.budget_id,
-                            tags: transaction.tags,
-                            custom_fields: {
-                                interest_date: transaction.interest_date,
-                                book_date: transaction.book_date,
-                                process_date: transaction.process_date,
-                                due_date: transaction.due_date,
-                                payment_date: transaction.payment_date,
-                                invoice_date: transaction.invoice_date,
-                                internal_reference: transaction.internal_reference,
-                                notes: transaction.notes
-                            },
-                            foreign_amount: {
-                                amount: _this.positiveAmount(transaction.foreign_amount),
-                                currency_id: transaction.foreign_currency_id
-                            },
-                            source_account: {
-                                id: transaction.source_id,
-                                name: transaction.source_name,
-                                type: transaction.source_type,
-                                // i dont know these
-                                currency_id: transaction.currency_id,
-                                currency_name: transaction.currency_name,
-                                currency_code: transaction.currency_code,
-                                currency_decimal_places: transaction.currency_decimal_places,
-                                allowed_types: [transaction.source_type]
-                            },
-                            destination_account: {
-                                id: transaction.destination_id,
-                                name: transaction.destination_name,
-                                type: transaction.destination_type,
-                                currency_id: transaction.currency_id,
-                                currency_name: transaction.currency_name,
-                                currency_code: transaction.currency_code,
-                                currency_decimal_places: transaction.currency_decimal_places,
-                                allowed_types: [transaction.destination_type]
-                            }
-                        });
-                    }
-                }
+                _this.processIncomingGroup(response.data.data);
             }).catch(function (error) {
                 console.error('Some error.');
             });
         },
+        processIncomingGroup: function processIncomingGroup(data) {
+            console.log(data);
+            this.group_title = data.attributes.group_title;
+            var transactions = data.attributes.transactions.reverse();
+            for (var key in transactions) {
+                if (transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
+                    var transaction = transactions[key];
+                    this.processIncomingGroupRow(transaction);
+                }
+            }
+        },
+        processIncomingGroupRow: function processIncomingGroupRow(transaction) {
+            console.log(transaction);
+            this.transactions.push({
+                description: transaction.description,
+                date: transaction.date.substr(0, 10),
+                amount: this.positiveAmount(transaction.amount),
+                category: transaction.category_name,
+                errors: {
+                    source_account: [],
+                    destination_account: [],
+                    description: [],
+                    amount: [],
+                    date: [],
+                    budget_id: [],
+                    foreign_amount: [],
+                    category: [],
+                    piggy_bank: [],
+                    tags: [],
+                    // custom fields:
+                    custom_errors: {
+                        interest_date: [],
+                        book_date: [],
+                        process_date: [],
+                        due_date: [],
+                        payment_date: [],
+                        invoice_date: [],
+                        internal_reference: [],
+                        notes: [],
+                        attachments: []
+                    }
+                },
+                budget: transaction.budget_id,
+                tags: transaction.tags,
+                custom_fields: {
+                    interest_date: transaction.interest_date,
+                    book_date: transaction.book_date,
+                    process_date: transaction.process_date,
+                    due_date: transaction.due_date,
+                    payment_date: transaction.payment_date,
+                    invoice_date: transaction.invoice_date,
+                    internal_reference: transaction.internal_reference,
+                    notes: transaction.notes
+                },
+                foreign_amount: {
+                    amount: this.positiveAmount(transaction.foreign_amount),
+                    currency_id: transaction.foreign_currency_id
+                },
+                source_account: {
+                    id: transaction.source_id,
+                    name: transaction.source_name,
+                    type: transaction.source_type,
+                    // i dont know these
+                    currency_id: transaction.currency_id,
+                    currency_name: transaction.currency_name,
+                    currency_code: transaction.currency_code,
+                    currency_decimal_places: transaction.currency_decimal_places,
+                    allowed_types: [transaction.source_type]
+                },
+                destination_account: {
+                    id: transaction.destination_id,
+                    name: transaction.destination_name,
+                    type: transaction.destination_type,
+                    currency_id: transaction.currency_id,
+                    currency_name: transaction.currency_name,
+                    currency_code: transaction.currency_code,
+                    currency_decimal_places: transaction.currency_decimal_places,
+                    allowed_types: [transaction.destination_type]
+                }
+            });
+        },
+
         convertData: function convertData() {
             var data = {
                 'transactions': []
             };
-            var tagList = [];
             var transactionType = void 0;
             var firstSource = void 0;
             var firstDestination = void 0;
-            var foreignAmount = null;
-            var foreignCurrency = null;
-            var currentArray = void 0;
-            var sourceId = void 0;
-            var sourceName = void 0;
-            var destId = void 0;
-            var destName = void 0;
-            var date = void 0;
 
             if (this.transactions.length > 1) {
                 data.group_title = this.group_title;
@@ -56884,119 +56841,128 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
 
             for (var key in this.transactions) {
                 if (this.transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
-
-                    sourceId = this.transactions[key].source_account.id;
-                    sourceName = this.transactions[key].source_account.name;
-                    destId = this.transactions[key].destination_account.id;
-                    destName = this.transactions[key].destination_account.name;
-
-                    date = this.transactions[key].date;
-                    if (key > 0) {
-                        date = this.transactions[0].date;
-                    }
-
-                    // if type is 'withdrawal' and destination is empty, cash withdrawal.
-                    if (transactionType === 'withdrawal' && '' === destName) {
-                        destId = window.cashAccountId;
-                    }
-
-                    // if type is 'deposit' and source is empty, cash deposit.
-                    if (transactionType === 'deposit' && '' === sourceName) {
-                        sourceId = window.cashAccountId;
-                    }
-
-                    // if key is over 0 and type is withdrawal or transfer, take source from key 0.
-                    if (key > 0 && (transactionType.toLowerCase() === 'withdrawal' || transactionType.toLowerCase() === 'transfer')) {
-                        sourceId = this.transactions[0].source_account.id;
-                        sourceName = this.transactions[0].source_account.name;
-                    }
-
-                    // if key is over 0 and type is deposit or transfer, take destination from key 0.
-                    if (key > 0 && (transactionType.toLowerCase() === 'deposit' || transactionType.toLowerCase() === 'transfer')) {
-                        destId = this.transactions[0].destination_account.id;
-                        destName = this.transactions[0].destination_account.name;
-                    }
-
-                    tagList = [];
-                    foreignAmount = null;
-                    foreignCurrency = null;
-                    // loop tags
-                    for (var tagKey in this.transactions[key].tags) {
-                        if (this.transactions[key].tags.hasOwnProperty(tagKey) && /^0$|^[1-9]\d*$/.test(tagKey) && key <= 4294967294) {
-                            tagList.push(this.transactions[key].tags[tagKey].text);
-                        }
-                    }
-
-                    // set foreign currency info:
-                    if (this.transactions[key].foreign_amount.amount !== '' && parseFloat(this.transactions[key].foreign_amount.amount) !== .00) {
-                        foreignAmount = this.transactions[key].foreign_amount.amount;
-                        foreignCurrency = this.transactions[key].foreign_amount.currency_id;
-                    }
-                    if (foreignCurrency === this.transactions[key].currency_id) {
-                        foreignAmount = null;
-                        foreignCurrency = null;
-                    }
-
-                    // correct some id's
-                    if (0 === destId) {
-                        destId = null;
-                    }
-                    if (0 === sourceId) {
-                        sourceId = null;
-                    }
-
-                    currentArray = {
-                        type: transactionType,
-                        date: date,
-
-                        amount: this.transactions[key].amount,
-                        currency_id: this.transactions[key].currency_id,
-
-                        description: this.transactions[key].description,
-
-                        source_id: sourceId,
-                        source_name: sourceName,
-
-                        destination_id: destId,
-                        destination_name: destName,
-
-                        category_name: this.transactions[key].category,
-                        //budget_id: this.transactions[key].budget,
-                        //piggy_bank_id: this.transactions[key].piggy_bank,
-
-
-                        interest_date: this.transactions[key].custom_fields.interest_date,
-                        book_date: this.transactions[key].custom_fields.book_date,
-                        process_date: this.transactions[key].custom_fields.process_date,
-                        due_date: this.transactions[key].custom_fields.due_date,
-                        payment_date: this.transactions[key].custom_fields.payment_date,
-                        invoice_date: this.transactions[key].custom_fields.invoice_date,
-                        internal_reference: this.transactions[key].custom_fields.internal_reference,
-                        notes: this.transactions[key].custom_fields.notes
-                    };
-
-                    if (tagList.length > 0) {
-                        currentArray.tags = tagList;
-                    }
-                    if (null !== foreignAmount) {
-                        currentArray.foreign_amount = foreignAmount;
-                        currentArray.foreign_currency_id = foreignCurrency;
-                    }
-                    // set budget id and piggy ID.
-                    if (parseInt(this.transactions[key].budget) > 0) {
-                        currentArray.budget_id = parseInt(this.transactions[key].budget);
-                    }
-                    if (parseInt(this.transactions[key].piggy_bank) > 0) {
-                        currentArray.piggy_bank_id = parseInt(this.transactions[key].piggy_bank);
-                    }
-
-                    data.transactions.push(currentArray);
+                    data.transactions.push(this.convertDataRow(this.transactions[key], key, transactionType));
                 }
             }
             //console.log(data);
 
             return data;
         },
+        convertDataRow: function convertDataRow(row, index, transactionType) {
+            var tagList = [];
+            var foreignAmount = null;
+            var foreignCurrency = null;
+            var currentArray = void 0;
+            var sourceId = void 0;
+            var sourceName = void 0;
+            var destId = void 0;
+            var destName = void 0;
+            var date = void 0;
+            sourceId = row.source_account.id;
+            sourceName = row.source_account.name;
+            destId = row.destination_account.id;
+            destName = row.destination_account.name;
+
+            date = row.date;
+            if (index > 0) {
+                date = this.transactions[0].date;
+            }
+
+            // if type is 'withdrawal' and destination is empty, cash withdrawal.
+            if (transactionType === 'withdrawal' && '' === destName) {
+                destId = window.cashAccountId;
+            }
+
+            // if type is 'deposit' and source is empty, cash deposit.
+            if (transactionType === 'deposit' && '' === sourceName) {
+                sourceId = window.cashAccountId;
+            }
+
+            // if index is over 0 and type is withdrawal or transfer, take source from index 0.
+            if (index > 0 && (transactionType.toLowerCase() === 'withdrawal' || transactionType.toLowerCase() === 'transfer')) {
+                sourceId = this.transactions[0].source_account.id;
+                sourceName = this.transactions[0].source_account.name;
+            }
+
+            // if index is over 0 and type is deposit or transfer, take destination from index 0.
+            if (index > 0 && (transactionType.toLowerCase() === 'deposit' || transactionType.toLowerCase() === 'transfer')) {
+                destId = this.transactions[0].destination_account.id;
+                destName = this.transactions[0].destination_account.name;
+            }
+
+            tagList = [];
+            foreignAmount = null;
+            foreignCurrency = null;
+            // loop tags
+            for (var tagKey in row.tags) {
+                if (row.tags.hasOwnProperty(tagKey) && /^0$|^[1-9]\d*$/.test(tagKey) && tagKey <= 4294967294) {
+                    tagList.push(row.tags[tagKey].text);
+                }
+            }
+
+            // set foreign currency info:
+            if (row.foreign_amount.amount !== '' && parseFloat(row.foreign_amount.amount) !== .00) {
+                foreignAmount = row.foreign_amount.amount;
+                foreignCurrency = row.foreign_amount.currency_id;
+            }
+            if (foreignCurrency === row.currency_id) {
+                foreignAmount = null;
+                foreignCurrency = null;
+            }
+
+            // correct some id's
+            if (0 === destId) {
+                destId = null;
+            }
+            if (0 === sourceId) {
+                sourceId = null;
+            }
+
+            currentArray = {
+                type: transactionType,
+                date: date,
+
+                amount: row.amount,
+                currency_id: row.currency_id,
+
+                description: row.description,
+
+                source_id: sourceId,
+                source_name: sourceName,
+
+                destination_id: destId,
+                destination_name: destName,
+
+                category_name: row.category,
+
+                interest_date: row.custom_fields.interest_date,
+                book_date: row.custom_fields.book_date,
+                process_date: row.custom_fields.process_date,
+                due_date: row.custom_fields.due_date,
+                payment_date: row.custom_fields.payment_date,
+                invoice_date: row.custom_fields.invoice_date,
+                internal_reference: row.custom_fields.internal_reference,
+                notes: row.custom_fields.notes
+            };
+
+            if (tagList.length > 0) {
+                currentArray.tags = tagList;
+            }
+            if (null !== foreignAmount) {
+                currentArray.foreign_amount = foreignAmount;
+                currentArray.foreign_currency_id = foreignCurrency;
+            }
+            // set budget id and piggy ID.
+            if (parseInt(row.budget) > 0) {
+                currentArray.budget_id = parseInt(row.budget);
+            }
+            if (parseInt(row.piggy_bank) > 0) {
+                currentArray.piggy_bank_id = parseInt(row.piggy_bank);
+            }
+
+            return currentArray;
+        },
+
         submit: function submit(e) {
             var _this2 = this;
 
@@ -57010,18 +56976,20 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
             button.prop("disabled", true);
 
             axios.put(uri, data).then(function (response) {
-                if (_this2.returnAfter) {
-                    // do message:
-                    _this2.success_message = 'The transaction has been updated.';
-                    _this2.error_message = '';
-                    button.prop("disabled", false);
-                    // TODO better
-                    if (_this2.resetFormAfter) {
-                        _this2.getGroup();
-                    }
-                } else {
-                    window.location.href = 'transactions/show/' + response.data.data.id + '?message=updated';
+
+                if (0 === _this2.collectAttachmentData(response)) {
+                    _this2.redirectUser(response.data.data.id, button);
                 }
+
+                // if (this.returnAfter) {
+                //     this.setDefaultErrors();
+                //     // do message:
+                //     this.success_message = 'The transaction has been updated.';
+                //     this.error_message = '';
+                //     button.prop("disabled", false);
+                // } else {
+                //     window.location.href = 'transactions/show/' + response.data.data.id + '?message=updated';
+                // }
             }).catch(function (error) {
                 // give user errors things back.
                 // something something render errors.
@@ -57033,6 +57001,128 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
                 e.preventDefault();
             }
         },
+
+        redirectUser: function redirectUser(groupId, button) {
+            console.log('In redirectUser()');
+            // if count is 0, send user onwards.
+
+            if (this.returnAfter) {
+                this.setDefaultErrors();
+                // do message:
+                this.success_message = 'The transaction has been updated.';
+                this.error_message = '';
+                button.prop("disabled", false);
+            } else {
+                window.location.href = 'transactions/show/' + groupId + '?message=updated';
+            }
+        },
+        collectAttachmentData: function collectAttachmentData(response) {
+            var _this3 = this;
+
+            console.log('Now incollectAttachmentData()');
+            var groupId = response.data.data.id;
+
+            // array of all files to be uploaded:
+            var toBeUploaded = [];
+
+            // array with all file data.
+            var fileData = [];
+
+            // all attachments
+            var attachments = $('input[name="attachments[]"]');
+
+            // loop over all attachments, and add references to this array:
+            for (var key in attachments) {
+                if (attachments.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
+                    for (var fileKey in attachments[key].files) {
+                        if (attachments[key].files.hasOwnProperty(fileKey) && /^0$|^[1-9]\d*$/.test(fileKey) && fileKey <= 4294967294) {
+                            // include journal thing.
+                            toBeUploaded.push({
+                                journal: response.data.data.attributes.transactions[key].transaction_journal_id,
+                                file: attachments[key].files[fileKey]
+                            });
+                        }
+                    }
+                }
+            }
+            var count = toBeUploaded.length;
+            console.log('Found ' + toBeUploaded.length + ' attachments.');
+
+            // loop all uploads.
+
+            var _loop = function _loop(_key2) {
+                if (toBeUploaded.hasOwnProperty(_key2) && /^0$|^[1-9]\d*$/.test(_key2) && _key2 <= 4294967294) {
+                    // create file reader thing that will read all of these uploads
+                    (function (f, i, theParent) {
+                        var fileReader = new FileReader();
+                        fileReader.onloadend = function (evt) {
+                            if (evt.target.readyState === FileReader.DONE) {
+                                // DONE == 2
+                                fileData.push({
+                                    name: toBeUploaded[_key2].file.name,
+                                    journal: toBeUploaded[_key2].journal,
+                                    content: new Blob([evt.target.result])
+                                });
+                                if (fileData.length === count) {
+                                    theParent.uploadFiles(fileData, groupId);
+                                }
+                            }
+                        };
+                        fileReader.readAsArrayBuffer(f.file);
+                    })(toBeUploaded[_key2], _key2, _this3);
+                }
+            };
+
+            for (var _key2 in toBeUploaded) {
+                _loop(_key2);
+            }
+            return count;
+        },
+        uploadFiles: function uploadFiles(fileData, groupId) {
+            var _this4 = this;
+
+            var count = fileData.length;
+            var uploads = 0;
+
+            var _loop2 = function _loop2(key) {
+                if (fileData.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
+                    console.log('Creating attachment #' + key);
+                    // axios thing, + then.
+                    var uri = './api/v1/attachments';
+                    var data = {
+                        filename: fileData[key].name,
+                        model: 'TransactionJournal',
+                        model_id: fileData[key].journal
+                    };
+                    axios.post(uri, data).then(function (response) {
+                        console.log('Created attachment #' + key);
+                        console.log('Uploading attachment #' + key);
+                        var uploadUri = './api/v1/attachments/' + response.data.data.id + '/upload';
+                        axios.post(uploadUri, fileData[key].content).then(function (response) {
+                            console.log('Uploaded attachment #' + key);
+                            uploads++;
+                            if (uploads === count) {
+                                // finally we can redirect the user onwards.
+                                console.log('FINAL UPLOAD');
+                                _this4.redirectUser(groupId);
+                            }
+                            console.log('Upload complete!');
+                            return true;
+                        }).catch(function (error) {
+                            console.error('Could not upload');
+                            console.error(error);
+                            return false;
+                        });
+                    });
+                }
+            };
+
+            for (var key in fileData) {
+                _loop2(key);
+            }
+        },
+
+
         addTransaction: function addTransaction(e) {
             this.transactions.push({
                 description: "",
@@ -57105,6 +57195,82 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
             if (e) {
                 e.preventDefault();
             }
+        },
+        parseErrors: function parseErrors(errors) {
+            this.setDefaultErrors();
+            this.error_message = "";
+            if (errors.message.length > 0) {
+                this.error_message = "There was something wrong with your submission. Please check out the errors below.";
+            } else {
+                this.error_message = '';
+            }
+            var transactionIndex = void 0;
+            var fieldName = void 0;
+
+            for (var key in errors.errors) {
+                if (errors.errors.hasOwnProperty(key)) {
+                    if (key === 'group_title') {
+                        this.group_title_errors = errors.errors[key];
+                    }
+                    if (key !== 'group_title') {
+                        // lol dumbest way to explode "transactions.0.something" ever.
+                        transactionIndex = parseInt(key.split('.')[1]);
+                        fieldName = key.split('.')[2];
+                        // set error in this object thing.
+                        switch (fieldName) {
+                            case 'amount':
+                            case 'date':
+                            case 'budget_id':
+                            case 'description':
+                            case 'tags':
+                                this.transactions[transactionIndex].errors[fieldName] = errors.errors[key];
+                                break;
+                            case 'source_name':
+                            case 'source_id':
+                                this.transactions[transactionIndex].errors.source_account = this.transactions[transactionIndex].errors.source_account.concat(errors.errors[key]);
+                                break;
+                            case 'destination_name':
+                            case 'destination_id':
+                                this.transactions[transactionIndex].errors.destination_account = this.transactions[transactionIndex].errors.destination_account.concat(errors.errors[key]);
+                                break;
+                            case 'foreign_amount':
+                            case 'foreign_currency_id':
+                                this.transactions[transactionIndex].errors.foreign_amount = this.transactions[transactionIndex].errors.foreign_amount.concat(errors.errors[key]);
+                                break;
+                        }
+                    }
+                }
+            }
+        },
+        setDefaultErrors: function setDefaultErrors() {
+            for (var key in this.transactions) {
+                if (this.transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
+                    this.transactions[key].errors = {
+                        source_account: [],
+                        destination_account: [],
+                        description: [],
+                        amount: [],
+                        date: [],
+                        budget_id: [],
+                        foreign_amount: [],
+                        category: [],
+                        piggy_bank: [],
+                        tags: [],
+                        // custom fields:
+                        custom_errors: {
+                            interest_date: [],
+                            book_date: [],
+                            process_date: [],
+                            due_date: [],
+                            payment_date: [],
+                            invoice_date: [],
+                            internal_reference: [],
+                            notes: [],
+                            attachments: []
+                        }
+                    };
+                }
+            }
         }
     },
 
@@ -57537,7 +57703,7 @@ var render = function() {
                     }
                   }),
                   _vm._v(
-                    "\n                            After updating, return here to create another one.\n                        "
+                    "\n                            After updating, return here to continue editing.\n                        "
                   )
                 ])
               ])
diff --git a/resources/assets/js/components/transactions/AccountSelect.vue b/resources/assets/js/components/transactions/AccountSelect.vue
index d766058991..41603dc789 100644
--- a/resources/assets/js/components/transactions/AccountSelect.vue
+++ b/resources/assets/js/components/transactions/AccountSelect.vue
@@ -138,9 +138,13 @@
                     }
                 },
                 selectedItem: function (e) {
+                    console.log('selectedItem()');
                     if (typeof this.name === 'undefined') {
                         return;
                     }
+                    if(typeof this.name === 'string') {
+                        console.log('Is a string.');
+                    }
                     // emit the fact that the user selected a type of account
                     // (influencing the destination)
                     this.$emit('select:account', this.name);
diff --git a/resources/assets/js/components/transactions/CreateTransaction.vue b/resources/assets/js/components/transactions/CreateTransaction.vue
index ed14ae407d..1347ee3f50 100644
--- a/resources/assets/js/components/transactions/CreateTransaction.vue
+++ b/resources/assets/js/components/transactions/CreateTransaction.vue
@@ -260,12 +260,12 @@
                 let destName;
                 let date;
 
-                sourceId = this.transactions[index].source_account.id;
-                sourceName = this.transactions[index].source_account.name;
-                destId = this.transactions[index].destination_account.id;
-                destName = this.transactions[index].destination_account.name;
+                sourceId = row.source_account.id;
+                sourceName = row.source_account.name;
+                destId = row.destination_account.id;
+                destName = row.destination_account.name;
 
-                date = this.transactions[index].date;
+                date = row.date;
                 if (index > 0) {
                     date = this.transactions[0].date;
                 }
@@ -280,13 +280,13 @@
                     sourceId = window.cashAccountId;
                 }
 
-                // if index is over 0 and type is withdrawal or transfer, take source from key 0.
+                // if index is over 0 and type is withdrawal or transfer, take source from index 0.
                 if (index > 0 && (transactionType.toLowerCase() === 'withdrawal' || transactionType.toLowerCase() === 'transfer')) {
                     sourceId = this.transactions[0].source_account.id;
                     sourceName = this.transactions[0].source_account.name;
                 }
 
-                // if index is over 0 and type is deposit or transfer, take destination from key 0.
+                // if index is over 0 and type is deposit or transfer, take destination from index 0.
                 if (index > 0 && (transactionType.toLowerCase() === 'deposit' || transactionType.toLowerCase() === 'transfer')) {
                     destId = this.transactions[0].destination_account.id;
                     destName = this.transactions[0].destination_account.name;
@@ -338,9 +338,6 @@
 
 
                         category_name: row.category,
-                        //budget_id: row.budget,
-                        //piggy_bank_id: row.piggy_bank,
-
 
                         interest_date: row.custom_fields.interest_date,
                         book_date: row.custom_fields.book_date,
@@ -422,8 +419,7 @@
             collectAttachmentData(response) {
                 console.log('Now incollectAttachmentData()');
                 let groupId = response.data.data.id;
-                //console.log(response.data.data.attributes.transactions);
-                //
+
                 // array of all files to be uploaded:
                 let toBeUploaded = [];
 
@@ -457,10 +453,8 @@
                     if (toBeUploaded.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
                         // create file reader thing that will read all of these uploads
                         (function (f, i, theParent) {
-                            var fileReader = new FileReader();
+                            let fileReader = new FileReader();
                             fileReader.onloadend = function (evt) {
-
-
                                 if (evt.target.readyState === FileReader.DONE) { // DONE == 2
                                     fileData.push(
                                         {
@@ -473,22 +467,7 @@
                                         theParent.uploadFiles(fileData, groupId);
                                     }
                                 }
-
-                                // // turn into binary strings.
-                                // let chars = new Uint8Array(evt.target.result);
-                                // let CHUNK_SIZE = 0x8000;
-                                // let index = 0;
-                                // let length = chars.length;
-                                // let result = '';
-                                // let slice;
-                                // while (index < length) {
-                                //     slice = chars.subarray(index, Math.min(index + CHUNK_SIZE, length));
-                                //     result += String.fromCharCode.apply(null, slice);
-                                //     index += CHUNK_SIZE;
-                                // }
-                                // console.log('Now reading file #' + key);
-
-                            }
+                            };
                             fileReader.readAsArrayBuffer(f.file);
                         })(toBeUploaded[key], key, this);
                     }
@@ -701,28 +680,6 @@
                 this.transactionType = type;
             },
 
-            // convert to binary stuff
-            arrayBufferToBinary(buffer) {
-                return String.fromCharCode.apply(null, Array.prototype.slice.apply(new Uint8Array(buffer)));
-            },
-            binaryToString: function (binary) {
-                let error;
-
-                try {
-                    return decodeURIComponent(escape(binary));
-                } catch (_error) {
-                    error = _error;
-                    if (error instanceof URIError) {
-                        return binary;
-                    } else {
-                        throw error;
-                    }
-                }
-            },
-
-            // end of convert to binary stuff
-
-
             deleteTransaction: function (index, event) {
                 event.preventDefault();
                 for (const key in this.transactions) {
diff --git a/resources/assets/js/components/transactions/EditTransaction.vue b/resources/assets/js/components/transactions/EditTransaction.vue
index 2453aa2e73..a044b8af33 100644
--- a/resources/assets/js/components/transactions/EditTransaction.vue
+++ b/resources/assets/js/components/transactions/EditTransaction.vue
@@ -184,7 +184,7 @@
                         
@@ -212,55 +212,51 @@ console.log('Ready Group ID: ' + this.groupId); }, methods: { - positiveAmount: function (amount) { + positiveAmount(amount) { if (amount < 0) { return amount * -1; } return amount; }, - - selectedSourceAccount: function (index, model) { + selectedSourceAccount(index, model) { if (typeof model === 'string') { // cant change types, only name. + // also clear ID + this.transactions[index].source_account.id = null; this.transactions[index].source_account.name = model; - } else { - this.transactions[index].source_account = { - id: model.id, - name: model.name, - type: model.type, - currency_id: model.currency_id, - currency_name: model.currency_name, - currency_code: model.currency_code, - currency_decimal_places: model.currency_decimal_places, - allowed_types: this.transactions[index].source_account.allowed_types - }; - - // force types on destination selector. - //this.transactions[index].destination_account.allowed_types = window.allowedOpposingTypes.source[model.type]; + return; } + this.transactions[index].source_account = { + id: model.id, + name: model.name, + type: model.type, + currency_id: model.currency_id, + currency_name: model.currency_name, + currency_code: model.currency_code, + currency_decimal_places: model.currency_decimal_places, + allowed_types: this.transactions[index].source_account.allowed_types + }; }, - selectedDestinationAccount: function (index, model) { + selectedDestinationAccount(index, model) { if (typeof model === 'string') { // cant change types, only name. + // also clear ID + this.transactions[index].destination_account.id = null; this.transactions[index].destination_account.name = model; - } else { - this.transactions[index].destination_account = { - id: model.id, - name: model.name, - type: model.type, - currency_id: model.currency_id, - currency_name: model.currency_name, - currency_code: model.currency_code, - currency_decimal_places: model.currency_decimal_places, - allowed_types: this.transactions[index].destination_account.allowed_types - }; - - // force types on destination selector. - //this.transactions[index].source_account.allowed_types = window.allowedOpposingTypes.destination[model.type]; + return; } + this.transactions[index].destination_account = { + id: model.id, + name: model.name, + type: model.type, + currency_id: model.currency_id, + currency_name: model.currency_name, + currency_code: model.currency_code, + currency_decimal_places: model.currency_decimal_places, + allowed_types: this.transactions[index].destination_account.allowed_types + }; }, - clearSource: function (index) { - console.log('clearSource(' + index + ')'); + clearSource(index) { // reset source account: this.transactions[index].source_account = { id: 0, @@ -272,23 +268,21 @@ currency_decimal_places: 2, allowed_types: this.transactions[index].source_account.allowed_types }; - // reset destination allowed account types. - // this.transactions[index].destination_account.allowed_types = []; - // if there is a destination model, reset the types of the source // by pretending we selected it again. if (this.transactions[index].destination_account) { this.selectedDestinationAccount(index, this.transactions[index].destination_account); } }, - setTransactionType: function (type) { + setTransactionType(type) { this.transactionType = type; }, - deleteTransaction: function (index, event) { + deleteTransaction(index, event) { event.preventDefault(); for (const key in this.transactions) { if ( this.transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) { + // TODO empty iff? } } @@ -297,10 +291,11 @@ for (const key in this.transactions) { if ( this.transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) { + // TODO empty iff? } } }, - clearDestination: function (index) { + clearDestination(index) { console.log('clearDestination(' + index + ')'); // reset destination account: console.log('Destination allowed types first:'); @@ -327,7 +322,7 @@ console.log('Destination allowed types after:'); console.log(this.transactions[index].destination_account.allowed_types); }, - getGroup: function () { + getGroup() { const page = window.location.href.split('/'); const groupId = page[page.length - 1]; @@ -339,104 +334,101 @@ // fill in transactions array. axios.get(uri) .then(response => { - console.log(response.data.data); - this.group_title = response.data.data.attributes.group_title; - let transactions = response.data.data.attributes.transactions.reverse(); - for (let key in transactions) { - if (transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) { - let transaction = transactions[key]; - console.log(transactions[key]); - this.transactions.push({ - description: transaction.description, - date: transaction.date.substr(0, 10), - amount: this.positiveAmount(transaction.amount), - category: transaction.category_name, - errors: { - source_account: [], - destination_account: [], - description: [], - amount: [], - date: [], - budget_id: [], - foreign_amount: [], - category: [], - piggy_bank: [], - tags: [], - // custom fields: - custom_errors: { - interest_date: [], - book_date: [], - process_date: [], - due_date: [], - payment_date: [], - invoice_date: [], - internal_reference: [], - notes: [], - attachments: [], - }, - }, - budget: transaction.budget_id, - tags: transaction.tags, - custom_fields: { - interest_date: transaction.interest_date, - book_date: transaction.book_date, - process_date: transaction.process_date, - due_date: transaction.due_date, - payment_date: transaction.payment_date, - invoice_date: transaction.invoice_date, - internal_reference: transaction.internal_reference, - notes: transaction.notes - }, - foreign_amount: { - amount: this.positiveAmount(transaction.foreign_amount), - currency_id: transaction.foreign_currency_id - }, - source_account: { - id: transaction.source_id, - name: transaction.source_name, - type: transaction.source_type, - // i dont know these - currency_id: transaction.currency_id, - currency_name: transaction.currency_name, - currency_code: transaction.currency_code, - currency_decimal_places: transaction.currency_decimal_places, - allowed_types: [transaction.source_type] - }, - destination_account: { - id: transaction.destination_id, - name: transaction.destination_name, - type: transaction.destination_type, - currency_id: transaction.currency_id, - currency_name: transaction.currency_name, - currency_code: transaction.currency_code, - currency_decimal_places: transaction.currency_decimal_places, - allowed_types: [transaction.destination_type] - } - }); - } - - } + this.processIncomingGroup(response.data.data); }) .catch(error => { console.error('Some error.'); }); }, + processIncomingGroup(data) { + console.log(data); + this.group_title = data.attributes.group_title; + let transactions = data.attributes.transactions.reverse(); + for (let key in transactions) { + if (transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) { + let transaction = transactions[key]; + this.processIncomingGroupRow(transaction); + } + + } + }, + processIncomingGroupRow(transaction) { + console.log(transaction); + this.transactions.push({ + description: transaction.description, + date: transaction.date.substr(0, 10), + amount: this.positiveAmount(transaction.amount), + category: transaction.category_name, + errors: { + source_account: [], + destination_account: [], + description: [], + amount: [], + date: [], + budget_id: [], + foreign_amount: [], + category: [], + piggy_bank: [], + tags: [], + // custom fields: + custom_errors: { + interest_date: [], + book_date: [], + process_date: [], + due_date: [], + payment_date: [], + invoice_date: [], + internal_reference: [], + notes: [], + attachments: [], + }, + }, + budget: transaction.budget_id, + tags: transaction.tags, + custom_fields: { + interest_date: transaction.interest_date, + book_date: transaction.book_date, + process_date: transaction.process_date, + due_date: transaction.due_date, + payment_date: transaction.payment_date, + invoice_date: transaction.invoice_date, + internal_reference: transaction.internal_reference, + notes: transaction.notes + }, + foreign_amount: { + amount: this.positiveAmount(transaction.foreign_amount), + currency_id: transaction.foreign_currency_id + }, + source_account: { + id: transaction.source_id, + name: transaction.source_name, + type: transaction.source_type, + // i dont know these + currency_id: transaction.currency_id, + currency_name: transaction.currency_name, + currency_code: transaction.currency_code, + currency_decimal_places: transaction.currency_decimal_places, + allowed_types: [transaction.source_type] + }, + destination_account: { + id: transaction.destination_id, + name: transaction.destination_name, + type: transaction.destination_type, + currency_id: transaction.currency_id, + currency_name: transaction.currency_name, + currency_code: transaction.currency_code, + currency_decimal_places: transaction.currency_decimal_places, + allowed_types: [transaction.destination_type] + } + }); + }, convertData: function () { let data = { 'transactions': [], }; - let tagList = []; let transactionType; let firstSource; let firstDestination; - let foreignAmount = null; - let foreignCurrency = null; - let currentArray; - let sourceId; - let sourceName; - let destId; - let destName; - let date; if (this.transactions.length > 1) { data.group_title = this.group_title; @@ -460,124 +452,131 @@ transactionType = 'deposit'; } - for (let key in this.transactions) { if (this.transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) { - - sourceId = this.transactions[key].source_account.id; - sourceName = this.transactions[key].source_account.name; - destId = this.transactions[key].destination_account.id; - destName = this.transactions[key].destination_account.name; - - date = this.transactions[key].date; - if (key > 0) { - date = this.transactions[0].date; - } - - // if type is 'withdrawal' and destination is empty, cash withdrawal. - if (transactionType === 'withdrawal' && '' === destName) { - destId = window.cashAccountId; - } - - // if type is 'deposit' and source is empty, cash deposit. - if (transactionType === 'deposit' && '' === sourceName) { - sourceId = window.cashAccountId; - } - - // if key is over 0 and type is withdrawal or transfer, take source from key 0. - if (key > 0 && (transactionType.toLowerCase() === 'withdrawal' || transactionType.toLowerCase() === 'transfer')) { - sourceId = this.transactions[0].source_account.id; - sourceName = this.transactions[0].source_account.name; - } - - // if key is over 0 and type is deposit or transfer, take destination from key 0. - if (key > 0 && (transactionType.toLowerCase() === 'deposit' || transactionType.toLowerCase() === 'transfer')) { - destId = this.transactions[0].destination_account.id; - destName = this.transactions[0].destination_account.name; - } - - tagList = []; - foreignAmount = null; - foreignCurrency = null; - // loop tags - for (let tagKey in this.transactions[key].tags) { - if (this.transactions[key].tags.hasOwnProperty(tagKey) && /^0$|^[1-9]\d*$/.test(tagKey) && key <= 4294967294) { - tagList.push(this.transactions[key].tags[tagKey].text); - } - } - - // set foreign currency info: - if (this.transactions[key].foreign_amount.amount !== '' && parseFloat(this.transactions[key].foreign_amount.amount) !== .00) { - foreignAmount = this.transactions[key].foreign_amount.amount; - foreignCurrency = this.transactions[key].foreign_amount.currency_id; - } - if (foreignCurrency === this.transactions[key].currency_id) { - foreignAmount = null; - foreignCurrency = null; - } - - // correct some id's - if (0 === destId) { - destId = null; - } - if (0 === sourceId) { - sourceId = null; - } - - currentArray = - { - type: transactionType, - date: date, - - amount: this.transactions[key].amount, - currency_id: this.transactions[key].currency_id, - - description: this.transactions[key].description, - - source_id: sourceId, - source_name: sourceName, - - destination_id: destId, - destination_name: destName, - - - category_name: this.transactions[key].category, - //budget_id: this.transactions[key].budget, - //piggy_bank_id: this.transactions[key].piggy_bank, - - - interest_date: this.transactions[key].custom_fields.interest_date, - book_date: this.transactions[key].custom_fields.book_date, - process_date: this.transactions[key].custom_fields.process_date, - due_date: this.transactions[key].custom_fields.due_date, - payment_date: this.transactions[key].custom_fields.payment_date, - invoice_date: this.transactions[key].custom_fields.invoice_date, - internal_reference: this.transactions[key].custom_fields.internal_reference, - notes: this.transactions[key].custom_fields.notes - }; - - if (tagList.length > 0) { - currentArray.tags = tagList; - } - if (null !== foreignAmount) { - currentArray.foreign_amount = foreignAmount; - currentArray.foreign_currency_id = foreignCurrency; - } - // set budget id and piggy ID. - if (parseInt(this.transactions[key].budget) > 0) { - currentArray.budget_id = parseInt(this.transactions[key].budget); - } - if (parseInt(this.transactions[key].piggy_bank) > 0) { - currentArray.piggy_bank_id = parseInt(this.transactions[key].piggy_bank); - } - - data.transactions.push(currentArray); + data.transactions.push(this.convertDataRow(this.transactions[key], key, transactionType)); } } //console.log(data); return data; }, + convertDataRow(row, index, transactionType) { + let tagList = []; + let foreignAmount = null; + let foreignCurrency = null; + let currentArray; + let sourceId; + let sourceName; + let destId; + let destName; + let date; + sourceId = row.source_account.id; + sourceName = row.source_account.name; + destId = row.destination_account.id; + destName = row.destination_account.name; + + date = row.date; + if (index > 0) { + date = this.transactions[0].date; + } + + // if type is 'withdrawal' and destination is empty, cash withdrawal. + if (transactionType === 'withdrawal' && '' === destName) { + destId = window.cashAccountId; + } + + // if type is 'deposit' and source is empty, cash deposit. + if (transactionType === 'deposit' && '' === sourceName) { + sourceId = window.cashAccountId; + } + + // if index is over 0 and type is withdrawal or transfer, take source from index 0. + if (index > 0 && (transactionType.toLowerCase() === 'withdrawal' || transactionType.toLowerCase() === 'transfer')) { + sourceId = this.transactions[0].source_account.id; + sourceName = this.transactions[0].source_account.name; + } + + // if index is over 0 and type is deposit or transfer, take destination from index 0. + if (index > 0 && (transactionType.toLowerCase() === 'deposit' || transactionType.toLowerCase() === 'transfer')) { + destId = this.transactions[0].destination_account.id; + destName = this.transactions[0].destination_account.name; + } + + tagList = []; + foreignAmount = null; + foreignCurrency = null; + // loop tags + for (let tagKey in row.tags) { + if (row.tags.hasOwnProperty(tagKey) && /^0$|^[1-9]\d*$/.test(tagKey) && tagKey <= 4294967294) { + tagList.push(row.tags[tagKey].text); + } + } + + // set foreign currency info: + if (row.foreign_amount.amount !== '' && parseFloat(row.foreign_amount.amount) !== .00) { + foreignAmount = row.foreign_amount.amount; + foreignCurrency = row.foreign_amount.currency_id; + } + if (foreignCurrency === row.currency_id) { + foreignAmount = null; + foreignCurrency = null; + } + + // correct some id's + if (0 === destId) { + destId = null; + } + if (0 === sourceId) { + sourceId = null; + } + + currentArray = + { + type: transactionType, + date: date, + + amount: row.amount, + currency_id: row.currency_id, + + description: row.description, + + source_id: sourceId, + source_name: sourceName, + + destination_id: destId, + destination_name: destName, + + + category_name: row.category, + + interest_date: row.custom_fields.interest_date, + book_date: row.custom_fields.book_date, + process_date: row.custom_fields.process_date, + due_date: row.custom_fields.due_date, + payment_date: row.custom_fields.payment_date, + invoice_date: row.custom_fields.invoice_date, + internal_reference: row.custom_fields.internal_reference, + notes: row.custom_fields.notes + }; + + if (tagList.length > 0) { + currentArray.tags = tagList; + } + if (null !== foreignAmount) { + currentArray.foreign_amount = foreignAmount; + currentArray.foreign_currency_id = foreignCurrency; + } + // set budget id and piggy ID. + if (parseInt(row.budget) > 0) { + currentArray.budget_id = parseInt(row.budget); + } + if (parseInt(row.piggy_bank) > 0) { + currentArray.piggy_bank_id = parseInt(row.piggy_bank); + } + + return currentArray; + }, submit: function (e) { console.log('I am submit'); const page = window.location.href.split('/'); @@ -590,19 +589,20 @@ axios.put(uri, data) .then(response => { - if (this.returnAfter) { - // do message: - this.success_message = 'The transaction has been updated.'; - this.error_message = ''; - button.prop("disabled", false); - // TODO better - if (this.resetFormAfter) { - this.getGroup(); - } - } else { - window.location.href = 'transactions/show/' + response.data.data.id + '?message=updated'; + if (0 === this.collectAttachmentData(response)) { + this.redirectUser(response.data.data.id, button); } + + // if (this.returnAfter) { + // this.setDefaultErrors(); + // // do message: + // this.success_message = 'The transaction has been updated.'; + // this.error_message = ''; + // button.prop("disabled", false); + // } else { + // window.location.href = 'transactions/show/' + response.data.data.id + '?message=updated'; + // } }).catch(error => { // give user errors things back. // something something render errors. @@ -614,6 +614,122 @@ e.preventDefault(); } }, + + redirectUser(groupId, button) { + console.log('In redirectUser()'); + // if count is 0, send user onwards. + + if (this.returnAfter) { + this.setDefaultErrors(); + // do message: + this.success_message = 'The transaction has been updated.'; + this.error_message = ''; + button.prop("disabled", false); + } else { + window.location.href = 'transactions/show/' + groupId + '?message=updated'; + } + }, + + collectAttachmentData(response) { + console.log('Now incollectAttachmentData()'); + let groupId = response.data.data.id; + + // array of all files to be uploaded: + let toBeUploaded = []; + + // array with all file data. + let fileData = []; + + // all attachments + let attachments = $('input[name="attachments[]"]'); + + // loop over all attachments, and add references to this array: + for (const key in attachments) { + if (attachments.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) { + for (const fileKey in attachments[key].files) { + if (attachments[key].files.hasOwnProperty(fileKey) && /^0$|^[1-9]\d*$/.test(fileKey) && fileKey <= 4294967294) { + // include journal thing. + toBeUploaded.push( + { + journal: response.data.data.attributes.transactions[key].transaction_journal_id, + file: attachments[key].files[fileKey] + } + ); + } + } + } + } + let count = toBeUploaded.length; + console.log('Found ' + toBeUploaded.length + ' attachments.'); + + // loop all uploads. + for (const key in toBeUploaded) { + if (toBeUploaded.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) { + // create file reader thing that will read all of these uploads + (function (f, i, theParent) { + let fileReader = new FileReader(); + fileReader.onloadend = function (evt) { + if (evt.target.readyState === FileReader.DONE) { // DONE == 2 + fileData.push( + { + name: toBeUploaded[key].file.name, + journal: toBeUploaded[key].journal, + content: new Blob([evt.target.result]) + } + ); + if (fileData.length === count) { + theParent.uploadFiles(fileData, groupId); + } + } + }; + fileReader.readAsArrayBuffer(f.file); + })(toBeUploaded[key], key, this); + } + } + return count; + }, + + uploadFiles(fileData, groupId) { + let count = fileData.length; + let uploads = 0; + for (const key in fileData) { + if (fileData.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) { + console.log('Creating attachment #' + key); + // axios thing, + then. + const uri = './api/v1/attachments'; + const data = { + filename: fileData[key].name, + model: 'TransactionJournal', + model_id: fileData[key].journal, + }; + axios.post(uri, data) + .then(response => { + console.log('Created attachment #' + key); + console.log('Uploading attachment #' + key); + const uploadUri = './api/v1/attachments/' + response.data.data.id + '/upload'; + axios.post(uploadUri, fileData[key].content) + .then(response => { + console.log('Uploaded attachment #' + key); + uploads++; + if (uploads === count) { + // finally we can redirect the user onwards. + console.log('FINAL UPLOAD'); + this.redirectUser(groupId); + } + console.log('Upload complete!'); + return true; + }).catch(error => { + console.error('Could not upload'); + console.error(error); + return false; + }); + }); + } + } + + }, + + addTransaction: function (e) { this.transactions.push({ description: "", @@ -686,7 +802,86 @@ if (e) { e.preventDefault(); } - } + }, + parseErrors: function (errors) { + this.setDefaultErrors(); + this.error_message = ""; + if (errors.message.length > 0) { + this.error_message = "There was something wrong with your submission. Please check out the errors below."; + } else { + this.error_message = ''; + } + let transactionIndex; + let fieldName; + + for (const key in errors.errors) { + if (errors.errors.hasOwnProperty(key)) { + if (key === 'group_title') { + this.group_title_errors = errors.errors[key]; + } + if (key !== 'group_title') { + // lol dumbest way to explode "transactions.0.something" ever. + transactionIndex = parseInt(key.split('.')[1]); + fieldName = key.split('.')[2]; + // set error in this object thing. + switch (fieldName) { + case 'amount': + case 'date': + case 'budget_id': + case 'description': + case 'tags': + this.transactions[transactionIndex].errors[fieldName] = errors.errors[key]; + break; + case 'source_name': + case 'source_id': + this.transactions[transactionIndex].errors.source_account = + this.transactions[transactionIndex].errors.source_account.concat(errors.errors[key]); + break; + case 'destination_name': + case 'destination_id': + this.transactions[transactionIndex].errors.destination_account = + this.transactions[transactionIndex].errors.destination_account.concat(errors.errors[key]); + break; + case 'foreign_amount': + case 'foreign_currency_id': + this.transactions[transactionIndex].errors.foreign_amount = + this.transactions[transactionIndex].errors.foreign_amount.concat(errors.errors[key]); + break; + } + } + } + } + }, + setDefaultErrors: function () { + for (const key in this.transactions) { + if (this.transactions.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) { + this.transactions[key].errors = { + source_account: [], + destination_account: [], + description: [], + amount: [], + date: [], + budget_id: [], + foreign_amount: [], + category: [], + piggy_bank: [], + tags: [], + // custom fields: + custom_errors: { + interest_date: [], + book_date: [], + process_date: [], + due_date: [], + payment_date: [], + invoice_date: [], + internal_reference: [], + notes: [], + attachments: [], + }, + }; + } + } + }, }, diff --git a/tests/Feature/Controllers/Transaction/ConvertControllerTest.php b/tests/Feature/Controllers/Transaction/ConvertControllerTest.php index 4aa908a009..57e17494c9 100644 --- a/tests/Feature/Controllers/Transaction/ConvertControllerTest.php +++ b/tests/Feature/Controllers/Transaction/ConvertControllerTest.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace Tests\Feature\Controllers\Transaction; use Amount; -use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\Account\AccountRepositoryInterface; @@ -35,7 +34,6 @@ use FireflyIII\Repositories\User\UserRepositoryInterface; use FireflyIII\Transformers\TransactionGroupTransformer; use FireflyIII\Validation\AccountValidator; use Illuminate\Support\Collection; -use Illuminate\Support\MessageBag; use Log; use Mockery; use Preferences; diff --git a/tests/Feature/Controllers/Transaction/CreateControllerTest.php b/tests/Feature/Controllers/Transaction/CreateControllerTest.php new file mode 100644 index 0000000000..28a3b16b91 --- /dev/null +++ b/tests/Feature/Controllers/Transaction/CreateControllerTest.php @@ -0,0 +1,66 @@ +. + */ + +namespace Tests\Feature\Controllers\Transaction; + + +use FireflyIII\Models\Preference; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\User\UserRepositoryInterface; +use Log; +use Preferences; +use Tests\TestCase; +use Mockery; + +/** + * Class CreateControllerTest + */ +class CreateControllerTest extends TestCase +{ + /** + * + */ + public function setUp(): void + { + parent::setUp(); + Log::info(sprintf('Now in %s.', get_class($this))); + } + + public function testCreate(): void + { + $this->mockDefaultSession(); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $userRepos = $this->mock(UserRepositoryInterface::class); + $cash = $this->getRandomAsset(); + $empty = new Preference; + $empty->data = []; + + $userRepos->shouldReceive('hasRole')->atLeast()->once()->withArgs([Mockery::any(),'owner'])->andReturn(true); + $accountRepos->shouldReceive('getCashAccount')->atLeast()->once()->andReturn($cash); + + Preferences::shouldReceive('get')->withArgs(['transaction_journal_optional_fields', []])->atLeast()->once()->andReturn($empty); + + + $this->be($this->user()); + $response = $this->get(route('transactions.create')); + $response->assertStatus(200); + } +} \ No newline at end of file