diff --git a/app/Http/Controllers/Transaction/ConvertController.php b/app/Http/Controllers/Transaction/ConvertController.php index 529a0f6b30..1d488e1767 100644 --- a/app/Http/Controllers/Transaction/ConvertController.php +++ b/app/Http/Controllers/Transaction/ConvertController.php @@ -44,6 +44,8 @@ use View; /** * Class ConvertController. + * + * TODO when converting to a split transfer, all sources and destinations must be the same. */ class ConvertController extends Controller { @@ -93,7 +95,7 @@ class ConvertController extends Controller $sourceType = $first->transactionType; // return to account. if (!in_array($sourceType->type, [TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::DEPOSIT], true)) { - return $this->redirectToAccount($first); + return $this->redirectToAccount($first); // @codeCoverageIgnore } $groupTitle = $group->title ?? $first->description; @@ -153,6 +155,11 @@ class ConvertController extends Controller return redirect()->route('transactions.convert.index', [strtolower($destinationType->type), $group->id])->withInput(); } } + + // correct transfers: + $group->refresh(); + $this->correctTransfer($group); + session()->flash('success', (string)trans('firefly.converted_to_' . $destinationType->type)); event(new UpdatedTransactionGroup($group)); @@ -205,7 +212,7 @@ class ConvertController extends Controller foreach ($accountList as $account) { $balance = app('steam')->balance($account, new Carbon); $currency = $repository->getAccountCurrency($account) ?? $defaultCurrency; - $role = 'l_' . $account->accountType->type; // @codeCoverageIgnore + $role = 'l_' . $account->accountType->type; $key = (string)trans('firefly.opt_group_' . $role); $grouped[$key][$account->id] = $account->name . ' (' . app('amount')->formatAnything($currency, $balance, false) . ')'; } @@ -239,11 +246,13 @@ class ConvertController extends Controller $role = 'l_' . $account->accountType->type; // @codeCoverageIgnore } if (AccountType::CASH === $account->accountType->type) { + // @codeCoverageIgnoreStart $role = 'cash_account'; $name = sprintf('(%s)', trans('firefly.cash')); + // @codeCoverageIgnoreEnd } if (AccountType::REVENUE === $account->accountType->type) { - $role = 'revenue_account'; + $role = 'revenue_account'; // @codeCoverageIgnore } $key = (string)trans('firefly.opt_group_' . $role); @@ -279,11 +288,13 @@ class ConvertController extends Controller $role = 'l_' . $account->accountType->type; // @codeCoverageIgnore } if (AccountType::CASH === $account->accountType->type) { + // @codeCoverageIgnoreStart $role = 'cash_account'; $name = sprintf('(%s)', trans('firefly.cash')); + // @codeCoverageIgnoreEnd } if (AccountType::EXPENSE === $account->accountType->type) { - $role = 'expense_account'; + $role = 'expense_account'; // @codeCoverageIgnore } $key = (string)trans('firefly.opt_group_' . $role); @@ -302,8 +313,6 @@ class ConvertController extends Controller */ private function convertJournal(TransactionJournal $journal, TransactionType $transactionType, array $data): TransactionJournal { - $sourceType = $journal->transactionType->type; - // make a switch based on original + dest type. /** @var AccountValidator $validator */ $validator = app(AccountValidator::class); $validator->setUser(auth()->user()); @@ -345,4 +354,11 @@ class ConvertController extends Controller return $journal; } + + /** + * @param TransactionGroup $group + */ + private function correctTransfer(TransactionGroup $group): void + { + } } diff --git a/public/v1/js/app.js b/public/v1/js/app.js index 6ee10da05a..7eee2b375f 100644 --- a/public/v1/js/app.js +++ b/public/v1/js/app.js @@ -49299,7 +49299,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", ""]); +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", ""]); // exports @@ -49350,15 +49350,27 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); // // // +// +// /* harmony default export */ __webpack_exports__["default"] = ({ name: "CustomAttachments", + data: function data() { + return { + files: '' + }; + }, + props: { title: String, name: String, error: Array }, methods: { + handleFilesUpload: function handleFilesUpload() { + this.files = this.$refs.files.files; + }, + hasError: function hasError() { return this.error.length > 0; } @@ -49386,6 +49398,7 @@ var render = function() { { staticClass: "col-sm-12" }, [ _c("input", { + ref: "files", staticClass: "form-control", attrs: { multiple: "multiple", @@ -49394,6 +49407,11 @@ var render = function() { title: _vm.title, name: _vm.name, type: "file" + }, + on: { + change: function($event) { + _vm.handleFilesUpload() + } } }), _vm._v(" "), @@ -51535,7 +51553,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", ""]); +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", ""]); // exports @@ -51609,7 +51627,6 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); //console.log('Dest "' + this.destination.name + '"'); if (!transactionType && !this.source.name && !this.destination.name) { $(this.$refs.cur).text(''); - console.log('A'); return; } if (null === transactionType) { @@ -51618,28 +51635,19 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); if ('' === transactionType && '' !== this.source.currency_name) { $(this.$refs.cur).text(this.source.currency_name); - console.log('B'); return; } if ('' === transactionType && '' !== this.destination.currency_name) { $(this.$refs.cur).text(this.destination.currency_name); - console.log('C'); return; } if (transactionType === 'Withdrawal' || transactionType === 'Transfer') { $(this.$refs.cur).text(this.source.currency_name); - console.log('D'); return; } if (transactionType === 'Deposit') { $(this.$refs.cur).text(this.destination.currency_name); - console.log('E'); - return; } - console.log('transactionType: ' + transactionType); - console.log('this.source.name: ' + this.source.name); - console.log('this.destination.name: ' + this.destination.name); - console.log('F'); } }, watch: { @@ -54898,7 +54906,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", ""]); +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", ""]); // exports @@ -55119,7 +55127,7 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); name: "CreateTransaction", components: {}, mounted: function mounted() { - this.addTransaction(); + this.addTransactionToArray(); }, ready: function ready() {}, @@ -55128,18 +55136,9 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); 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; @@ -55154,130 +55153,139 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); firstDestination = this.transactions[0].destination_account.type; if ('invalid' === transactionType && ['Asset account', 'Loan', 'Debt', 'Mortgage'].includes(firstSource)) { - //console.log('Assumed this is a withdrawal.'); transactionType = 'withdrawal'; } if ('invalid' === transactionType && ['Asset account', 'Loan', 'Debt', 'Mortgage'].includes(firstDestination)) { - //console.log('Assumed this is a deposit.'); transactionType = 'deposit'; } - 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); + for (var _key in this.transactions) { + if (this.transactions.hasOwnProperty(_key) && /^0$|^[1-9]\d*$/.test(_key) && _key <= 4294967294) { + 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 = 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; + + date = this.transactions[index].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 key 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 > 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) && key <= 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, + //budget_id: row.budget, + //piggy_bank_id: row.piggy_bank, + + + 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 transaction submit: function submit(e) { var _this = this; @@ -55290,8 +55298,10 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); var button = $(e.currentTarget); button.prop("disabled", true); - axios.post(uri, data).then(function (response) { + axions.post(uri, data).then(function (response) { + // send user onwards. if (_this.createAnother) { + console.log('Will create another.'); // do message: _this.success_message = 'The transaction has been stored.'; _this.error_message = ''; @@ -55300,24 +55310,28 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); } button.prop("disabled", false); } else { + console.log('Will redirect to transaction.'); window.location.href = 'transactions/show/' + response.data.data.id + '?message=created'; } }).catch(function (error) { // give user errors things back. // something something render errors. + console.error('Error in transaction submission.'); + console.error(error); _this.parseErrors(error.response.data); // something. button.prop("disabled", false); }); + if (e) { e.preventDefault(); } }, 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 = { + for (var _key2 in this.transactions) { + if (this.transactions.hasOwnProperty(_key2) && /^0$|^[1-9]\d*$/.test(_key2) && _key2 <= 4294967294) { + this.transactions[_key2].errors = { source_account: [], destination_account: [], description: [], @@ -55355,15 +55369,15 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); 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]; + for (var _key3 in errors.errors) { + if (errors.errors.hasOwnProperty(_key3)) { + if (_key3 === 'group_title') { + this.group_title_errors = errors.errors[_key3]; } - if (key !== 'group_title') { + if (_key3 !== 'group_title') { // lol dumbest way to explode "transactions.0.something" ever. - transactionIndex = parseInt(key.split('.')[1]); - fieldName = key.split('.')[2]; + transactionIndex = parseInt(_key3.split('.')[1]); + fieldName = _key3.split('.')[2]; // set error in this object thing. switch (fieldName) { case 'amount': @@ -55371,19 +55385,19 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); case 'budget_id': case 'description': case 'tags': - this.transactions[transactionIndex].errors[fieldName] = errors.errors[key]; + this.transactions[transactionIndex].errors[fieldName] = errors.errors[_key3]; break; case 'source_name': case 'source_id': - this.transactions[transactionIndex].errors.source_account = this.transactions[transactionIndex].errors.source_account.concat(errors.errors[key]); + this.transactions[transactionIndex].errors.source_account = this.transactions[transactionIndex].errors.source_account.concat(errors.errors[_key3]); break; case 'destination_name': case 'destination_id': - this.transactions[transactionIndex].errors.destination_account = this.transactions[transactionIndex].errors.destination_account.concat(errors.errors[key]); + this.transactions[transactionIndex].errors.destination_account = this.transactions[transactionIndex].errors.destination_account.concat(errors.errors[_key3]); break; case 'foreign_amount': case 'foreign_currency_id': - this.transactions[transactionIndex].errors.foreign_amount = this.transactions[transactionIndex].errors.foreign_amount.concat(errors.errors[key]); + this.transactions[transactionIndex].errors.foreign_amount = this.transactions[transactionIndex].errors.foreign_amount.concat(errors.errors[_key3]); break; } } @@ -55393,7 +55407,7 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); resetTransactions: function resetTransactions() { this.transactions = []; }, - addTransaction: function addTransaction(e) { + addTransactionToArray: function addTransactionToArray(e) { this.transactions.push({ description: "", date: "", @@ -55476,14 +55490,14 @@ 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) {} + for (var _key4 in this.transactions) { + if (this.transactions.hasOwnProperty(_key4) && /^0$|^[1-9]\d*$/.test(_key4) && _key4 <= 4294967294) {} } this.transactions.splice(index, 1); - for (var _key in this.transactions) { - if (this.transactions.hasOwnProperty(_key) && /^0$|^[1-9]\d*$/.test(_key) && _key <= 4294967294) {} + for (var _key5 in this.transactions) { + if (this.transactions.hasOwnProperty(_key5) && /^0$|^[1-9]\d*$/.test(_key5) && _key5 <= 4294967294) {} } }, limitSourceType: function limitSourceType(type) { @@ -55618,7 +55632,7 @@ var render = function() { staticClass: "form-horizontal", attrs: { method: "POST", - action: "transactions/store", + action: "#", "accept-charset": "UTF-8", id: "store", enctype: "multipart/form-data" @@ -55973,7 +55987,7 @@ var render = function() { "button", { staticClass: "btn btn-primary", - on: { click: _vm.addTransaction } + on: { click: _vm.addTransactionToArray } }, [_vm._v("Add another split")] ) diff --git a/tests/Feature/Controllers/Transaction/ConvertControllerTest.php b/tests/Feature/Controllers/Transaction/ConvertControllerTest.php index ed857d8902..4aa908a009 100644 --- a/tests/Feature/Controllers/Transaction/ConvertControllerTest.php +++ b/tests/Feature/Controllers/Transaction/ConvertControllerTest.php @@ -23,19 +23,23 @@ declare(strict_types=1); namespace Tests\Feature\Controllers\Transaction; use Amount; -use DB; use FireflyIII\Models\Account; -use FireflyIII\Models\TransactionCurrency; +use FireflyIII\Models\AccountType; use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface; +use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface; 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; +use Steam; use Tests\TestCase; /** @@ -62,30 +66,53 @@ class ConvertControllerTest extends TestCase */ public function testIndexDepositTransfer(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; // mock stuff: - $journalRepos = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); + $journalRepos = $this->mockDefaultSession(); + $userRepos = $this->mock(UserRepositoryInterface::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); + $groupRepos = $this->mock(TransactionGroupRepositoryInterface::class); + $transformer = $this->mock(TransactionGroupTransformer::class); + + $revenue = $this->getRandomRevenue(); + $deposit = $this->getRandomDepositGroup(); + $euro = $this->getEuro(); + $asset = $this->getRandomAsset(); + $loan = $this->getRandomLoan(); + $expense = $this->getRandomExpense(); + + Steam::shouldReceive('balance')->atLeast()->once()->andReturn('100'); + + // mock calls: + $transformer->shouldReceive('transformObject')->atLeast()->once()->andReturn([]); + + $accountRepos->shouldReceive('getActiveAccountsByType') + ->atLeast()->once()->withArgs([[AccountType::REVENUE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]]) + ->andReturn(new Collection([$revenue])); + + $accountRepos->shouldReceive('getActiveAccountsByType') + ->atLeast()->once()->withArgs([[AccountType::EXPENSE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]]) + ->andReturn(new Collection([$expense])); + + $accountRepos->shouldReceive('getActiveAccountsByType') + ->atLeast()->once()->withArgs([[AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]]) + ->andReturn(new Collection([$loan])); + + $accountRepos->shouldReceive('getActiveAccountsByType') + ->atLeast()->once()->withArgs([[AccountType::ASSET]]) + ->andReturn(new Collection([$asset])); + + $userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true); + $accountRepos->shouldReceive('getMetaValue')->atLeast()->once()->withArgs([Mockery::any(), 'account_role'])->andReturn('', 'defaultAsset'); + $accountRepos->shouldReceive('getAccountCurrency')->atLeast()->once()->andReturn($euro); + // $journalRepos->shouldReceive('firstNull')->andReturn($deposit); + // $journalRepos->shouldReceive('getJournalTotal')->andReturn('1')->once(); + // $journalRepos->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection)->once(); + // $journalRepos->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection)->once(); - // find deposit: - $deposit = $this->getRandomDeposit(); - $journalRepos->shouldReceive('firstNull')->andReturn($deposit); - $journalRepos->shouldReceive('getJournalTotal')->andReturn('1')->once(); - $journalRepos->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection)->once(); - $journalRepos->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection)->once(); - - // mock stuff for new account list thing. - $currency = TransactionCurrency::first(); - $account = factory(Account::class)->make(); - $this->mock(CurrencyRepositoryInterface::class); - - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - Amount::shouldReceive('getDefaultCurrency')->andReturn($currency)->times(2); - Amount::shouldReceive('formatAnything')->andReturn('0')->once(); + // Amount::shouldReceive('getDefaultCurrency')->andReturn($currency)->times(2); + Amount::shouldReceive('formatAnything')->andReturn('0')->atLeast()->once(); $this->be($this->user()); @@ -94,56 +121,52 @@ class ConvertControllerTest extends TestCase $response->assertSee('Convert a deposit into a transfer'); } - /** - * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController - */ - public function testIndexDepositWithdrawal(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock stuff: - $journalRepos = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true); - - // find deposit: - $deposit = $this->getRandomDeposit(); - $journalRepos->shouldReceive('firstNull')->andReturn($deposit); - $journalRepos->shouldReceive('getJournalTotal')->andReturn('1')->once(); - $journalRepos->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection)->once(); - $journalRepos->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection)->once(); - - // mock stuff for new account list thing. - $currency = TransactionCurrency::first(); - - Amount::shouldReceive('getDefaultCurrency')->andReturn($currency)->twice(); - Amount::shouldReceive('formatAnything')->andReturn('0')->once(); - - - $this->be($this->user()); - $response = $this->get(route('transactions.convert.index', ['withdrawal', $deposit->id])); - $response->assertStatus(200); - $response->assertSee('Convert a deposit into a withdrawal'); - } - /** * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController */ public function testIndexSameType(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; // mock stuff: + $this->mockDefaultSession(); + $this->mock(UserRepositoryInterface::class); + $this->mock(CurrencyRepositoryInterface::class); + $this->mock(TransactionGroupRepositoryInterface::class); - // find deposit: - $deposit = $this->getRandomDeposit(); - $journalRepos = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); + $accountRepos = $this->mock(AccountRepositoryInterface::class); + $transformer = $this->mock(TransactionGroupTransformer::class); - $journalRepos->shouldReceive('firstNull')->andReturn($deposit); - $journalRepos->shouldReceive('getJournalTotal')->andReturn('1')->once(); + $revenue = $this->getRandomRevenue(); + $deposit = $this->getRandomDepositGroup(); + $euro = $this->getEuro(); + $asset = $this->getRandomAsset(); + $loan = $this->getRandomLoan(); + $expense = $this->getRandomExpense(); + + Steam::shouldReceive('balance')->atLeast()->once()->andReturn('100'); + + // mock calls: + $transformer->shouldReceive('transformObject')->atLeast()->once()->andReturn([]); + + $accountRepos->shouldReceive('getActiveAccountsByType') + ->atLeast()->once()->withArgs([[AccountType::REVENUE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]]) + ->andReturn(new Collection([$revenue])); + + $accountRepos->shouldReceive('getActiveAccountsByType') + ->atLeast()->once()->withArgs([[AccountType::EXPENSE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]]) + ->andReturn(new Collection([$expense])); + + $accountRepos->shouldReceive('getActiveAccountsByType') + ->atLeast()->once()->withArgs([[AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]]) + ->andReturn(new Collection([$loan])); + + $accountRepos->shouldReceive('getActiveAccountsByType') + ->atLeast()->once()->withArgs([[AccountType::ASSET]]) + ->andReturn(new Collection([$asset])); + + + $accountRepos->shouldReceive('getMetaValue')->atLeast()->once()->withArgs([Mockery::any(), 'account_role'])->andReturn('', 'defaultAsset'); + $accountRepos->shouldReceive('getAccountCurrency')->atLeast()->once()->andReturn($euro); + Amount::shouldReceive('formatAnything')->andReturn('0')->atLeast()->once(); $this->be($this->user()); @@ -152,199 +175,33 @@ class ConvertControllerTest extends TestCase $response->assertSessionHas('info'); } - /** - * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController - */ - public function testIndexSplit(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock stuff: - $journalRepos = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - - $journalRepos->shouldReceive('firstNull')->andReturn(new TransactionJournal); - $journalRepos->shouldReceive('getJournalTotal')->andReturn('1')->once(); - - // mock stuff for new account list thing. - $currency = TransactionCurrency::first(); - $currencyRepos = $this->mock(CurrencyRepositoryInterface::class); - $currencyRepos->shouldReceive('findNull')->andReturn($currency); - - Amount::shouldReceive('getDefaultCurrency')->andReturn($currency)->once(); - - $this->be($this->user()); - $withdrawal = TransactionJournal::where('transaction_type_id', 1) - ->whereNull('transaction_journals.deleted_at') - ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->groupBy('transaction_journals.id') - ->orderBy('ct', 'DESC') - ->where('user_id', $this->user()->id)->first(['transaction_journals.id', DB::raw('count(transactions.`id`) as ct')]); - $response = $this->get(route('transactions.convert.index', ['deposit', $withdrawal->id])); - $response->assertStatus(302); - $response->assertSessionHas('error'); - } - - /** - * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController - */ - public function testIndexTransferDeposit(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // mock stuff: - - // find transfer: - $transfer = $this->getRandomTransfer(); - $journalRepos = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true); - - $journalRepos->shouldReceive('firstNull')->andReturn($transfer); - $journalRepos->shouldReceive('getJournalTotal')->andReturn('1')->once(); - $journalRepos->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection)->once(); - $journalRepos->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection)->once(); - - $this->be($this->user()); - $response = $this->get(route('transactions.convert.index', ['deposit', $transfer->id])); - $response->assertStatus(200); - $response->assertSee('Convert a transfer into a deposit'); - } - - /** - * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController - */ - public function testIndexTransferWithdrawal(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // find transfer: - $transfer = $this->getRandomTransfer(); - // mock stuff: - $journalRepos = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true); - - $journalRepos->shouldReceive('firstNull')->andReturn(new TransactionJournal); - $journalRepos->shouldReceive('getJournalTotal')->andReturn('1')->once(); - $journalRepos->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection)->once(); - $journalRepos->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection)->once(); - - // mock stuff for new account list thing. - $currency = TransactionCurrency::first(); - Amount::shouldReceive('getDefaultCurrency')->andReturn($currency)->times(2); - Amount::shouldReceive('formatAnything')->andReturn('0')->once(); - - $this->be($this->user()); - $response = $this->get(route('transactions.convert.index', ['withdrawal', $transfer->id])); - $response->assertStatus(200); - $response->assertSee('Convert a transfer into a withdrawal'); - } - - /** - * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController - */ - public function testIndexWithdrawalDeposit(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - - // find withdrawal: - $withdrawal = $this->getRandomWithdrawal(); - // mock stuff: - $journalRepos = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true); - - $journalRepos->shouldReceive('firstNull')->andReturn(new TransactionJournal); - $journalRepos->shouldReceive('getJournalTotal')->andReturn('1')->once(); - $journalRepos->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection)->once(); - $journalRepos->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection)->once(); - - // mock stuff for new account list thing. - $currency = TransactionCurrency::first(); - Amount::shouldReceive('getDefaultCurrency')->andReturn($currency)->times(2); - Amount::shouldReceive('formatAnything')->andReturn('0')->once(); - - $this->be($this->user()); - $response = $this->get(route('transactions.convert.index', ['deposit', $withdrawal->id])); - $response->assertStatus(200); - $response->assertSee('Convert a withdrawal into a deposit'); - } - - /** - * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController - */ - public function testIndexWithdrawalTransfer(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - // find withdrawal: - $withdrawal = $this->getRandomWithdrawal(); - // mock stuff: - $journalRepos = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true); - - $journalRepos->shouldReceive('firstNull')->andReturn(new TransactionJournal); - $journalRepos->shouldReceive('getJournalTotal')->andReturn('1')->once(); - $journalRepos->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection)->once(); - $journalRepos->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection)->once(); - - // mock stuff for new account list thing. - $currency = TransactionCurrency::first(); - $this->mock(CurrencyRepositoryInterface::class); - - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - Amount::shouldReceive('getDefaultCurrency')->andReturn($currency)->times(2); - Amount::shouldReceive('formatAnything')->andReturn('0')->once(); - - $this->be($this->user()); - $response = $this->get(route('transactions.convert.index', ['transfer', $withdrawal->id])); - $response->assertStatus(200); - $response->assertSee('Convert a withdrawal into a transfer'); - } - /** * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController */ public function testPostIndexDepositTransfer(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); + $this->mockDefaultSession(); + $repository = $this->mock(JournalRepositoryInterface::class); + $this->mock(UserRepositoryInterface::class); + $this->mock(AccountRepositoryInterface::class); + $this->mock(RuleGroupRepositoryInterface::class); + $validator = $this->mock(AccountValidator::class); + $deposit = $this->getRandomDepositGroup(); - return; - Log::info(sprintf('Now in test %s', __METHOD__)); - // mock stuff - $repository = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); + Preferences::shouldReceive('mark')->atLeast()->once()->withNoArgs(); - $ruleGroupRepos->shouldReceive('setUser')->atLeast()->once(); - $ruleGroupRepos->shouldReceive('getActiveGroups')->atLeast()->once()->andReturn(new Collection); + $validator->shouldReceive('setUser')->atLeast()->once(); + $validator->shouldReceive('setTransactionType')->atLeast()->once()->withArgs(['Transfer']); + $validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true); - // get journal: - $deposit = $this->getRandomDeposit(); - $source = $this->getRandomRevenue(); - $destination = $this->getRandomAsset(); - - $repository->shouldReceive('convert')->andReturn(new MessageBag)->atLeast()->once(); $repository->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal)->atLeast()->once(); - $repository->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection([$source]))->atLeast()->once(); - $repository->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection([$destination]))->atLeast()->once(); - $accountRepos->shouldReceive('findNull')->andReturn(new Account)->atLeast()->once(); - $data = ['source_account_asset' => 1]; + $data = ['source_account_id' => 1]; $this->be($this->user()); - $response = $this->post(route('transactions.convert.index', ['transfer', $deposit->id]), $data); + $response = $this->post(route('transactions.convert.index.post', ['transfer', $deposit->id]), $data); $response->assertStatus(302); $response->assertRedirect(route('transactions.show', [$deposit->id])); } @@ -352,316 +209,62 @@ class ConvertControllerTest extends TestCase /** * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController */ - public function testPostIndexDepositWithdrawal(): void + public function testPostIndexBadSource(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); + $this->mockDefaultSession(); + $repository = $this->mock(JournalRepositoryInterface::class); + $this->mock(UserRepositoryInterface::class); + $this->mock(AccountRepositoryInterface::class); + $this->mock(RuleGroupRepositoryInterface::class); + $validator = $this->mock(AccountValidator::class); + $deposit = $this->getRandomDepositGroup(); - return; - Log::info(sprintf('Now in test %s', __METHOD__)); - // mock stuff - $repository = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); + // first journal: + $journal = $deposit->transactionJournals()->first(); - $ruleGroupRepos->shouldReceive('setUser')->atLeast()->once(); - $ruleGroupRepos->shouldReceive('getActiveGroups')->atLeast()->once()->andReturn(new Collection); - - // get journal: - $deposit = $this->getRandomDeposit(); - $source = $this->getRandomRevenue(); - $destination = $this->getRandomAsset(); - $expense = $this->getRandomExpense(); - - $repository->shouldReceive('convert')->andReturn(new MessageBag)->atLeast()->once(); + $validator->shouldReceive('setUser')->atLeast()->once(); + $validator->shouldReceive('setTransactionType')->atLeast()->once()->withArgs(['Transfer']); + $validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(false); + $validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true); $repository->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal)->atLeast()->once(); - $repository->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection([$source]))->atLeast()->once(); - $repository->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection([$destination]))->atLeast()->once(); - $accountRepos->shouldReceive('store')->atLeast()->once()->andReturn($expense); - $data = ['destination_account_expense' => 'New expense name.']; + + $data = ['source_account_id' => 1]; $this->be($this->user()); - $response = $this->post(route('transactions.convert.index', ['withdrawal', $deposit->id]), $data); + $response = $this->post(route('transactions.convert.index.post', ['transfer', $deposit->id]), $data); $response->assertStatus(302); - $response->assertRedirect(route('transactions.show', [$deposit->id])); + $response->assertSessionHas('error', sprintf('Source information is invalid for transaction #%d.', $journal->id)); + $response->assertRedirect(route('transactions.convert.index', ['transfer', $deposit->id])); } /** * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController */ - public function testPostIndexDepositWithdrawalEmptyName(): void + public function testPostIndexBadDestination(): void { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); + $this->mockDefaultSession(); + $repository = $this->mock(JournalRepositoryInterface::class); + $this->mock(UserRepositoryInterface::class); + $this->mock(AccountRepositoryInterface::class); + $this->mock(RuleGroupRepositoryInterface::class); + $validator = $this->mock(AccountValidator::class); + $deposit = $this->getRandomDepositGroup(); - return; - Log::info(sprintf('Now in test %s', __METHOD__)); - // mock stuff - $repository = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); + // first journal: + $journal = $deposit->transactionJournals()->first(); - $ruleGroupRepos->shouldReceive('setUser')->atLeast()->once(); - $ruleGroupRepos->shouldReceive('getActiveGroups')->atLeast()->once()->andReturn(new Collection); - - // get journal: - $deposit = $this->getRandomDeposit(); - $source = $this->getRandomRevenue(); - $destination = $this->getRandomAsset(); - $expense = $this->getRandomExpense(); - - $repository->shouldReceive('convert')->andReturn(new MessageBag)->atLeast()->once(); - $repository->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal)->atLeast()->once(); - $repository->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection([$source]))->atLeast()->once(); - $repository->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection([$destination]))->atLeast()->once(); - $accountRepos->shouldReceive('getCashAccount')->atLeast()->once()->andReturn($expense); - - $data = ['destination_account_expense' => '']; - $this->be($this->user()); - $response = $this->post(route('transactions.convert.index', ['withdrawal', $deposit->id]), $data); - $response->assertStatus(302); - $response->assertRedirect(route('transactions.show', [$deposit->id])); - } - - - /** - * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController - */ - public function testPostIndexErrored(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - Log::info(sprintf('Now in test %s', __METHOD__)); - // mock stuff - $repository = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); - - // mock stuff - $messageBag = new MessageBag; - $messageBag->add('fake', 'fake error'); - - // get journal: - $withdrawal = $this->getRandomWithdrawal(); - $source = $this->getRandomRevenue(); - $destination = $this->getRandomAsset(); - - $repository->shouldReceive('convert')->andReturn($messageBag)->atLeast()->once(); - $repository->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal)->atLeast()->once(); - $repository->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection([$source]))->atLeast()->once(); - $repository->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection([$destination]))->atLeast()->once(); - $accountRepos->shouldReceive('findNull')->andReturn(new Account)->atLeast()->once(); - - $data = [ - 'destination_account_asset' => 2, - ]; - $this->be($this->user()); - $response = $this->post(route('transactions.convert.index', ['transfer', $withdrawal->id]), $data); - $response->assertStatus(302); - $response->assertRedirect(route('transactions.convert.index', ['transfer', $withdrawal->id])); - } - - /** - * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController - */ - public function testPostIndexSameType(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - Log::info(sprintf('Now in test %s', __METHOD__)); - // mock stuff - $repository = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); - - - // get journal: - $withdrawal = $this->getRandomWithdrawal(); + $validator->shouldReceive('setUser')->atLeast()->once(); + $validator->shouldReceive('setTransactionType')->atLeast()->once()->withArgs(['Transfer']); + $validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true); + $validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(false); $repository->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal)->atLeast()->once(); - $data = [ - 'destination_account_asset' => 2, - ]; + + $data = ['source_account_id' => 1]; $this->be($this->user()); - $response = $this->post(route('transactions.convert.index', ['withdrawal', $withdrawal->id]), $data); + $response = $this->post(route('transactions.convert.index.post', ['transfer', $deposit->id]), $data); $response->assertStatus(302); - $response->assertSessionHas('error'); - } - - /** - * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController - */ - public function testPostIndexSplit(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - Log::info(sprintf('Now in test %s', __METHOD__)); - // mock stuff - $repository = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - - // get journal: - $withdrawal = $this->getRandomSplitWithdrawal(); - $repository->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal)->atLeast()->once(); - - $data = [ - 'destination_account_asset' => 2, - ]; - $this->be($this->user()); - $response = $this->post(route('transactions.convert.index', ['transfer', $withdrawal->id]), $data); - $response->assertStatus(302); - $response->assertSessionHas('error'); - } - - /** - * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController - */ - public function testPostIndexTransferDeposit(): void - { $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - - Log::info(sprintf('Now in test %s', __METHOD__)); - // mock stuff - $repository = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); - - $ruleGroupRepos->shouldReceive('setUser')->atLeast()->once(); - $ruleGroupRepos->shouldReceive('getActiveGroups')->atLeast()->once()->andReturn(new Collection); - - // mock stuff - - // get journal: - $transfer = $this->getRandomTransfer(); - $source = $this->getRandomAsset(); - $destination = $this->getRandomAsset(); - $revenue = $this->getRandomRevenue(); - - $repository->shouldReceive('convert')->andReturn(new MessageBag)->atLeast()->once(); - $repository->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal)->atLeast()->once(); - $repository->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection([$source]))->atLeast()->once(); - $repository->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection([$destination]))->atLeast()->once(); - $accountRepos->shouldReceive('store')->atLeast()->once()->andReturn($revenue); - - $data = ['source_account_revenue' => 'New rev']; - $this->be($this->user()); - $response = $this->post(route('transactions.convert.index', ['deposit', $transfer->id]), $data); - $response->assertStatus(302); - $response->assertRedirect(route('transactions.show', [$transfer->id])); - } - - /** - * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController - */ - public function testPostIndexWithdrawalDeposit(): void - { - $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - Log::info(sprintf('Now in test %s', __METHOD__)); - // mock stuff - $repository = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); - - $ruleGroupRepos->shouldReceive('setUser')->atLeast()->once(); - $ruleGroupRepos->shouldReceive('getActiveGroups')->atLeast()->once()->andReturn(new Collection); - - $withdrawal = $this->getRandomWithdrawal(); - $source = $this->getRandomExpense(); - $destination = $this->getRandomAsset(); - $revenue = $this->getRandomRevenue(); - - $repository->shouldReceive('convert')->andReturn(new MessageBag)->atLeast()->once(); - $repository->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal)->atLeast()->once(); - $repository->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection([$source]))->atLeast()->once(); - $repository->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection([$destination]))->atLeast()->once(); - $accountRepos->shouldReceive('store')->atLeast()->once()->andReturn($revenue); - - - $data = ['source_account_revenue' => 'New revenue name.']; - $this->be($this->user()); - $response = $this->post(route('transactions.convert.index', ['deposit', $withdrawal->id]), $data); - $response->assertStatus(302); - $response->assertRedirect(route('transactions.show', [$withdrawal->id])); - } - - /** - * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController - */ - public function testPostIndexWithdrawalDepositEmptyName(): void - { $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - Log::info(sprintf('Now in test %s', __METHOD__)); - // mock stuff - $repository = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); - - $ruleGroupRepos->shouldReceive('setUser')->atLeast()->once(); - $ruleGroupRepos->shouldReceive('getActiveGroups')->atLeast()->once()->andReturn(new Collection); - - $withdrawal = $this->getRandomWithdrawal(); - $source = $this->getRandomExpense(); - $destination = $this->getRandomAsset(); - $revenue = $this->getRandomRevenue(); - - $repository->shouldReceive('convert')->andReturn(new MessageBag)->atLeast()->once(); - $repository->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal)->atLeast()->once(); - $repository->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection([$source]))->atLeast()->once(); - $repository->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection([$destination]))->atLeast()->once(); - $accountRepos->shouldReceive('getCashAccount')->atLeast()->once()->andReturn($revenue); - - $data = ['source_account_revenue' => '']; - $this->be($this->user()); - $response = $this->post(route('transactions.convert.index', ['deposit', $withdrawal->id]), $data); - $response->assertStatus(302); - $response->assertRedirect(route('transactions.show', [$withdrawal->id])); - } - - /** - * @covers \FireflyIII\Http\Controllers\Transaction\ConvertController - */ - public function testPostIndexWithdrawalTransfer(): void - { $this->markTestIncomplete('Needs to be rewritten for v4.8.0'); - - return; - Log::info(sprintf('Now in test %s', __METHOD__)); - // mock stuff - $repository = $this->mock(JournalRepositoryInterface::class); - $userRepos = $this->mock(UserRepositoryInterface::class); - $accountRepos = $this->mock(AccountRepositoryInterface::class); - $ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class); - - $ruleGroupRepos->shouldReceive('setUser')->atLeast()->once(); - $ruleGroupRepos->shouldReceive('getActiveGroups')->atLeast()->once()->andReturn(new Collection); - - $withdrawal = $this->getRandomWithdrawal(); - $source = $this->getRandomExpense(); - $destination = $this->getRandomAsset(); - $newDest = $this->getRandomAsset(); - - $repository->shouldReceive('convert')->andReturn(new MessageBag)->atLeast()->once(); - $repository->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal)->atLeast()->once(); - $repository->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection([$source]))->atLeast()->once(); - $repository->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection([$destination]))->atLeast()->once(); - $accountRepos->shouldReceive('findNull')->atLeast()->once()->andReturn($newDest); - - $data = ['destination_account_asset' => 2,]; - $this->be($this->user()); - $response = $this->post(route('transactions.convert.index', ['transfer', $withdrawal->id]), $data); - $response->assertStatus(302); - $response->assertRedirect(route('transactions.show', [$withdrawal->id])); + $response->assertSessionHas('error', sprintf('Destination information is invalid for transaction #%d.', $journal->id)); + $response->assertRedirect(route('transactions.convert.index', ['transfer', $deposit->id])); } } diff --git a/tests/TestCase.php b/tests/TestCase.php index fd1147920e..bf28445822 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -443,6 +443,14 @@ abstract class TestCase extends BaseTestCase return $this->getRandomGroup(TransactionType::WITHDRAWAL); } + /** + * @return TransactionGroup + */ + protected function getRandomDepositGroup(): TransactionGroup + { + return $this->getRandomGroup(TransactionType::DEPOSIT); + } + /** * @param string $class *