From 1088a438667670f79a3665bda465f43a1602cdf9 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 21 Mar 2021 18:48:47 +0100 Subject: [PATCH] Rebuild frontend, first working edit form (no feedback) --- .../Autocomplete/PiggyBankController.php | 25 +- .../PiggyBank/PiggyBankRepository.php | 1 + frontend/src/components/transactions/Edit.vue | 160 +- .../transactions/TransactionLinks.vue | 39 +- .../transactions/TransactionNotes.vue | 7 +- .../transactions/TransactionPiggyBank.vue | 98 +- frontend/src/scss/_variables.scss | 5 +- frontend/yarn.lock | 2724 ++++++++++++----- public/v2/css/app.css | 2 +- public/v2/css/app.css.map | 2 +- public/v2/images/logo-hollow.png | Bin 1385 -> 1744 bytes public/v2/js/transactions/edit.js | 2 +- public/v2/js/transactions/edit.js.map | 2 +- public/v2/js/vendor.js | 2 +- public/v2/js/vendor.js.map | 2 +- resources/views/v2/transactions/edit.twig | 23 + 16 files changed, 2243 insertions(+), 851 deletions(-) create mode 100644 resources/views/v2/transactions/edit.twig diff --git a/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php b/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php index 4887963ea1..1a94dfbb74 100644 --- a/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php +++ b/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php @@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Controllers\Autocomplete; use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest; +use FireflyIII\Models\ObjectGroup; use FireflyIII\Models\PiggyBank; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; @@ -37,7 +38,7 @@ use Illuminate\Http\JsonResponse; */ class PiggyBankController extends Controller { - private AccountRepositoryInterface $accountRepository; + private AccountRepositoryInterface $accountRepository; private PiggyBankRepositoryInterface $piggyRepository; /** @@ -75,9 +76,19 @@ class PiggyBankController extends Controller /** @var PiggyBank $piggy */ foreach ($piggies as $piggy) { $currency = $this->accountRepository->getAccountCurrency($piggy->account) ?? $defaultCurrency; + $groupTitle = null; + $groupId = null; + /** @var ObjectGroup $group */ + $group = $piggy->objectGroups()->first(); + if (null !== $group) { + $groupTitle = $group->title; + $groupId = (string)$group->id; + } $response[] = [ 'id' => (string)$piggy->id, 'name' => $piggy->name, + 'object_group_id' => $groupId, + 'object_group_title' => $groupTitle, 'currency_id' => $currency->id, 'currency_name' => $currency->name, 'currency_code' => $currency->code, @@ -103,13 +114,23 @@ class PiggyBankController extends Controller foreach ($piggies as $piggy) { $currency = $this->accountRepository->getAccountCurrency($piggy->account) ?? $defaultCurrency; $currentAmount = $this->piggyRepository->getRepetition($piggy)->currentamount ?? '0'; - $response[] = [ + $groupTitle = null; + $groupId = null; + /** @var ObjectGroup $group */ + $group = $piggy->objectGroups()->first(); + if (null !== $group) { + $groupTitle = $group->title; + $groupId = (string)$group->id; + } + $response[] = [ 'id' => (string)$piggy->id, 'name' => $piggy->name, 'name_with_balance' => sprintf( '%s (%s / %s)', $piggy->name, app('amount')->formatAnything($currency, $currentAmount, false), app('amount')->formatAnything($currency, $piggy->targetamount, false), ), + 'object_group_id' => $groupId, + 'object_group_title' => $groupTitle, 'currency_id' => $currency->id, 'currency_name' => $currency->name, 'currency_code' => $currency->code, diff --git a/app/Repositories/PiggyBank/PiggyBankRepository.php b/app/Repositories/PiggyBank/PiggyBankRepository.php index 82bb5d5ab6..a9aa50798c 100644 --- a/app/Repositories/PiggyBank/PiggyBankRepository.php +++ b/app/Repositories/PiggyBank/PiggyBankRepository.php @@ -387,6 +387,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface /** * @inheritDoc + * TODO need to sort by group order as well. */ public function searchPiggyBank(string $query, int $limit): Collection { diff --git a/frontend/src/components/transactions/Edit.vue b/frontend/src/components/transactions/Edit.vue index 2c525bf1a3..b5727352b4 100644 --- a/frontend/src/components/transactions/Edit.vue +++ b/frontend/src/components/transactions/Edit.vue @@ -136,19 +136,19 @@ export default { groupTitle: '', originalGroupTitle: '', transactionType: 'any', - groudId: 0, + groupId: 0, // errors in the group title: groupTitleErrors: [], - // which custom fields to show TODO + // which custom fields to show customFields: {}, // group ID + title once submitted: returnedGroupId: 0, returnedGroupTitle: '', - // date and time of the transaction, TODO + // date and time of the transaction, date: new Date, time: new Date, originalDate: new Date, @@ -252,7 +252,7 @@ export default { // meta data result.category = array.category_name; result.budget_id = array.budget_id; - result.bill_id = array.bill_id; + result.bill_id = array.bill_id ?? 0; result.tags = array.tags; @@ -287,7 +287,7 @@ export default { * Get the links of this transaction group from the API. */ parseLinks: function (journalId, index) { - axios.get('./api/v1/transactions/' + journalId + '/links') + axios.get('./api/v1/transaction-journals/' + journalId + '/links') .then(response => { let links = response.data.data; for (let i in links) { @@ -342,6 +342,7 @@ export default { let direction = responses[0].direction; let linkTypeId = responses[2].data.data.id; let object = { + id: link.id, link_type_id: linkTypeId + '-' + direction, transaction_group_id: responses[1].data.data.id, transaction_journal_id: journal.transaction_journal_id, @@ -355,12 +356,13 @@ export default { }); }, /** + * TODO same method as Create * Get API value. */ getAllowedOpposingTypes: function () { - axios.get('./api/v1/configuration/static/firefly.allowed_opposing_types') + axios.get('./api/v1/configuration/firefly.allowed_opposing_types') .then(response => { - this.allowedOpposingTypes = response.data['firefly.allowed_opposing_types']; + this.allowedOpposingTypes = response.data.data.value; // console.log('Set allowedOpposingTypes'); }); }, @@ -439,6 +441,7 @@ export default { submission.group_title = this.groupTitle; shouldSubmit = true; } + let transactionCount = this.originalTransactions.length; for (let i in this.transactions) { if (this.transactions.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) { // original transaction present? @@ -467,17 +470,20 @@ export default { // console.log(originalTransaction[fieldName]); // console.log(currentTransaction[fieldName]); diff[fieldName] = currentTransaction[fieldName]; + shouldSubmit = true; } } } if (0 !== currentTransaction.piggy_bank_id) { diff.piggy_bank_id = currentTransaction.piggy_bank_id; + shouldSubmit = true; } if (JSON.stringify(currentTransaction.tags) !== JSON.stringify(originalTransaction.tags)) { // console.log('tags are different'); // console.log(currentTransaction.tags); // console.log(originalTransaction.tags); diff.tags = currentTransaction.tags; + shouldSubmit = true; } // compare links: @@ -515,10 +521,13 @@ export default { dateStr = toW3CString(theDate); submission.date = dateStr; } - - if (Object.keys(diff).length !== 0) { + if (Object.keys(diff).length === 0 && transactionCount > 1) { diff.transaction_journal_id = originalTransaction.transaction_journal_id; - submission.transactions.push(diff); + submission.transactions.push(lodashClonedeep(diff)); + shouldSubmit = true; + } else if (Object.keys(diff).length !== 0) { + diff.transaction_journal_id = originalTransaction.transaction_journal_id; + submission.transactions.push(lodashClonedeep(diff)); shouldSubmit = true; } } @@ -529,8 +538,12 @@ export default { console.log(shouldLinks); console.log(shouldSubmit); if (shouldSubmit) { - this.submitUpdate(submission); + this.submitUpdate(submission, shouldLinks, shouldUpload); } + if (!shouldSubmit && shouldLinks) { + this.submitTransactionLinks(); + } + //console.log(submission); }, compareLinks: function (array) { @@ -553,17 +566,24 @@ export default { // console.log(compare); return JSON.stringify(compare); }, - submitUpdate: function (submission) { + submitUpdate: function (submission, shouldLinks, shouldUpload) { console.log('submitUpdate'); const url = './api/v1/transactions/' + this.groupId; + console.log(submission); axios.put(url, submission) .then(response => { - // console.log('Response is OK!'); + console.log('Response is OK!'); // report the transaction is submitted. this.submittedTransaction = true; - // // submit links and attachments (can only be done when the transaction is created) - // this.submitTransactionLinks(data, response); + // submit links and attachments (can only be done when the transaction is created) + if (shouldLinks) { + console.log('Need to update links.'); + this.submitTransactionLinks(); + } + if (!shouldLinks) { + console.log('No need to update links.'); + } // this.submitAttachments(data, response); // // // meanwhile, store the ID and the title in some easy to access variables. @@ -678,6 +698,116 @@ export default { resetErrors(payload) { this.transactions[payload.index].errors = lodashClonedeep(getDefaultErrors()); }, + + deleteOriginalLinks: function (transaction) { + console.log(transaction.links); + for (let i in transaction.links) { + if (transaction.links.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) { + let current = transaction.links[i]; + let url = '/api/v1/transaction_links/' + current.id; + axios.delete(url).then(response => { + // TODO response + }); + } + } + }, + + /** + * Submit transaction links. + * TODO same method as CREATE + */ + submitTransactionLinks() { + let total = 0; + let promises = []; + + console.log('submitTransactionLinks()'); + for (let i in this.transactions) { + if (this.transactions.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) { + // original transaction present? + let currentTransaction = this.transactions[i]; + let originalTransaction = this.originalTransactions.hasOwnProperty(i) ? this.originalTransactions[i] : {}; + // compare links: + let newLinks = this.compareLinks(currentTransaction.links); + let originalLinks = this.compareLinks(originalTransaction.links); + if (newLinks !== originalLinks) { + if ('[]' !== originalLinks) { + this.deleteOriginalLinks(originalTransaction); + } + + console.log('links are different!'); + // console.log(newLinks); + // console.log(originalLinks); + for (let ii in currentTransaction.links) { + if (currentTransaction.links.hasOwnProperty(ii) && /^0$|^[1-9]\d*$/.test(ii) && ii <= 4294967294) { + let currentLink = currentTransaction.links[ii]; + let linkObject = { + inward_id: currentTransaction.transaction_journal_id, + outward_id: currentTransaction.transaction_journal_id, + link_type_id: 'something' + }; + + let parts = currentLink.link_type_id.split('-'); + linkObject.link_type_id = parts[0]; + if ('inward' === parts[1]) { + linkObject.inward_id = currentLink.transaction_journal_id; + } + if ('outward' === parts[1]) { + linkObject.outward_id = currentLink.transaction_journal_id; + } + + console.log(linkObject); + total++; + // submit transaction link: + promises.push(axios.post('./api/v1/transaction_links', linkObject).then(response => { + // TODO error handling. + })); + } + } + + // shouldLinks = true; + } + + } + } + + + return; + let result = response.data.data.attributes.transactions; + + // for (let i in data.transactions) { + // if (data.transactions.hasOwnProperty(i) && /^0$|^[1-9]\d*$/.test(i) && i <= 4294967294) { + // let submitted = data.transactions[i]; + // if (result.hasOwnProperty(i)) { + // // found matching created transaction. + // let received = result[i]; + // // grab ID from received, loop "submitted" transaction links + // for (let ii in submitted.links) { + // if (submitted.links.hasOwnProperty(ii) && /^0$|^[1-9]\d*$/.test(ii) && ii <= 4294967294) { + // let currentLink = submitted.links[ii]; + // total++; + // if (0 === currentLink.outward_id) { + // currentLink.outward_id = received.transaction_journal_id; + // } + // if (0 === currentLink.inward_id) { + // currentLink.inward_id = received.transaction_journal_id; + // } + // // submit transaction link: + // promises.push(axios.post('./api/v1/transaction_links', currentLink).then(response => { + // // TODO error handling. + // })); + // } + // } + // } + // } + // } + if (0 === total) { + this.submittedLinks = true; + return; + } + Promise.all(promises).then(function () { + this.submittedLinks = true; + }); + }, } } diff --git a/frontend/src/components/transactions/TransactionLinks.vue b/frontend/src/components/transactions/TransactionLinks.vue index a6b8faae07..ee56cac09c 100644 --- a/frontend/src/components/transactions/TransactionLinks.vue +++ b/frontend/src/components/transactions/TransactionLinks.vue @@ -27,7 +27,9 @@

- +

  • @@ -64,13 +66,13 @@
- +
-