// A helper function that takes two splits. If the splits are of opposite sign // it reduces the biggest split to have the same value (but with opposite sign) // of the smaller split. // To make sure everything still continues to balance in addition a "remainder" split // will be created that will be added to the same lot and transaction as the biggest // split. // The opposite sign restriction is because that's the only scenario that makes sense // in the context of scrubbing business lots below. // If we created new splits, return TRUE, otherwise FALSE static gboolean reduce_biggest_split (Split *splitA, Split *splitB) { gnc_numeric valA = xaccSplitGetValue (splitA); gnc_numeric valB = xaccSplitGetValue (splitB); if (gnc_numeric_compare (gnc_numeric_abs (valA), gnc_numeric_abs (valB)) >= 0) return gncOwnerReduceSplitTo (splitA, gnc_numeric_neg (valB)); else return gncOwnerReduceSplitTo (splitB, gnc_numeric_neg (valA)); }
static void gncOwnerOffsetLots (GNCLot *from_lot, GNCLot *to_lot, const GncOwner *owner) { gnc_numeric target_offset; Split *split; /* from lot should not be a document lot because we're removing a split from there ! */ if (gncInvoiceGetInvoiceFromLot (from_lot)) { PWARN ("from_lot %p is a document lot. That is not allowed in gncOwnerOffsetLots", from_lot); return; } /* Get best matching split from from_lot to offset to_lot */ target_offset = gnc_lot_get_balance (to_lot); if (gnc_numeric_zero_p (target_offset)) return; // to_lot is already balanced, nothing more to do split = gncOwnerFindOffsettingSplit (from_lot, target_offset); if (!split) return; // No suitable offsetting split found, nothing more to do /* If the offsetting split is bigger than the amount needed to balance * to_lot, reduce the split so its reduced value closes to_lot exactly. * Note the negation in the reduction function. The split must be of * opposite sign of to_lot's balance in order to be able to close it. */ if (gnc_numeric_compare (gnc_numeric_abs (xaccSplitGetValue (split)), gnc_numeric_abs (target_offset)) > 0) gncOwnerReduceSplitTo (split, gnc_numeric_neg (target_offset)); /* Move the reduced split from from_lot to to_lot */ gnc_lot_add_split (to_lot, split); }