[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