Refactor gncOwnerReduceSplitTo out of reduce_biggest_split

It can now be used both for scrubbing and when applying payments
This commit is contained in:
Geert Janssens 2014-08-26 19:24:56 +02:00
parent 7b642081a3
commit e44bb5ffac
3 changed files with 43 additions and 33 deletions

View File

@ -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));
}

View File

@ -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)
{

View File

@ -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