static GncBillTerm * billterm_find_senior (GncBillTerm *term) { GncBillTerm *temp, *parent, *gp = NULL; temp = term; do { /* See if "temp" is a grandchild */ parent = gncBillTermGetParent(temp); if (!parent) break; gp = gncBillTermGetParent(parent); if (!gp) break; /* Yep, this is a grandchild. Move up one generation and try again */ temp = parent; } while (TRUE); /* Ok, at this point temp points to the most senior child and parent * should point to the top billterm (and gp should be NULL). If * parent is NULL then we are the most senior child (and have no * children), so do nothing. If temp == term then there is no * grandparent, so do nothing. * * Do something if parent != NULL && temp != term */ g_assert (gp == NULL); /* return the most senior term */ return temp; }
static GncBillTerm* load_single_billterm (GncSqlBackend* sql_be, GncSqlRow& row, BillTermParentGuidVec& l_billterms_needing_parents) { g_return_val_if_fail (sql_be != NULL, NULL); auto guid = gnc_sql_load_guid (sql_be, row); auto pBillTerm = gncBillTermLookup (sql_be->book(), guid); if (pBillTerm == nullptr) { pBillTerm = gncBillTermCreate (sql_be->book()); } gnc_sql_load_object (sql_be, row, GNC_ID_BILLTERM, pBillTerm, col_table); /* If the billterm doesn't have a parent, it might be because it hasn't been loaded yet. If so, add this billterm to the list of billterms with no parent, along with the parent GncGUID so that after they are all loaded, the parents can be fixed up. */ if (gncBillTermGetParent (pBillTerm) == NULL) { BillTermParentGuid s; s.billterm = pBillTerm; s.have_guid = false; gnc_sql_load_object (sql_be, row, GNC_ID_TAXTABLE, &s, billterm_parent_col_table); if (s.have_guid) l_billterms_needing_parents.push_back(new BillTermParentGuid(s)); } qof_instance_mark_clean (QOF_INSTANCE (pBillTerm)); return pBillTerm; }
static xmlNodePtr billterm_dom_tree_create (GncBillTerm *term) { xmlNodePtr ret, data, kvpnode; ret = xmlNewNode(NULL, BAD_CAST gnc_billterm_string); xmlSetProp(ret, BAD_CAST "version", BAD_CAST billterm_version_string); maybe_add_guid(ret, billterm_guid_string, QOF_INSTANCE(term)); xmlAddChild(ret, text_to_dom_tree (billterm_name_string, gncBillTermGetName (term))); xmlAddChild(ret, text_to_dom_tree (billterm_desc_string, gncBillTermGetDescription (term))); xmlAddChild(ret, int_to_dom_tree (billterm_refcount_string, gncBillTermGetRefcount (term))); xmlAddChild(ret, int_to_dom_tree (billterm_invisible_string, gncBillTermGetInvisible (term))); kvpnode = kvp_frame_to_dom_tree (billterm_slots_string, qof_instance_get_slots (QOF_INSTANCE(term))); if (kvpnode) xmlAddChild (ret, kvpnode); /* We should not be our own child */ if (gncBillTermGetChild(term) != term) maybe_add_guid(ret, billterm_child_string, QOF_INSTANCE(gncBillTermGetChild (term))); maybe_add_guid(ret, billterm_parent_string, QOF_INSTANCE(gncBillTermGetParent (term))); switch (gncBillTermGetType (term)) { case GNC_TERM_TYPE_DAYS: data = xmlNewChild (ret, NULL, BAD_CAST gnc_daystype_string, NULL); maybe_add_int (data, days_duedays_string, gncBillTermGetDueDays (term)); maybe_add_int (data, days_discdays_string, gncBillTermGetDiscountDays (term)); maybe_add_numeric (data, days_discount_string, gncBillTermGetDiscount (term)); break; case GNC_TERM_TYPE_PROXIMO: data = xmlNewChild (ret, NULL, BAD_CAST gnc_proximotype_string, NULL); maybe_add_int (data, prox_dueday_string, gncBillTermGetDueDays (term)); maybe_add_int (data, prox_discday_string, gncBillTermGetDiscountDays (term)); maybe_add_numeric (data, prox_discount_string, gncBillTermGetDiscount (term)); maybe_add_int (data, prox_cutoff_string, gncBillTermGetCutoff (term)); break; } return ret; }
static GncBillTerm* load_single_billterm (GncSqlBackend* be, GncSqlRow* row, GList** l_billterms_needing_parents) { const GncGUID* guid; GncBillTerm* pBillTerm; g_return_val_if_fail (be != NULL, NULL); g_return_val_if_fail (row != NULL, NULL); guid = gnc_sql_load_guid (be, row); pBillTerm = gncBillTermLookup (be->book, guid); if (pBillTerm == NULL) { pBillTerm = gncBillTermCreate (be->book); } gnc_sql_load_object (be, row, GNC_ID_BILLTERM, pBillTerm, col_table); /* If the billterm doesn't have a parent, it might be because it hasn't been loaded yet. If so, add this billterm to the list of billterms with no parent, along with the parent GncGUID so that after they are all loaded, the parents can be fixed up. */ if (gncBillTermGetParent (pBillTerm) == NULL) { billterm_parent_guid_struct* s = static_cast<decltype (s)> ( g_malloc (sizeof (billterm_parent_guid_struct))); g_assert (s != NULL); s->billterm = pBillTerm; s->have_guid = FALSE; gnc_sql_load_object (be, row, GNC_ID_TAXTABLE, s, billterm_parent_col_table); if (s->have_guid) { *l_billterms_needing_parents = g_list_prepend (*l_billterms_needing_parents, s); } else { g_free (s); } } qof_instance_mark_clean (QOF_INSTANCE (pBillTerm)); return pBillTerm; }
static void billterm_scrub (QofBook *book) { GList *list = NULL; GList *node; GncBillTerm *parent, *term; GHashTable *ht = g_hash_table_new(g_direct_hash, g_direct_equal); DEBUG("scrubbing billterms..."); qof_object_foreach (GNC_ID_INVOICE, book, billterm_scrub_invoices, ht); qof_object_foreach (GNC_ID_CUSTOMER, book, billterm_scrub_cust, ht); qof_object_foreach (GNC_ID_VENDOR, book, billterm_scrub_vendor, ht); qof_object_foreach (GNC_ID_BILLTERM, book, billterm_scrub_cb, &list); /* destroy the list of "grandchildren" bill terms */ for (node = list; node; node = node->next) { gchar termstr[GUID_ENCODING_LENGTH+1]; term = node->data; guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(term)), termstr); PWARN ("deleting grandchild billterm: %s\n", termstr); /* Make sure the parent has no children */ parent = gncBillTermGetParent(term); gncBillTermSetChild(parent, NULL); /* Destroy this bill term */ gncBillTermBeginEdit(term); gncBillTermDestroy(term); } /* reset the refcounts as necessary */ g_hash_table_foreach(ht, billterm_reset_refcount, NULL); g_list_free(list); g_hash_table_destroy(ht); }
static gpointer bt_get_parent (gpointer pObject) { const GncBillTerm* billterm; const GncBillTerm* pParent; const GncGUID* parent_guid; g_return_val_if_fail (pObject != NULL, NULL); g_return_val_if_fail (GNC_IS_BILLTERM (pObject), NULL); billterm = GNC_BILLTERM (pObject); pParent = gncBillTermGetParent (billterm); if (pParent == NULL) { parent_guid = NULL; } else { parent_guid = qof_instance_get_guid (QOF_INSTANCE (pParent)); } return (gpointer)parent_guid; }
/* build a list of bill terms that are grandchildren or bogus (empty entry list). */ static void billterm_scrub_cb (QofInstance *term_p, gpointer list_p) { GncBillTerm *term = GNC_BILLTERM(term_p); GList **list = list_p; if (billterm_is_grandchild(term)) { *list = g_list_prepend(*list, term); } else if (!gncBillTermGetType(term)) { GncBillTerm *t = gncBillTermGetParent(term); if (t) { /* Fix up the broken "copy" function */ gchar guidstr[GUID_ENCODING_LENGTH+1]; guid_to_string_buff(qof_instance_get_guid(QOF_INSTANCE(term)),guidstr); PWARN("Fixing broken child billterm: %s", guidstr); gncBillTermBeginEdit(term); gncBillTermSetType(term, gncBillTermGetType(t)); gncBillTermSetDueDays (term, gncBillTermGetDueDays(t)); gncBillTermSetDiscountDays (term, gncBillTermGetDiscountDays(t)); gncBillTermSetDiscount (term, gncBillTermGetDiscount(t)); gncBillTermSetCutoff (term, gncBillTermGetCutoff(t)); gncBillTermCommitEdit(term); } else { /* No parent? Must be a standalone */ *list = g_list_prepend(*list, term); } } }
static gboolean billterm_is_grandchild (GncBillTerm *term) { return (gncBillTermGetParent(gncBillTermGetParent(term)) != NULL); }