Skip to content

Commit

Permalink
Add an option to add a reversing transaction to the one(s) currently…
Browse files Browse the repository at this point in the history
… selected:

 - add negateValue() to MyMoneySplit which does exactly that.
 - add reverse() to MyMoneyTransaction which negates value of all its splits, effectively reversing the transaction.
 - refactor slotDuplicateTransaction(reverse bool) to optionally handle the reversing. Assuming typical use case being to transfer the reversed amount to an income/expense category, the reversed transaction has the same date as the original.
 - add Icon::Reverse
  • Loading branch information
wrobelda committed Mar 20, 2020
1 parent 57d5c38 commit 170be2e
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 35 deletions.
3 changes: 2 additions & 1 deletion kmymoney/icons/icons.cpp
Expand Up @@ -206,7 +206,8 @@ namespace Icons {
{Icon::PreferencesFont, QStringLiteral("preferences-desktop-font")},
{Icon::PreferencesIcon, QStringLiteral("preferences-desktop-icon")},
{Icon::NetworkDisconect, QStringLiteral("network-disconnect")},
{Icon::Folder, QStringLiteral("folder")}
{Icon::Folder, QStringLiteral("folder")},
{Icon::Reverse, QStringLiteral("reverse")},
};
}

Expand Down
2 changes: 1 addition & 1 deletion kmymoney/icons/icons.h
Expand Up @@ -98,7 +98,7 @@ enum class Icon { SVNUpdate, Merge, Reconcile, Split, Tip, Fork,
InvestmentNew, InvestmentEdit,
InvestmentDelete, InvestmentOnlinePrice,
BudgetNew, BudgetRename, BudgetDelete, BudgetCopy,
PriceUpdate, ToolUpdatePrices
PriceUpdate, ToolUpdatePrices, Reverse
};

