diff --git a/src/engine/ScrubBusiness.c b/src/engine/ScrubBusiness.c index 8ce5667ddc..5212b5bc60 100644 --- a/src/engine/ScrubBusiness.c +++ b/src/engine/ScrubBusiness.c @@ -37,6 +37,7 @@ #include "policy-p.h" #include "Account.h" #include "gncInvoice.h" +#include "gncInvoiceP.h" #include "Scrub2.h" #include "ScrubBusiness.h" #include "Transaction.h" @@ -46,6 +47,41 @@ static QofLogModule log_module = G_LOG_DOMAIN; +static void +gncScrubInvoiceState (GNCLot *lot) +{ + SplitList *ls_iter = NULL; + Transaction *txn = NULL; // ll_txn = "Lot Link Transaction" + GncInvoice *invoice = NULL; + GncInvoice *lot_invoice = gncInvoiceGetInvoiceFromLot (lot); + + for (ls_iter = gnc_lot_get_split_list (lot); ls_iter; ls_iter = ls_iter->next) + { + Split *split = ls_iter->data; + Transaction *txn = NULL; // ll_txn = "Lot Link Transaction" + + if (!split) + continue; // next scrub lot split + + txn = xaccSplitGetParent (split); + invoice = gncInvoiceGetInvoiceFromTxn (txn); + if (invoice) + break; + + } + + if (invoice != lot_invoice) + { + PINFO("Correcting lot invoice associaton. Old invoice: %p, new invoice %p", lot_invoice, invoice); + gncInvoiceDetachFromLot(lot); + + if (invoice) + gncInvoiceAttachToLot (invoice, lot); + else + gncOwnerAttachToLot (gncInvoiceGetOwner(lot_invoice), lot); + } +} + // 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. @@ -214,7 +250,7 @@ scrub_start: // Depending on the type of lots we're comparing, we need different actions // - Two document lots (an invoice and a credit note): // Special treatment - look for all document lots linked via ll_txn - // and update the memo to be of more use to the uses. + // and update the memo to be of more use to the users. // - Two payment lots: // (Part of) the link will be eliminated and instead (part of) // one payment will be added to the other lot to keep the balance. @@ -424,6 +460,13 @@ gncScrubBusinessLot (GNCLot *lot) if (acc) xaccAccountBeginEdit(acc); + /* Check invoice link consistency + * A lot should have both or neither of: + * - one split from an invoice transaction + * - an invoice-guid set + */ + gncScrubInvoiceState (lot); + // Scrub lot links. // They should only remain when two document lots are linked together xaccScrubMergeLotSubSplits (lot, FALSE); diff --git a/src/engine/gncInvoice.c b/src/engine/gncInvoice.c index 9b6c33f629..222553f435 100644 --- a/src/engine/gncInvoice.c +++ b/src/engine/gncInvoice.c @@ -1130,7 +1130,7 @@ qofInvoiceSetJob (GncInvoice *invoice, GncJob *job) invoice->job = job; } -static void +void gncInvoiceDetachFromLot (GNCLot *lot) { KvpFrame *kvp; @@ -1143,7 +1143,7 @@ gncInvoiceDetachFromLot (GNCLot *lot) gnc_lot_commit_edit (lot); } -static void +void gncInvoiceAttachToLot (GncInvoice *invoice, GNCLot *lot) { KvpFrame *kvp; @@ -1182,7 +1182,7 @@ GncInvoice * gncInvoiceGetInvoiceFromLot (GNCLot *lot) return gncInvoiceLookup(book, guid); } -static void +void gncInvoiceAttachToTxn (GncInvoice *invoice, Transaction *txn) { KvpFrame *kvp; diff --git a/src/engine/gncInvoiceP.h b/src/engine/gncInvoiceP.h index 537dc2e453..5b4942a864 100644 --- a/src/engine/gncInvoiceP.h +++ b/src/engine/gncInvoiceP.h @@ -41,5 +41,9 @@ void gncInvoiceSetPostedTxn (GncInvoice *invoice, Transaction *txn); void gncInvoiceSetPostedLot (GncInvoice *invoice, GNCLot *lot); //void gncInvoiceSetPaidTxn (GncInvoice *invoice, Transaction *txn); +void gncInvoiceAttachToLot (GncInvoice *invoice, GNCLot *lot); +void gncInvoiceDetachFromLot (GNCLot *lot); +void gncInvoiceAttachToTxn (GncInvoice *invoice, Transaction *txn); + #define gncInvoiceSetGUID(I,G) qof_instance_set_guid(QOF_INSTANCE(I),(G)) #endif /* GNC_INVOICEP_H_ */