[Kmymoney-devel] [PATCH 1/4] payee: Added support to Merge Payee slot
Felipe F. Tonello
eu at felipetonello.com
Wed Apr 24 07:19:40 UTC 2013
From: "Felipe F. Tonello" <eu at felipetonello.com>
This patch enables a slotPayeeMerge() which makes all the operations to merge
multiple payees into one.
The operations that reassings to a new payee are:
* transactions
* schedules
* loans
* accounts
Signed-off-by: Felipe F. Tonello <eu at felipetonello.com>
---
kmymoney/kmymoney.cpp | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++
kmymoney/kmymoney.h | 5 ++
2 files changed, 142 insertions(+)
diff --git a/kmymoney/kmymoney.cpp b/kmymoney/kmymoney.cpp
index 063f8b5..05b74d6 100644
--- a/kmymoney/kmymoney.cpp
+++ b/kmymoney/kmymoney.cpp
@@ -4808,6 +4808,143 @@ void KMyMoneyApp::slotPayeeDelete(void)
}
}
+/**
+ * TODO: improve user experience (UX) by:
+ * - Use a dialog similar to the KPayeeReassignDlg. Probably just making it more generic.
+ * - Improve slotPayeeNew() to not to ask if user wants to create new payee or not.
+ *
+ * FIXME: Too much duplicated code from slotPayeeDelete() and others. The way that the
+ * MyMoney* Objects are designed requires too much repeated work, so I believe using
+ * generic helper functions might be a good idea.
+ *
+ * []'s Felipe
+ **/
+void KMyMoneyApp::slotPayeeMerge(void)
+{
+ if (d->m_selectedPayees.size() < 1)
+ return; // shouldn't happen
+
+ QString newPayee = KInputDialog::getText(i18n("Merge Payee"), i18n("New payee name"));
+ QString newPayeeId;
+
+ // create new payee
+ slotPayeeNew(newPayee, newPayeeId);
+
+ // if new payee was not created
+ if (newPayeeId.isNull())
+ return;
+
+ MyMoneyFileTransaction ft;
+
+ try {
+ MyMoneyTransactionFilter filter;
+
+ for (QList<MyMoneyPayee>::const_iterator it = d->m_selectedPayees.constBegin();
+ it != d->m_selectedPayees.constEnd();
+ ++it) {
+ filter.addPayee((*it).id());
+ }
+
+ MyMoneyFile *file = MyMoneyFile::instance();
+
+ // Go over the transactions
+ // I don't know why but with MyMoneySeqAccessMgr::transactionList(QList<MyMoneyTransaction>& list, MyMoneyTransactionFilter& filter)
+ // doesn't work.
+ QList<MyMoneyTransaction> translist = file->transactionList(filter);
+
+ for (QList<MyMoneyTransaction>::iterator it = translist.begin();
+ it != translist.end();
+ ++it) {
+ QList<MyMoneySplit> splits = (*it).splits();
+
+ // loop over all splits
+ for (QList<MyMoneySplit>::iterator s_it = splits.begin();
+ s_it != splits.end();
+ ++s_it) {
+
+ // if the split is assigned to new payees, merge it
+ if (payeeInList(d->m_selectedPayees, (*s_it).payeeId())) {
+ (*s_it).setPayeeId(newPayeeId);
+ (*it).modifySplit(*s_it); // this does not modify the list object 'splits'!
+ }
+ }
+ file->modifyTransaction(*it); // modify the transaction in the MyMoney object
+ }
+
+ // now get a list of all schedules that make use of one of the payees
+ QList<MyMoneySchedule> all_schedules = file->scheduleList();
+ QList<MyMoneySchedule> used_schedules;
+ for (QList<MyMoneySchedule>::ConstIterator it = all_schedules.constBegin();
+ it != all_schedules.constEnd(); ++it) {
+ // loop over all splits in the transaction of the schedule
+ for (QList<MyMoneySplit>::ConstIterator s_it = (*it).transaction().splits().constBegin();
+ s_it != (*it).transaction().splits().constEnd(); ++s_it) {
+ // is the payee in the split to be deleted?
+ if (payeeInList(d->m_selectedPayees, (*s_it).payeeId())) {
+ used_schedules.push_back(*it); // remember this schedule
+ break;
+ }
+ }
+ }
+
+ // now loop over all schedules and reassign payees
+ for (QList<MyMoneySchedule>::iterator it = used_schedules.begin();
+ it != used_schedules.end(); ++it) {
+ // create copy of transaction in current schedule
+ MyMoneyTransaction trans = (*it).transaction();
+ // create copy of lists of splits
+ QList<MyMoneySplit> splits = trans.splits();
+ for (QList<MyMoneySplit>::iterator s_it = splits.begin(); s_it != splits.end(); ++s_it) {
+ if (payeeInList(d->m_selectedPayees, (*s_it).payeeId())) {
+ (*s_it).setPayeeId(newPayeeId);
+ trans.modifySplit(*s_it); // does not modify the list object 'splits'!
+ }
+ }
+ // store transaction in current schedule
+ (*it).setTransaction(trans);
+ file->modifySchedule(*it); // modify the schedule in the MyMoney engine
+ }
+
+ // and a list of all loan accounts that references one of the payees
+ QList<MyMoneyAccount> allAccounts;
+ QList<MyMoneyAccount> usedAccounts;
+ file->accountList(allAccounts);
+ foreach (const MyMoneyAccount &account, allAccounts) {
+ if (account.isLoan()) {
+ MyMoneyAccountLoan loanAccount(account);
+ foreach (const MyMoneyPayee &payee, d->m_selectedPayees) {
+ if (loanAccount.hasReferenceTo(payee.id())) {
+ usedAccounts.append(account);
+ }
+ }
+ }
+ }
+
+ // reassign the payees in the loans that reference the deleted payees
+ foreach (const MyMoneyAccount &account, usedAccounts) {
+ MyMoneyAccountLoan loanAccount(account);
+ loanAccount.setPayee(newPayeeId);
+ file->modifyAccount(loanAccount);
+ }
+
+ // now loop over all selected payees and remove them
+ for (QList<MyMoneyPayee>::iterator it = d->m_selectedPayees.begin();
+ it != d->m_selectedPayees.end(); ++it) {
+ file->removePayee(*it);
+ }
+
+ ft.commit();
+
+ } catch (MyMoneyException *e) {
+ KMessageBox::detailedSorry(0, i18n("Unable to Merge payees"),
+ i18n("%1 thrown in %2:%3", e->what(), e->file(), e->line()));
+ delete e;
+ }
+
+ // If we just deleted the payees, they sure don't exist anymore
+ slotSelectPayees(QList<MyMoneyPayee>());
+}
+
void KMyMoneyApp::slotTagNew(const QString& newnameBase, QString& id)
{
bool doit = true;
diff --git a/kmymoney/kmymoney.h b/kmymoney/kmymoney.h
index 22515f4..30629ea 100644
--- a/kmymoney/kmymoney.h
+++ b/kmymoney/kmymoney.h
@@ -287,6 +287,11 @@ protected slots:
void slotPayeeDelete(void);
/**
+ * Slot that merges two or more selected payess into a new payee
+ */
+ void slotPayeeMerge(void);
+
+ /**
*/
void slotTagNew(const QString& newnameBase, QString& id);
void slotTagNew(void);
--
1.7.11.7
More information about the KMyMoney-devel
mailing list