From e44bb5ffac76beb3171bef310f600b4f3a8cfa9c Mon Sep 17 00:00:00 2001 From: Geert Janssens Date: Tue, 26 Aug 2014 19:24:56 +0200 Subject: [PATCH] Refactor gncOwnerReduceSplitTo out of reduce_biggest_split It can now be used both for scrubbing and when applying payments --- src/engine/ScrubBusiness.c | 36 +++--------------------------------- src/engine/gncOwner.c | 32 ++++++++++++++++++++++++++++++++ src/engine/gncOwner.h | 8 ++++++++ 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/src/engine/ScrubBusiness.c b/src/engine/ScrubBusiness.c index 979cc45e8b..8eb6ccca4a 100644 --- a/src/engine/ScrubBusiness.c +++ b/src/engine/ScrubBusiness.c @@ -64,41 +64,11 @@ static gboolean reduce_biggest_split (Split *splitA, Split *splitB) { gnc_numeric valA = xaccSplitGetValue (splitA); gnc_numeric valB = xaccSplitGetValue (splitB); - gnc_numeric new_val, rem_val; - Split *to_reduce, *rem_split; - Transaction *txn; - GNCLot *lot; - if (gnc_numeric_positive_p (valA) == gnc_numeric_positive_p (valB)) - return FALSE; //Splits are not of opposite sign - - if (gnc_numeric_equal (gnc_numeric_abs (valA), gnc_numeric_abs (valB))) - return FALSE; // Splits have an equal value (but with opposite sign - nothing to do - else if (gnc_numeric_compare (gnc_numeric_abs (valA), gnc_numeric_abs (valB)) > 0) - { - to_reduce = splitA; - new_val = gnc_numeric_neg (valB); - } + if (gnc_numeric_compare (gnc_numeric_abs (valA), gnc_numeric_abs (valB)) >= 0) + return gncOwnerReduceSplitTo (splitA, gnc_numeric_neg (valB)); else - { - to_reduce = splitB; - new_val = gnc_numeric_neg (valA); - } - - rem_val = gnc_numeric_add (valA, valB, GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD); // note: values are of opposite sign - rem_split = xaccMallocSplit (xaccSplitGetBook (to_reduce)); - xaccSplitCopyOnto (to_reduce, rem_split); - xaccSplitSetValue (rem_split, rem_val); - - txn = xaccSplitGetParent (to_reduce); - xaccTransBeginEdit (txn); - xaccSplitSetValue (to_reduce, new_val); - xaccSplitSetParent (rem_split, txn); - xaccTransCommitEdit (txn); - - lot = xaccSplitGetLot (to_reduce); - gnc_lot_add_split (lot, rem_split); - return TRUE; + return gncOwnerReduceSplitTo (splitB, gnc_numeric_neg (valA)); } diff --git a/src/engine/gncOwner.c b/src/engine/gncOwner.c index 468b5fc73b..b56e4897bc 100644 --- a/src/engine/gncOwner.c +++ b/src/engine/gncOwner.c @@ -841,6 +841,38 @@ gncOwnerCreatePaymentLot (const GncOwner *owner, Transaction *txn, return payment_lot; } +gboolean +gncOwnerReduceSplitTo (Split *split, gnc_numeric target_value) +{ + gnc_numeric split_val = xaccSplitGetValue (split); + gnc_numeric rem_val; + Split *rem_split; + Transaction *txn; + GNCLot *lot; + + if (gnc_numeric_positive_p (split_val) != gnc_numeric_positive_p (target_value)) + return FALSE; // Split and target value have to be of the same sign + + if (gnc_numeric_equal (split_val, target_value)) + return FALSE; // Split already has the target value + + rem_val = gnc_numeric_sub (split_val, target_value, GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD); // note: values are of opposite sign + rem_split = xaccMallocSplit (xaccSplitGetBook (split)); + xaccSplitCopyOnto (split, rem_split); + xaccSplitSetValue (rem_split, rem_val); + + txn = xaccSplitGetParent (split); + xaccTransBeginEdit (txn); + xaccSplitSetValue (split, target_value); + xaccSplitSetParent (rem_split, txn); + xaccTransCommitEdit (txn); + + lot = xaccSplitGetLot (split); + gnc_lot_add_split (lot, rem_split); + + return TRUE; +} + void gncOwnerSetLotLinkMemo (Transaction *ll_txn) { diff --git a/src/engine/gncOwner.h b/src/engine/gncOwner.h index 9c4a2e9a90..47ae3af820 100644 --- a/src/engine/gncOwner.h +++ b/src/engine/gncOwner.h @@ -266,6 +266,14 @@ gncOwnerApplyPayment (const GncOwner *owner, Transaction *txn, GList *lots, gnc_numeric amount, gnc_numeric exch, Timespec date, const char *memo, const char *num, gboolean auto_pay); +/** Helper function to reduce the value of a split to target_value. To make + * sure the split's parent transaction remains balanced a second split + * will be created with the remainder. Similarly if the split was part of a + * (business) lot, the remainder split will be added to the same lot to + * keep the lot's balance unchanged. + */ +gboolean gncOwnerReduceSplitTo (Split *split, gnc_numeric target_value); + /** To help a user understand what a lot link transaction does, * we set the memo to name all documents involved in the link. * The function below calculates this memo and sets it for