From 5789d865f8335218f8d482965c3e0a5e8a270b1b Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Sun, 12 Oct 2003 19:08:47 +0000 Subject: [PATCH] changes to copy tax term, bill table children correctly git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@9489 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/business/business-core/gncBillTerm.c | 93 ++++++++++++++++------- src/business/business-core/gncBillTermP.h | 21 ++++- src/business/business-core/gncBusPeriod.c | 4 +- src/business/business-core/gncCustomer.c | 8 +- src/business/business-core/gncTaxTable.c | 37 ++++++++- src/business/business-core/gncTaxTableP.h | 14 ++++ 6 files changed, 134 insertions(+), 43 deletions(-) diff --git a/src/business/business-core/gncBillTerm.c b/src/business/business-core/gncBillTerm.c index 0055cc6f4d..950f782f89 100644 --- a/src/business/business-core/gncBillTerm.c +++ b/src/business/business-core/gncBillTerm.c @@ -38,6 +38,7 @@ #include "gnc-event-p.h" #include "gnc-be-utils.h" #include "kvp_frame.h" + #include "qofbook.h" #include "qofclass.h" #include "qofid.h" @@ -60,6 +61,7 @@ struct _gncBillTerm gnc_numeric discount; gint cutoff; + /* See src/doc/business.txt for an explanation of the following */ gint64 refcount; GncBillTerm * parent; /* if non-null, we are an immutable child */ GncBillTerm * child; /* if non-null, we have not changed */ @@ -97,8 +99,7 @@ static void maybe_resort_list (GncBillTerm *term); /* ============================================================== */ /* Misc inl;ine utilities */ -G_INLINE_FUNC void mark_term (GncBillTerm *term); -G_INLINE_FUNC void +static inline void mark_term (GncBillTerm *term) { term->inst.dirty = TRUE; @@ -107,6 +108,29 @@ mark_term (GncBillTerm *term) gnc_engine_generate_event (&term->inst.guid, _GNC_MOD_NAME, GNC_EVENT_MODIFY); } +static inline void maybe_resort_list (GncBillTerm *term) +{ + struct _book_info *bi; + + if (term->parent || term->invisible) return; + bi = gnc_book_get_data (term->inst.book, _GNC_MOD_NAME); + bi->terms = g_list_sort (bi->terms, (GCompareFunc)gncBillTermCompare); +} + +static inline void add_or_rem_object (GncBillTerm *term, gboolean add) +{ + struct _book_info *bi; + + if (!term) return; + bi = gnc_book_get_data (term->inst.book, _GNC_MOD_NAME); + + if (add) + bi->terms = g_list_insert_sorted (bi->terms, term, + (GCompareFunc)gncBillTermCompare); + else + bi->terms = g_list_remove (bi->terms, term); +} + static inline void addObj (GncBillTerm *term) { gncBusinessAddObject (term->inst.book, _GNC_MOD_NAME, term, &term->inst.guid); @@ -197,7 +221,6 @@ static void gncBillTermFree (GncBillTerm *term) g_free (term); } - GncBillTerm * gncCloneBillTerm (GncBillTerm *from, QofBook *book) { @@ -216,15 +239,47 @@ gncCloneBillTerm (GncBillTerm *from, QofBook *book) term->disc_days = from->disc_days; term->discount = from->discount; term->cutoff = from->cutoff; + term->invisible = from->invisible; - /** xxx I don't know what to do about parent, children, disconnect ... - * FIXME XXX */ + /** xxx I don't know what to do about refcount ... FIXME XXX */ + + /* XXX this treats parent-child as double-linked list, not sure + * if that's true .. */ + /* Make copies of parents and children. Note that this can be + * a recursive copy ... */ + if (from->child) + { + term->child = gncBillTermObtainTwin (from->child, book); + term->child->parent = term; + term->child->refcount = 0; /* XXX is this right ?? */ + term->children = g_list_prepend(term->children, term->child); + } + + if (from->parent) + { + term->parent = gncBillTermObtainTwin (from->parent, book); + term->parent->child = term; + } addObj (term); gnc_engine_generate_event (&term->inst.guid, _GNC_MOD_NAME, GNC_EVENT_CREATE); return term; } +GncBillTerm * +gncBillTermObtainTwin (GncBillTerm *from, QofBook *book) +{ + GncBillTerm *term; + if (!from) return NULL; + + term = (GncBillTerm *) qof_instance_lookup_twin (QOF_INSTANCE(from), book); + if (!term) + { + term = gncCloneBillTerm (from, book); + } + return term; +} + /* ============================================================== */ /* Set Functions */ @@ -309,6 +364,11 @@ void gncBillTermSetCutoff (GncBillTerm *term, gint cutoff) gncBillTermCommitEdit (term); } +/* XXX this doesn't seem right. If the parent/child relationship + * is a doubly-linked list, then there shouldn't be separate set-parent, + * set-child routines, else misuse of the routines will goof up + * relationships. These ops should be atomic, I think. + */ void gncBillTermSetParent (GncBillTerm *term, GncBillTerm *parent) { if (!term) return; @@ -623,29 +683,6 @@ gncBillTermComputeDiscountDate (GncBillTerm *term, Timespec post_date) /* Package-Private functions */ -static void maybe_resort_list (GncBillTerm *term) -{ - struct _book_info *bi; - - if (term->parent || term->invisible) return; - bi = gnc_book_get_data (term->inst.book, _GNC_MOD_NAME); - bi->terms = g_list_sort (bi->terms, (GCompareFunc)gncBillTermCompare); -} - -static void add_or_rem_object (GncBillTerm *term, gboolean add) -{ - struct _book_info *bi; - - if (!term) return; - bi = gnc_book_get_data (term->inst.book, _GNC_MOD_NAME); - - if (add) - bi->terms = g_list_insert_sorted (bi->terms, term, - (GCompareFunc)gncBillTermCompare); - else - bi->terms = g_list_remove (bi->terms, term); -} - static void _gncBillTermCreate (QofBook *book) { struct _book_info *bi; diff --git a/src/business/business-core/gncBillTermP.h b/src/business/business-core/gncBillTermP.h index 73de2712a0..6c5d2969a9 100644 --- a/src/business/business-core/gncBillTermP.h +++ b/src/business/business-core/gncBillTermP.h @@ -43,12 +43,27 @@ gboolean gncBillTermGetInvisible (GncBillTerm *term); /** The gncCloneBillTerm() routine makes a copy of the indicated * bill term, placing it in the indicated book. It copies - * the etc. - * It does not copy parent/child relationships ??? - * XXX the above need fixin.... + * the name, description, type, due-days, discount, etc. + * It also copies (as needed) both parents and children, so that + * the parent-child relationship is correctly mirrored in the + * clone. + * XXX the refcount is mis-handled. This needs fixin.... * It then adds a pair of 'gemini' kvp pointers so that each copy * can be found from the other. */ GncBillTerm * gncCloneBillTerm (GncBillTerm *from, QofBook *); + +/** The gncBillTermObtainTwin() will find the 'twin' of the + * indicated bill term in the indicated book. If the twin doesn't + * yet exist in the book, it will be created (by calling + * gncCloneBillTerm()) and placed into the book. + * + * We called this routine 'Obtain' instead of "Get" to distinguish + * it from the other Get routines, which work in fundamentally + * different ways. + */ +GncBillTerm * gncBillTermObtainTwin (GncBillTerm *from, QofBook *book); + + #endif /* GNC_BILLTERMP_H_ */ diff --git a/src/business/business-core/gncBusPeriod.c b/src/business/business-core/gncBusPeriod.c index eb98ef45f9..1434b11e7f 100644 --- a/src/business/business-core/gncBusPeriod.c +++ b/src/business/business-core/gncBusPeriod.c @@ -1,14 +1,14 @@ XXX TODO: -- billterms is incompletely cloned, not sure what to do - with certain fields, ask warlord + with refcount, ask warlord, need to explore. -- taxtable is incompletely cloned, not sure what to do with certain fields, ask warlord -- customer incomplete cloned, neeed to handle jobs --- Ask warlord is *all bill terms should eb copied, or just +-- Ask warlord if all bill terms should be copied, or just thiose on customers ... diff --git a/src/business/business-core/gncCustomer.c b/src/business/business-core/gncCustomer.c index fb54366934..2ec0ebc2b4 100644 --- a/src/business/business-core/gncCustomer.c +++ b/src/business/business-core/gncCustomer.c @@ -173,13 +173,7 @@ gncCloneCustomer (GncCustomer *from, QofBook *book) * else clone that too. */ if (from->terms) { - GncBillTerm *bitty; - bitty = (GncBillTerm *) qof_instance_lookup_twin (QOF_INSTANCE(from->terms), book); - if (!bitty) - { - bitty = gncCloneBillTerm (from->terms, book); - } - cust->terms = bitty; + cust->terms = gncBillTermObtainTwin(from->terms, book); } /* Find the matching taxtable in the new book, diff --git a/src/business/business-core/gncTaxTable.c b/src/business/business-core/gncTaxTable.c index a0641f284d..b801ea73c7 100644 --- a/src/business/business-core/gncTaxTable.c +++ b/src/business/business-core/gncTaxTable.c @@ -54,6 +54,7 @@ struct _gncTaxTable char * name; GList * entries; + /* See src/doc/business.txt for an explanation of the following */ Timespec modtime; /* internal date of last modtime */ gint64 refcount; GncTaxTable * parent; /* if non-null, we are an immutable child */ @@ -255,16 +256,46 @@ gncCloneTaxTable (GncTaxTable *from, QofBook *book) #if LATER_FIXME GList * entries; gint64 refcount; - GncTaxTable * parent; - GncTaxTable * child; - GList * children; #endif + /* XXX this treats parent-child as double-linked list, not sure + * if that's true .. */ + /* Make copies of parents and children. Note that this can be + * a recursive copy ... */ + if (from->child) + { + table->child = gncTaxTableObtainTwin (from->child, book); + table->child->parent = table; + table->child->refcount = 0; /* XXX is this right ?? */ + table->children = g_list_prepend(table->children, table->child); + } + + if (from->parent) + { + table->parent = gncTaxTableObtainTwin (from->parent, book); + table->parent->child = table; + } + addObj (table); gnc_engine_generate_event (&table->inst.guid, _GNC_MOD_NAME, GNC_EVENT_CREATE); return table; } +GncTaxTable * +gncTaxTableObtainTwin (GncTaxTable *from, QofBook *book) +{ + GncTaxTable *table; + if (!from) return NULL; + + table = (GncTaxTable *) qof_instance_lookup_twin (QOF_INSTANCE(from), book); + if (!table) + { + table = gncCloneTaxTable (table, book); + } + return table; +} + + void gncTaxTableDestroy (GncTaxTable *table) { diff --git a/src/business/business-core/gncTaxTableP.h b/src/business/business-core/gncTaxTableP.h index 55a0c55ab1..2fc3ca91ab 100644 --- a/src/business/business-core/gncTaxTableP.h +++ b/src/business/business-core/gncTaxTableP.h @@ -52,4 +52,18 @@ gboolean gncTaxTableGetInvisible (GncTaxTable *table); GncTaxTable * gncCloneTaxTable (GncTaxTable *from, QofBook *book); +/** The gncTaxTableObtainTwin() will find the 'twin' of the + * indicated tax table in the indicated book. If the twin doesn't + * yet exist in the book, it will be created (by calling + * gncCloneTaxTable()) and placed into the book. + * + * We called this routine 'Obtain' instead of "Get" to distinguish + * it from the other Get routines, which work in fundamentally + * different ways. + */ +GncTaxTable * gncTaxTableObtainTwin (GncTaxTable *from, QofBook *book); + + + + #endif /* GNC_TAXTABLEP_H_ */