From d6cdfd49a1d15390d3c8325527fac4c179f100aa Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 30 Sep 2026 18:48:24 +0200 Subject: [PATCH] Add remove money buttons. --- config/translations.php | 1 + .../assets/v3/js/pages/transactions/create.js | 20 ++-- .../assets/v3/js/pages/transactions/edit.js | 103 ++++++++++-------- .../transactions/shared/changed-amount.js | 20 +++- .../shared/changed-foreign-amount.js | 25 +++-- .../pages/transactions/shared/clear-fields.js | 16 +++ resources/lang/en_US/firefly.php | 1 + .../form/transaction/amount.blade.php | 3 + .../form/transaction/foreign-amount.blade.php | 3 + 9 files changed, 127 insertions(+), 65 deletions(-) diff --git a/config/translations.php b/config/translations.php index d6a6d60896..6591c0599f 100644 --- a/config/translations.php +++ b/config/translations.php @@ -70,6 +70,7 @@ return [ 'never', 'account_type_loan', 'account_type_mortgage', + 'account_type_Cash account', 'account_type_debt', 'withdrawal', 'i_owe_amount', diff --git a/resources/assets/v3/js/pages/transactions/create.js b/resources/assets/v3/js/pages/transactions/create.js index ff4d7107e5..06e875d688 100644 --- a/resources/assets/v3/js/pages/transactions/create.js +++ b/resources/assets/v3/js/pages/transactions/create.js @@ -41,7 +41,14 @@ import i18next from "i18next"; import { processUploadError } from "./shared/process-upload-error.js"; import { showMessageOrRedirectUser } from "./shared/show-message-or-redirect.js"; import { addSplit } from "./shared/add-split.js"; -import { clearDestinationAccount, clearSourceAccount } from "./shared/clear-fields.js"; +import { + clearDestinationAccount, + clearSourceAccount, + clearCategory, + clearDescription, + clearAmount, + clearForeignAmount +} from "./shared/clear-fields.js"; import { detectTransactionType } from "./shared/detect-transaction-type.js"; import { determineAmountCurrency } from "./shared/determine-amount-currency.js"; import { loadCustomFields } from "./shared/load-custom-fields.js"; @@ -203,6 +210,10 @@ let create = function () { removeSplit: removeSplit, clearSourceAccount: clearSourceAccount, clearDestinationAccount: clearDestinationAccount, + clearCategory: clearCategory, + clearDescription: clearDescription, + clearAmount: clearAmount, + clearForeignAmount: clearForeignAmount, detectTransactionType: detectTransactionType, determineAmountCurrency: determineAmountCurrency, addAllAutocompleteToForm: addAllAutocompleteToForm, @@ -238,12 +249,7 @@ let create = function () { this.formStates.storedAttachments = true; this.showMessageOrRedirectUser("create.js processUpload"); }, - clearDescription(index) { - this.entries[index].description = ""; - }, - clearCategory(index) { - this.entries[index].category_name = ""; - }, + fillSourceAccount() { this.fillAccount("source", "source_account"); }, diff --git a/resources/assets/v3/js/pages/transactions/edit.js b/resources/assets/v3/js/pages/transactions/edit.js index f25fffe43a..a0c3c7377b 100644 --- a/resources/assets/v3/js/pages/transactions/edit.js +++ b/resources/assets/v3/js/pages/transactions/edit.js @@ -21,54 +21,61 @@ import "../../boot/bootstrap.js"; import dates from "../../pages/shared/dates.js"; import Get from "../../api/model/transaction/get.js"; -import { parseDownloadedSplits } from "./shared/parse-downloaded-splits.js"; -import { addAllAutocompleteToForm } from "./shared/add-autocomplete.js"; -import { loadCurrencies } from "./shared/load-currencies.js"; -import { loadBudgets } from "./shared/load-budgets.js"; -import { loadPiggyBanks } from "./shared/load-piggy-banks.js"; -import { processUploadError } from "./shared/process-upload-error.js"; -import { loadSubscriptions } from "./shared/load-subscriptions.js"; +import {parseDownloadedSplits} from "./shared/parse-downloaded-splits.js"; +import {addAllAutocompleteToForm} from "./shared/add-autocomplete.js"; +import {loadCurrencies} from "./shared/load-currencies.js"; +import {loadBudgets} from "./shared/load-budgets.js"; +import {loadPiggyBanks} from "./shared/load-piggy-banks.js"; +import {processUploadError} from "./shared/process-upload-error.js"; +import {loadSubscriptions} from "./shared/load-subscriptions.js"; import i18next from "i18next"; -import { defaultErrorSet } from "./shared/create-empty-split.js"; -import { parseFromEntries } from "./shared/parse-from-entries.js"; +import {defaultErrorSet} from "./shared/create-empty-split.js"; +import {parseFromEntries} from "./shared/parse-from-entries.js"; import Put from "../../api/model/transaction/put.js"; -import { showMessageOrRedirectUser } from "./shared/show-message-or-redirect.js"; -import { processAttachments } from "./shared/process-attachments.js"; +import {showMessageOrRedirectUser} from "./shared/show-message-or-redirect.js"; +import {processAttachments} from "./shared/process-attachments.js"; import sidebar from "../shared/sidebar.js"; -import { disableSplitInputs } from "./shared/disable-split-inputs.js"; -import { parseTotalAmount } from "./shared/parse-total-amount.js"; -import { keyUpFromCategory } from "./shared/keyup-from-category.js"; -import { keyUpFromSource } from "./shared/keyup-from-source.js"; -import { keyUpFromDestination } from "./shared/keyup-from-destination.js"; -import { keyUpFromDescription } from "./shared/keyup-from-description.js"; -import { changedAmount } from "./shared/changed-amount.js"; -import { changedForeignAmount } from "./shared/changed-foreign-amount.js"; -import { parseErrors } from "./shared/parse-errors.js"; -import { addSplit } from "./shared/add-split.js"; -import { clearDestinationAccount, clearSourceAccount } from "./shared/clear-fields.js"; -import { detectTransactionType } from "./shared/detect-transaction-type.js"; -import { determineAmountCurrency } from "./shared/determine-amount-currency.js"; -import { loadCustomFields } from "./shared/load-custom-fields.js"; -import { displayMap } from "./shared/display-map.js"; -import { loadDefaultCoordinates } from "./shared/load-default-coordinates.js"; -import { renderMap } from "./shared/render-map.js"; +import {disableSplitInputs} from "./shared/disable-split-inputs.js"; +import {parseTotalAmount} from "./shared/parse-total-amount.js"; +import {keyUpFromCategory} from "./shared/keyup-from-category.js"; +import {keyUpFromSource} from "./shared/keyup-from-source.js"; +import {keyUpFromDestination} from "./shared/keyup-from-destination.js"; +import {keyUpFromDescription} from "./shared/keyup-from-description.js"; +import {changedAmount} from "./shared/changed-amount.js"; +import {changedForeignAmount} from "./shared/changed-foreign-amount.js"; +import {parseErrors} from "./shared/parse-errors.js"; +import {addSplit} from "./shared/add-split.js"; +import { + clearAmount, + clearCategory, + clearDescription, + clearForeignAmount, + clearDestinationAccount, + clearSourceAccount +} from "./shared/clear-fields.js"; +import {detectTransactionType} from "./shared/detect-transaction-type.js"; +import {determineAmountCurrency} from "./shared/determine-amount-currency.js"; +import {loadCustomFields} from "./shared/load-custom-fields.js"; +import {displayMap} from "./shared/display-map.js"; +import {loadDefaultCoordinates} from "./shared/load-default-coordinates.js"; +import {renderMap} from "./shared/render-map.js"; import "leaflet/dist/leaflet.css"; -import { onMapClick } from "./shared/on-map-click.js"; -import { onMapZoom } from "./shared/on-map-zoom.js"; -import { clearLocation } from "./shared/clear-location.js"; -import { removeSplit } from "./shared/remove-split.js"; -import { loadTransactionLinks } from "./shared/load-transaction-links.js"; -import { createLinkAutocomplete } from "./shared/create-link-autocomplete.js"; -import { editLink } from "./shared/edit-link.js"; -import { switchLink } from "./shared/switch-link.js"; -import { removeLink } from "./shared/remove-link.js"; -import { saveEditedLink } from "./shared/save-edited-link.js"; -import { saveNewLink } from "./shared/save-new-link.js"; -import { processTransactionLinks } from "./shared/process-transaction-links.js"; -import { redirectAfterTransactionLinks } from "./shared/redirect-after-transaction-links.js"; -import { addTabListener } from "./shared/add-tab-listener.js"; -import { autoStep } from "./shared/auto-step.js"; -import { respondToTabSwitch } from "./shared/respond-to-tab-switch.js"; +import {onMapClick} from "./shared/on-map-click.js"; +import {onMapZoom} from "./shared/on-map-zoom.js"; +import {clearLocation} from "./shared/clear-location.js"; +import {removeSplit} from "./shared/remove-split.js"; +import {loadTransactionLinks} from "./shared/load-transaction-links.js"; +import {createLinkAutocomplete} from "./shared/create-link-autocomplete.js"; +import {editLink} from "./shared/edit-link.js"; +import {switchLink} from "./shared/switch-link.js"; +import {removeLink} from "./shared/remove-link.js"; +import {saveEditedLink} from "./shared/save-edited-link.js"; +import {saveNewLink} from "./shared/save-new-link.js"; +import {processTransactionLinks} from "./shared/process-transaction-links.js"; +import {redirectAfterTransactionLinks} from "./shared/redirect-after-transaction-links.js"; +import {addTabListener} from "./shared/add-tab-listener.js"; +import {autoStep} from "./shared/auto-step.js"; +import {respondToTabSwitch} from "./shared/respond-to-tab-switch.js"; import Alpine from "@alpinejs/csp"; import focusFirstInput from "../../shared/focus-first-input.js"; import filterForeignCurrencies from "./shared/filter-foreign-currencies.js"; @@ -183,6 +190,10 @@ let transactions = function () { addSplit: addSplit, clearSourceAccount: clearSourceAccount, clearDestinationAccount: clearDestinationAccount, + clearCategory: clearCategory, + clearDescription: clearDescription, + clearAmount: clearAmount, + clearForeignAmount: clearForeignAmount, detectTransactionType: detectTransactionType, determineAmountCurrency: determineAmountCurrency, addAllAutocompleteToForm: addAllAutocompleteToForm, @@ -401,7 +412,7 @@ let transactions = function () { // submit the transaction. Multi-stage process thing going on here! let putter = new Put(); putter - .put(submission, { id: this.groupProperties.id }) + .put(submission, {id: this.groupProperties.id}) .then((response) => { this.formStates.storedGroup = true; const group = response.data.data; @@ -454,7 +465,7 @@ let transactions = function () { }; }; -let comps = { transactions, sidebar, dates }; +let comps = {transactions, sidebar, dates}; function loadPage() { Object.keys(comps).forEach((comp) => { diff --git a/resources/assets/v3/js/pages/transactions/shared/changed-amount.js b/resources/assets/v3/js/pages/transactions/shared/changed-amount.js index 63cb3fa35a..67026d09ad 100644 --- a/resources/assets/v3/js/pages/transactions/shared/changed-amount.js +++ b/resources/assets/v3/js/pages/transactions/shared/changed-amount.js @@ -18,9 +18,23 @@ * along with this program. If not, see . */ -export function changedAmount(e) { - const index = parseInt(e.target.dataset.index); - this.entries[index].amount = parseFloat(e.target.value); +export function changedAmount(e, givenIndex) { + let index = 0; + if (null === e) { + index = parseInt(givenIndex); + } + if (null !== e) { + index = parseInt(e.target.dataset.index); + let value = e.target.value; + // switch commas for dots. + let len = (value.match(/,/g) || []).length; + if(1 === len) { + value = value.replace(',', '.'); + } + this.entries[index].amount = parseFloat(value); + } + + this.groupProperties.totalAmount = 0; for (let i in this.entries) { if (Object.hasOwn(this.entries, i)) { diff --git a/resources/assets/v3/js/pages/transactions/shared/changed-foreign-amount.js b/resources/assets/v3/js/pages/transactions/shared/changed-foreign-amount.js index 9ed7cd2a4e..3c592c517a 100644 --- a/resources/assets/v3/js/pages/transactions/shared/changed-foreign-amount.js +++ b/resources/assets/v3/js/pages/transactions/shared/changed-foreign-amount.js @@ -18,13 +18,20 @@ * along with this program. If not, see . */ -export function changedForeignAmount(e) { - const index = parseInt(e.target.dataset.index); - this.entries[index].foreign_amount = parseFloat(e.target.value); - //this.groupProperties.totalAmount = 0; - // for (let i in this.entries) { - // if (this.entries.hasOwnProperty(i)) { - // this.groupProperties.totalAmount = this.groupProperties.totalAmount + parseFloat(this.entries[i].amount); - // } - // } +export function changedForeignAmount(e, givenIndex) { + let index = 0; + if (null === e) { + index = parseInt(givenIndex); + } + if (null !== e) { + index = parseInt(e.target.dataset.index); + let value = e.target.value; + // switch commas for dots. + let len = (value.match(/,/g) || []).length; + if (1 === len) { + value = value.replace(',', '.'); + } + this.entries[index].foreign_amount = parseFloat(value); + } + } diff --git a/resources/assets/v3/js/pages/transactions/shared/clear-fields.js b/resources/assets/v3/js/pages/transactions/shared/clear-fields.js index e84d9763c4..4094b48d2d 100644 --- a/resources/assets/v3/js/pages/transactions/shared/clear-fields.js +++ b/resources/assets/v3/js/pages/transactions/shared/clear-fields.js @@ -29,3 +29,19 @@ export function clearDestinationAccount(index) { this.entries[index].destination_account = getAccount(); this.detectTransactionType(); } +export function clearDescription(index) { + this.entries[index].description = ""; +} +export function clearAmount(index) { + this.entries[index].amount = ""; + this.changedAmount(null, index); +} + +export function clearForeignAmount(index) { + this.entries[index].foreign_amount = ""; + this.changedForeignAmount(null, index); +} + +export function clearCategory(index) { + this.entries[index].category_name = ""; +}; diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index 973ff20bc1..7a73bdc20d 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -2324,6 +2324,7 @@ return [ 'account_type_loan' => 'Loan', 'account_type_mortgage' => 'Mortgage', 'account_type_Credit card' => 'Credit card', + 'account_type_Cash account' => 'Cash account', 'credit_card_type_monthlyFull' => 'Full payment every month', 'liability_direction_credit' => 'I am owed this debt', 'liability_direction_debit' => 'I owe this debt to somebody else', diff --git a/resources/views/partials/form/transaction/amount.blade.php b/resources/views/partials/form/transaction/amount.blade.php index 101dea95aa..f5c3d5e76f 100644 --- a/resources/views/partials/form/transaction/amount.blade.php +++ b/resources/views/partials/form/transaction/amount.blade.php @@ -5,6 +5,7 @@
+
+ +