KMM_ICONS_EXPORT void setIconThemeNames(const QString &_themeName);
Expand Down
1 change: 1 addition & 0 deletions kmymoney/kmymoney.cpp
Expand Up @@ -1496,6 +1496,7 @@ QHash<Action, QAction *> KMyMoneyApp::initActions()
{Action::CancelTransaction, QStringLiteral("transaction_cancel"), i18nc("Cancel transaction edit", "Cancel"), Icon::DialogCancel},
{Action::DeleteTransaction, QStringLiteral("transaction_delete"), i18nc("Delete transaction", "Delete"), Icon::EditDelete},
{Action::DuplicateTransaction, QStringLiteral("transaction_duplicate"), i18nc("Duplicate transaction", "Duplicate"), Icon::EditCopy},
{Action::AddReversingTransaction, QStringLiteral("transaction_add_reversing"), i18nc("Add reversing transaction", "Add reversing"),Icon::Reverse},
{Action::MatchTransaction, QStringLiteral("transaction_match"), i18nc("Button text for match transaction", "Match"),Icon::TransactionMatch},
{Action::AcceptTransaction, QStringLiteral("transaction_accept"), i18nc("Accept 'imported' and 'matched' transaction", "Accept"), Icon::TransactionAccept},
{Action::ToggleReconciliationFlag, QStringLiteral("transaction_mark_toggle"), i18nc("Toggle reconciliation flag", "Toggle"), Icon::Empty},
Expand Down
2 changes: 2 additions & 0 deletions kmymoney/kmymoneyui.rc
Expand Up @@ -75,6 +75,7 @@
<Action name="transaction_editsplits" />
<Action name="transaction_delete" />
<Action name="transaction_duplicate" />
<Action name="transaction_add_reversing" />
<Menu name="transaction_mark_menu">
<text>Mark transaction as...</text>
<title>Mark transaction</title>
Expand Down Expand Up @@ -200,6 +201,7 @@
<Action name="transaction_editsplits" />
<Action name="transaction_delete" />
<Action name="transaction_duplicate" />
<Action name="transaction_add_reversing" />
<Action name="transaction_copy_splits" />
<Menu name="transaction_move_menu">
<text>Move transaction to...</text>
Expand Down
2 changes: 1 addition & 1 deletion kmymoney/menus/menuenums.h
Expand Up @@ -72,7 +72,7 @@ namespace eMenu {
// *************
NewTransaction, EditTransaction, DeleteTransaction,
EnterTransaction, CancelTransaction,
DuplicateTransaction,
DuplicateTransaction, AddReversingTransaction,
MatchTransaction, AcceptTransaction,
EditSplits, CopySplits,
ToggleReconciliationFlag, MarkCleared,
Expand Down
6 changes: 6 additions & 0 deletions kmymoney/mymoney/mymoneysplit.cpp
Expand Up @@ -187,6 +187,12 @@ void MyMoneySplit::setValue(const MyMoneyMoney& value, const QString& transactio
setShares(value);
}

void MyMoneySplit::negateValue()
{
Q_D(MyMoneySplit);
d->m_value = d->m_value * MyMoneyMoney::MINUS_ONE;
}

QString MyMoneySplit::payeeId() const
{
Q_D(const MyMoneySplit);
Expand Down
1 change: 1 addition & 0 deletions kmymoney/mymoney/mymoneysplit.h
Expand Up @@ -140,6 +140,7 @@ class KMM_MYMONEY_EXPORT MyMoneySplit : public MyMoneyObject, public MyMoneyKeyV
*/
void setValue(const MyMoneyMoney& value, const QString& transactionCurrencyId, const QString& splitCurrencyId);

void negateValue();

QString accountId() const;
void setAccountId(const QString& account);
Expand Down
7 changes: 7 additions & 0 deletions kmymoney/mymoney/mymoneytransaction.cpp
Expand Up @@ -316,6 +316,13 @@ MyMoneyMoney MyMoneyTransaction::splitSum() const
return result;
}

void MyMoneyTransaction::reverse()
{
Q_D(MyMoneyTransaction);
for (MyMoneySplit& split : d->m_splits)
split.negateValue();
}

bool MyMoneyTransaction::isLoanPayment() const
{
try {
Expand Down
5 changes: 5 additions & 0 deletions kmymoney/mymoney/mymoneytransaction.h
Expand Up @@ -189,6 +189,11 @@ class KMM_MYMONEY_EXPORT MyMoneyTransaction : public MyMoneyObject, public MyMon
*/
MyMoneyMoney splitSum() const;

/**
* This method is used to reverse a transaction by reversing the values of each split
*/
void reverse();

/**
* This method returns information if the transaction
* contains information of a loan payment or not.
Expand Down
71 changes: 40 additions & 31 deletions kmymoney/views/kgloballedgerview.cpp
Expand Up @@ -76,33 +76,33 @@ QDate KGlobalLedgerViewPrivate::m_lastPostDate;
KGlobalLedgerView::KGlobalLedgerView(QWidget *parent) :
KMyMoneyViewBase(*new KGlobalLedgerViewPrivate(this), parent)
{
typedef void(KGlobalLedgerView::*KGlobalLedgerViewFunc)();
const QHash<Action, KGlobalLedgerViewFunc> actionConnections {
{Action::NewTransaction, &KGlobalLedgerView::slotNewTransaction},
{Action::EditTransaction, &KGlobalLedgerView::slotEditTransaction},
{Action::DeleteTransaction, &KGlobalLedgerView::slotDeleteTransaction},
{Action::DuplicateTransaction, &KGlobalLedgerView::slotDuplicateTransaction},
{Action::EnterTransaction, &KGlobalLedgerView::slotEnterTransaction},
{Action::AcceptTransaction, &KGlobalLedgerView::slotAcceptTransaction},
{Action::CancelTransaction, &KGlobalLedgerView::slotCancelTransaction},
{Action::EditSplits, &KGlobalLedgerView::slotEditSplits},
{Action::CopySplits, &KGlobalLedgerView::slotCopySplits},
{Action::GoToPayee, &KGlobalLedgerView::slotGoToPayee},
{Action::GoToAccount, &KGlobalLedgerView::slotGoToAccount},
{Action::MatchTransaction, &KGlobalLedgerView::slotMatchTransactions},
{Action::CombineTransactions, &KGlobalLedgerView::slotCombineTransactions},
{Action::ToggleReconciliationFlag, &KGlobalLedgerView::slotToggleReconciliationFlag},
{Action::MarkCleared, &KGlobalLedgerView::slotMarkCleared},
{Action::MarkReconciled, &KGlobalLedgerView::slotMarkReconciled},
{Action::MarkNotReconciled, &KGlobalLedgerView::slotMarkNotReconciled},
{Action::SelectAllTransactions, &KGlobalLedgerView::slotSelectAllTransactions},
{Action::NewScheduledTransaction, &KGlobalLedgerView::slotCreateScheduledTransaction},
{Action::AssignTransactionsNumber, &KGlobalLedgerView::slotAssignNumber},
{Action::StartReconciliation, &KGlobalLedgerView::slotStartReconciliation},
{Action::FinishReconciliation, &KGlobalLedgerView::slotFinishReconciliation},
{Action::PostponeReconciliation, &KGlobalLedgerView::slotPostponeReconciliation},
{Action::OpenAccount, &KGlobalLedgerView::slotOpenAccount},
{Action::EditFindTransaction, &KGlobalLedgerView::slotFindTransaction},
const QHash<Action, std::function<void()>> actionConnections {
{Action::NewTransaction, [this](){ KGlobalLedgerView::slotNewTransaction(); }},
{Action::EditTransaction, [this](){ KGlobalLedgerView::slotEditTransaction(); }},
{Action::DeleteTransaction, [this](){ KGlobalLedgerView::slotDeleteTransaction(); }},
{Action::DuplicateTransaction, [this](){ KGlobalLedgerView::slotDuplicateTransaction(); }},
{Action::AddReversingTransaction, [this](){ KGlobalLedgerView::slotDuplicateTransaction(true); }},
{Action::EnterTransaction, [this](){ KGlobalLedgerView::slotEnterTransaction(); }},
{Action::AcceptTransaction, [this](){ KGlobalLedgerView::slotAcceptTransaction(); }},
{Action::CancelTransaction, [this](){ KGlobalLedgerView::slotCancelTransaction(); }},
{Action::EditSplits, [this](){ KGlobalLedgerView::slotEditSplits(); }},
{Action::CopySplits, [this](){ KGlobalLedgerView::slotCopySplits(); }},
{Action::GoToPayee, [this](){ KGlobalLedgerView::slotGoToPayee(); }},
{Action::GoToAccount, [this](){ KGlobalLedgerView::slotGoToAccount(); }},
{Action::MatchTransaction, [this](){ KGlobalLedgerView::slotMatchTransactions(); }},
{Action::CombineTransactions, [this](){ KGlobalLedgerView::slotCombineTransactions(); }},
{Action::ToggleReconciliationFlag, [this](){ KGlobalLedgerView::slotToggleReconciliationFlag(); }},
{Action::MarkCleared, [this](){ KGlobalLedgerView::slotMarkCleared(); }},
{Action::MarkReconciled, [this](){ KGlobalLedgerView::slotMarkReconciled(); }},
{Action::MarkNotReconciled, [this](){ KGlobalLedgerView::slotMarkNotReconciled(); }},
{Action::SelectAllTransactions, [this](){ KGlobalLedgerView::slotSelectAllTransactions(); }},
{Action::NewScheduledTransaction, [this](){ KGlobalLedgerView::slotCreateScheduledTransaction(); }},
{Action::AssignTransactionsNumber, [this](){ KGlobalLedgerView::slotAssignNumber(); }},
{Action::StartReconciliation, [this](){ KGlobalLedgerView::slotStartReconciliation(); }},
{Action::FinishReconciliation, [this](){ KGlobalLedgerView::slotFinishReconciliation(); }},
{Action::PostponeReconciliation, [this](){ KGlobalLedgerView::slotPostponeReconciliation(); }},
{Action::OpenAccount, [this](){ KGlobalLedgerView::slotOpenAccount(); }},
{Action::EditFindTransaction, [this](){ KGlobalLedgerView::slotFindTransaction(); }},
};

for (auto a = actionConnections.cbegin(); a != actionConnections.cend(); ++a)
Expand Down Expand Up @@ -288,7 +288,7 @@ void KGlobalLedgerView::updateLedgerActionsInternal()
const QVector<Action> actionsToBeDisabled {
Action::EditTransaction, Action::EditSplits, Action::EnterTransaction,
Action::CancelTransaction, Action::DeleteTransaction, Action::MatchTransaction,
Action::AcceptTransaction, Action::DuplicateTransaction, Action::ToggleReconciliationFlag, Action::MarkCleared,
Action::AcceptTransaction, Action::DuplicateTransaction, Action::AddReversingTransaction, Action::ToggleReconciliationFlag, Action::MarkCleared,
Action::GoToAccount, Action::GoToPayee, Action::AssignTransactionsNumber, Action::NewScheduledTransaction,
Action::CombineTransactions, Action::CopySplits,
};
Expand Down Expand Up @@ -320,6 +320,10 @@ void KGlobalLedgerView::updateLedgerActionsInternal()
pActions[Action::DuplicateTransaction]->setEnabled(canDuplicateTransactions(d->m_selectedTransactions, tooltip) && !d->m_selectedTransactions[0].transaction().id().isEmpty());
pActions[Action::DuplicateTransaction]->setToolTip(tooltip);

tooltip = i18n("Add reversing transactions to the currently selected");
pActions[Action::AddReversingTransaction]->setEnabled(canDuplicateTransactions(d->m_selectedTransactions, tooltip) && !d->m_selectedTransactions[0].transaction().id().isEmpty());
pActions[Action::AddReversingTransaction]->setToolTip(tooltip);

if (canEditTransactions(d->m_selectedTransactions, tooltip)) {
pActions[Action::EditTransaction]->setEnabled(true);
// editing splits is allowed only if we have one transaction selected
Expand Down Expand Up @@ -1514,7 +1518,7 @@ void KGlobalLedgerView::slotDeleteTransaction()
}
}

void KGlobalLedgerView::slotDuplicateTransaction()
void KGlobalLedgerView::slotDuplicateTransaction(bool reverse)
{
Q_D(KGlobalLedgerView);
// since we may jump here via code, we have to make sure to react only
Expand All @@ -1541,8 +1545,13 @@ void KGlobalLedgerView::slotDuplicateTransaction()
// clear invalid data
t.setEntryDate(QDate());
t.clearId();
// and set the post date to today
t.setPostDate(QDate::currentDate());

if (reverse)
// reverse transaction
t.reverse();
else
// set the post date to today
t.setPostDate(QDate::currentDate());

MyMoneyFile::instance()->addTransaction(t);
lt = t;
Expand Down
2 changes: 1 addition & 1 deletion kmymoney/views/kgloballedgerview.h
Expand Up @@ -253,7 +253,7 @@ private Q_SLOTS:
void slotNewTransaction();
void slotEditTransaction();
void slotDeleteTransaction();
void slotDuplicateTransaction();
void slotDuplicateTransaction(bool reverse = false);
void slotEnterTransaction();

/**
Expand Down

0 comments on commit 170be2e

Please sign in to comment.