LCOV - code coverage report
Current view: top level - libgnucash/engine - gncVendor.c (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 75.6 % 435 329
Test Date: 2026-11-02 18:19:43 Functions: 83.6 % 55 46
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /********************************************************************\
       2              :  * gncVendor.c -- the Core Vendor Interface                         *
       3              :  *                                                                  *
       4              :  * This program is free software; you can redistribute it and/or    *
       5              :  * modify it under the terms of the GNU General Public License as   *
       6              :  * published by the Free Software Foundation; either version 2 of   *
       7              :  * the License, or (at your option) any later version.              *
       8              :  *                                                                  *
       9              :  * This program is distributed in the hope that it will be useful,  *
      10              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
      11              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
      12              :  * GNU General Public License for more details.                     *
      13              :  *                                                                  *
      14              :  * You should have received a copy of the GNU General Public License*
      15              :  * along with this program; if not, contact:                        *
      16              :  *                                                                  *
      17              :  * Free Software Foundation           Voice:  +1-617-542-5942       *
      18              :  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
      19              :  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
      20              :  *                                                                  *
      21              : \********************************************************************/
      22              : 
      23              : /*
      24              :  * Copyright (C) 2001, 2002 Derek Atkins
      25              :  * Copyright (C) 2003 <linas@linas.org>
      26              :  * Author: Derek Atkins <warlord@MIT.EDU>
      27              :  */
      28              : 
      29              : #include <config.h>
      30              : 
      31              : #include <glib.h>
      32              : #include <string.h>
      33              : #include <qofinstance-p.h>
      34              : 
      35              : #include "gnc-commodity.h"
      36              : #include "gncAddressP.h"
      37              : #include "gncBillTermP.h"
      38              : #include "gncInvoice.h"
      39              : #include "gncJobP.h"
      40              : #include "gncTaxTableP.h"
      41              : #include "gncVendor.h"
      42              : #include "gncVendorP.h"
      43              : 
      44              : static gint vend_qof_event_handler_id = 0;
      45              : static void vend_handle_qof_events (QofInstance *entity, QofEventId event_type,
      46              :                                     gpointer user_data, gpointer event_data);
      47              : static void qofVendorSetAddr (GncVendor *vendor, QofInstance *addr_ent);
      48              : static const char* qofVendorGetTaxIncluded(const GncVendor *vendor);
      49              : static void qofVendorSetTaxIncluded(GncVendor *vendor, const char* type_string);
      50              : 
      51              : struct _gncVendor
      52              : {
      53              :     QofInstance     inst;
      54              : 
      55              :     const char *    id;
      56              :     const char *    name;
      57              :     const char *    notes;
      58              :     GncBillTerm *   terms;
      59              :     GncAddress *    addr;
      60              :     gnc_commodity * currency;
      61              :     GncTaxTable*    taxtable;
      62              :     gboolean        taxtable_override;
      63              :     GncTaxIncluded  taxincluded;
      64              :     gboolean        active;
      65              :     GList *         jobs;
      66              :     gnc_numeric *   balance; /* cached vendor balance, will not be stored */
      67              : };
      68              : 
      69              : struct _gncVendorClass
      70              : {
      71              :     QofInstanceClass parent_class;
      72              : };
      73              : 
      74              : static QofLogModule log_module = GNC_MOD_BUSINESS;
      75              : 
      76              : #define _GNC_MOD_NAME        GNC_ID_VENDOR
      77              : 
      78              : /* ============================================================ */
      79              : /* Misc inline funcs */
      80              : 
      81              : static inline void mark_vendor (GncVendor *vendor);
      82           79 : void mark_vendor (GncVendor *vendor)
      83              : {
      84           79 :     qof_instance_set_dirty(&vendor->inst);
      85           79 :     qof_event_gen (&vendor->inst, QOF_EVENT_MODIFY, NULL);
      86           79 : }
      87              : 
      88              : /* ============================================================== */
      89              : 
      90              : enum
      91              : {
      92              :     PROP_0,
      93              :     PROP_NAME,                  /* Table */
      94              :     PROP_ID,                    /* Table */
      95              :     PROP_NOTES,                 /* Table */
      96              :     PROP_CURRENCY,              /* Table */
      97              :     PROP_ACTIVE,                /* Table */
      98              :     PROP_TAXTABLE_OVERRIDE,     /* Table */
      99              :     PROP_BILLTERMS,             /* Table */
     100              :     PROP_TAXTABLE,              /* Table */
     101              :     PROP_ADDRESS,               /* Table, 8 fields */
     102              :     PROP_TAX_INCLUDED,          /* Table */
     103              :     PROP_TAX_INCLUDED_STR,      /* Alternate setter for PROP_TAX_INCLUDED */
     104              :     PROP_PDF_DIRNAME,           /* KVP */
     105              :     PROP_LAST_POSTED,           /* KVP */
     106              :     PROP_PAYMENT_LAST_ACCT,     /* KVP */
     107              : };
     108              : 
     109              : /* GObject Initialization */
     110          160 : G_DEFINE_TYPE(GncVendor, gnc_vendor, QOF_TYPE_INSTANCE)
     111              : 
     112              : static void
     113           26 : gnc_vendor_init(GncVendor* vendor)
     114              : {
     115           26 : }
     116              : 
     117              : static void
     118           14 : gnc_vendor_dispose(GObject *vendorp)
     119              : {
     120           14 :     G_OBJECT_CLASS(gnc_vendor_parent_class)->dispose(vendorp);
     121           14 : }
     122              : 
     123              : static void
     124           14 : gnc_vendor_finalize(GObject* vendorp)
     125              : {
     126           14 :     G_OBJECT_CLASS(gnc_vendor_parent_class)->finalize(vendorp);
     127           14 : }
     128              : 
     129              : /* Note that g_value_set_object() refs the object, as does
     130              :  * g_object_get(). But g_object_get() only unrefs once when it disgorges
     131              :  * the object, leaving an unbalanced ref, which leaks. So instead of
     132              :  * using g_value_set_object(), use g_value_take_object() which doesn't
     133              :  * ref the object when used in get_property().
     134              :  */
     135              : static void
     136           13 : gnc_vendor_get_property (GObject         *object,
     137              :                          guint            prop_id,
     138              :                          GValue          *value,
     139              :                          GParamSpec      *pspec)
     140              : {
     141              :     GncVendor *vendor;
     142              : 
     143           13 :     g_return_if_fail(GNC_IS_VENDOR(object));
     144              : 
     145           13 :     vendor = GNC_VENDOR(object);
     146           13 :     switch (prop_id)
     147              :     {
     148            1 :     case PROP_NAME:
     149            1 :         g_value_set_string(value, vendor->name);
     150            1 :         break;
     151            1 :     case PROP_ID:
     152            1 :         g_value_set_string(value, vendor->id);
     153            1 :         break;
     154            1 :     case PROP_NOTES:
     155            1 :         g_value_set_string(value, vendor->notes);
     156            1 :         break;
     157            1 :     case PROP_CURRENCY:
     158            1 :         g_value_take_object(value, vendor->currency);
     159            1 :         break;
     160            1 :     case PROP_ACTIVE:
     161            1 :         g_value_set_boolean(value, vendor->active);
     162            1 :         break;
     163            1 :     case PROP_TAXTABLE_OVERRIDE:
     164            1 :         g_value_set_boolean(value, vendor->taxtable_override);
     165            1 :         break;
     166            1 :     case PROP_BILLTERMS:
     167            1 :         g_value_take_object(value, vendor->terms);
     168            1 :         break;
     169            1 :     case PROP_TAXTABLE:
     170            1 :         g_value_take_object(value, vendor->taxtable);
     171            1 :         break;
     172            1 :     case PROP_ADDRESS:
     173            1 :         g_value_take_object(value, vendor->addr);
     174            1 :         break;
     175            0 :     case PROP_TAX_INCLUDED:
     176            0 :         g_value_set_int(value, vendor->taxincluded);
     177            0 :         break;
     178            1 :     case PROP_TAX_INCLUDED_STR:
     179            1 :         g_value_set_string(value, qofVendorGetTaxIncluded(vendor));
     180            1 :         break;
     181            1 :     case PROP_PDF_DIRNAME:
     182            1 :         qof_instance_get_kvp (QOF_INSTANCE (vendor), value, 1, OWNER_EXPORT_PDF_DIRNAME);
     183            1 :         break;
     184            1 :     case PROP_LAST_POSTED:
     185            1 :         qof_instance_get_kvp (QOF_INSTANCE (vendor), value, 1, LAST_POSTED_TO_ACCT);
     186            1 :         break;
     187            1 :     case PROP_PAYMENT_LAST_ACCT:
     188            1 :         qof_instance_get_kvp (QOF_INSTANCE (vendor), value, 2, GNC_PAYMENT, GNC_LAST_ACCOUNT);
     189            1 :         break;
     190            0 :     default:
     191            0 :         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
     192            0 :         break;
     193              :     }
     194              : }
     195              : 
     196              : static void
     197           11 : gnc_vendor_set_property (GObject         *object,
     198              :                          guint            prop_id,
     199              :                          const GValue          *value,
     200              :                          GParamSpec      *pspec)
     201              : {
     202              :     GncVendor *vendor;
     203              : 
     204           11 :     g_return_if_fail(GNC_IS_VENDOR(object));
     205              : 
     206           11 :     vendor = GNC_VENDOR(object);
     207           11 :     g_assert (qof_instance_get_editlevel(vendor));
     208              : 
     209           11 :     switch (prop_id)
     210              :     {
     211            1 :     case PROP_NAME:
     212            1 :         gncVendorSetName(vendor, g_value_get_string(value));
     213            1 :         break;
     214            1 :     case PROP_ID:
     215            1 :         gncVendorSetID(vendor, g_value_get_string(value));
     216            1 :         break;
     217            1 :     case PROP_NOTES:
     218            1 :         gncVendorSetNotes(vendor, g_value_get_string(value));
     219            1 :         break;
     220            1 :     case PROP_CURRENCY:
     221            1 :         gncVendorSetCurrency(vendor, g_value_get_object(value));
     222            1 :         break;
     223            1 :     case PROP_ACTIVE:
     224            1 :         gncVendorSetActive(vendor, g_value_get_boolean(value));
     225            1 :         break;
     226            1 :     case PROP_TAXTABLE_OVERRIDE:
     227            1 :         gncVendorSetTaxTableOverride(vendor, g_value_get_boolean(value));
     228            1 :         break;
     229            0 :     case PROP_BILLTERMS:
     230            0 :         gncVendorSetTerms(vendor, g_value_get_object(value));
     231            0 :         break;
     232            0 :     case PROP_TAXTABLE:
     233            0 :         gncVendorSetTaxTable(vendor, g_value_get_object(value));
     234            0 :         break;
     235            1 :     case PROP_ADDRESS:
     236            1 :         qofVendorSetAddr(vendor, g_value_get_object(value));
     237            1 :         break;
     238            0 :     case PROP_TAX_INCLUDED:
     239            0 :         gncVendorSetTaxIncluded(vendor, (GncTaxIncluded)g_value_get_int(value));
     240            0 :         break;
     241            1 :     case PROP_TAX_INCLUDED_STR:
     242            1 :         qofVendorSetTaxIncluded(vendor, g_value_get_string(value));
     243            1 :         break;
     244            1 :     case PROP_PDF_DIRNAME:
     245            1 :         qof_instance_set_kvp (QOF_INSTANCE (vendor), value, 1, OWNER_EXPORT_PDF_DIRNAME);
     246            1 :         break;
     247            1 :     case PROP_LAST_POSTED:
     248            1 :         qof_instance_set_kvp (QOF_INSTANCE (vendor), value, 1, LAST_POSTED_TO_ACCT);
     249            1 :         break;
     250            1 :     case PROP_PAYMENT_LAST_ACCT:
     251            1 :         qof_instance_set_kvp (QOF_INSTANCE (vendor), value, 2, GNC_PAYMENT, GNC_LAST_ACCOUNT);
     252            1 :         break;
     253            0 :     default:
     254            0 :         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
     255            0 :         break;
     256              :     }
     257              : }
     258              : 
     259              : /** Does this object refer to a specific object */
     260              : static gboolean
     261            0 : impl_refers_to_object(const QofInstance* inst, const QofInstance* ref)
     262              : {
     263              :     GncVendor* v;
     264              : 
     265            0 :     g_return_val_if_fail(inst != NULL, FALSE);
     266            0 :     g_return_val_if_fail(GNC_IS_VENDOR(inst), FALSE);
     267              : 
     268            0 :     v = GNC_VENDOR(inst);
     269              : 
     270            0 :     if (GNC_IS_BILLTERM(ref))
     271              :     {
     272            0 :         return (v->terms == GNC_BILLTERM(ref));
     273              :     }
     274            0 :     else if (GNC_IS_TAXTABLE(ref))
     275              :     {
     276            0 :         return (v->taxtable == GNC_TAXTABLE(ref));
     277              :     }
     278              : 
     279            0 :     return FALSE;
     280              : }
     281              : 
     282              : /** Returns a list of my type of object which refers to an object.  For example, when called as
     283              :         qof_instance_get_typed_referring_object_list(taxtable, account);
     284              :     it will return the list of taxtables which refer to a specific account.  The result should be the
     285              :     same regardless of which taxtable object is used.  The list must be freed by the caller but the
     286              :     objects on the list must not.
     287              :  */
     288              : static GList*
     289            0 : impl_get_typed_referring_object_list(const QofInstance* inst, const QofInstance* ref)
     290              : {
     291            0 :     if (!GNC_IS_BILLTERM(ref) && !GNC_IS_TAXTABLE(ref))
     292              :     {
     293            0 :         return NULL;
     294              :     }
     295              : 
     296            0 :     return qof_instance_get_referring_object_list_from_collection(qof_instance_get_collection(inst), ref);
     297              : }
     298              : 
     299              : static void
     300            8 : gnc_vendor_class_init (GncVendorClass *klass)
     301              : {
     302            8 :     GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
     303            8 :     QofInstanceClass* qof_class = QOF_INSTANCE_CLASS(klass);
     304              : 
     305            8 :     gobject_class->dispose = gnc_vendor_dispose;
     306            8 :     gobject_class->finalize = gnc_vendor_finalize;
     307            8 :     gobject_class->set_property = gnc_vendor_set_property;
     308            8 :     gobject_class->get_property = gnc_vendor_get_property;
     309              : 
     310            8 :     qof_class->get_display_name = NULL;
     311            8 :     qof_class->refers_to_object = impl_refers_to_object;
     312            8 :     qof_class->get_typed_referring_object_list = impl_get_typed_referring_object_list;
     313              : 
     314            8 :     g_object_class_install_property
     315              :     (gobject_class,
     316              :      PROP_NAME,
     317              :      g_param_spec_string ("name",
     318              :                           "Vendor Name",
     319              :                           "The vendor name is an arbitrary string "
     320              :                           "assigned by the user to provide the vendor name.",
     321              :                           NULL,
     322              :                           G_PARAM_READWRITE));
     323              : 
     324            8 :     g_object_class_install_property
     325              :     (gobject_class,
     326              :      PROP_ID,
     327              :      g_param_spec_string ("id",
     328              :                           "Vendor ID",
     329              :                           "The vendor id is an arbitrary string "
     330              :                           "assigned by the user to identify the vendor.",
     331              :                           NULL,
     332              :                           G_PARAM_READWRITE));
     333              : 
     334            8 :     g_object_class_install_property
     335              :     (gobject_class,
     336              :      PROP_NOTES,
     337              :      g_param_spec_string ("notes",
     338              :                           "Vendor notes",
     339              :                           "The vendor notes is an arbitrary string "
     340              :                           "assigned by the user to add extra information about the vendor.",
     341              :                           NULL,
     342              :                           G_PARAM_READWRITE));
     343              : 
     344            8 :     g_object_class_install_property
     345              :     (gobject_class,
     346              :      PROP_CURRENCY,
     347              :      g_param_spec_object ("currency",
     348              :                           "Currency",
     349              :                           "The currency property denotes the currency used by this vendor.",
     350              :                           GNC_TYPE_COMMODITY,
     351              :                           G_PARAM_READWRITE));
     352              : 
     353            8 :     g_object_class_install_property
     354              :     (gobject_class,
     355              :      PROP_ACTIVE,
     356              :      g_param_spec_boolean ("active",
     357              :                            "Active",
     358              :                            "TRUE if the vendor is active.  FALSE if inactive.",
     359              :                            FALSE,
     360              :                            G_PARAM_READWRITE));
     361              : 
     362            8 :     g_object_class_install_property
     363              :     (gobject_class,
     364              :      PROP_TAXTABLE_OVERRIDE,
     365              :      g_param_spec_boolean ("tax-table-override",
     366              :                            "Tax table override",
     367              :                            "TRUE if the vendor has a specific tax table which overrides the default "
     368              :                            "tax table.  FALSE if the default table should be used.",
     369              :                            FALSE,
     370              :                            G_PARAM_READWRITE));
     371              : 
     372            8 :     g_object_class_install_property
     373              :     (gobject_class,
     374              :      PROP_BILLTERMS,
     375              :      g_param_spec_object ("terms",
     376              :                           "Terms",
     377              :                           "The billing terms used by this vendor.",
     378              :                           GNC_TYPE_BILLTERM,
     379              :                           G_PARAM_READWRITE));
     380              : 
     381            8 :     g_object_class_install_property
     382              :     (gobject_class,
     383              :      PROP_TAXTABLE,
     384              :      g_param_spec_object ("tax-table",
     385              :                           "Tax table",
     386              :                           "The tax table which applies to this vendor.",
     387              :                           GNC_TYPE_TAXTABLE,
     388              :                           G_PARAM_READWRITE));
     389              : 
     390            8 :     g_object_class_install_property
     391              :     (gobject_class,
     392              :      PROP_ADDRESS,
     393              :      g_param_spec_object ("address",
     394              :                           "Address",
     395              :                           "The address property contains the address information for this vendor.",
     396              :                           GNC_TYPE_ADDRESS,
     397              :                           G_PARAM_READWRITE));
     398              : 
     399            8 :     g_object_class_install_property
     400              :     (gobject_class,
     401              :      PROP_TAX_INCLUDED,
     402              :      g_param_spec_int  ("tax-included",
     403              :                         "Tax included",
     404              :                         "The tax-included property contains the information about tax calculation this vendor.",
     405              :                         GNC_TAXINCLUDED_YES,       /* min */
     406              :                         GNC_TAXINCLUDED_USEGLOBAL, /* max */
     407              :                         GNC_TAXINCLUDED_USEGLOBAL, /* default */
     408              :                         G_PARAM_READWRITE));
     409              : 
     410            8 :     g_object_class_install_property
     411              :     (gobject_class,
     412              :      PROP_TAX_INCLUDED_STR,
     413              :      g_param_spec_string("tax-included-string",
     414              :                          "Tax included string",
     415              :                          "The tax-included-string property contains a character version of tax-included.",
     416              :                          FALSE,
     417              :                          G_PARAM_READWRITE));
     418            8 :     g_object_class_install_property
     419              :     (gobject_class,
     420              :      PROP_PDF_DIRNAME,
     421              :      g_param_spec_string ("export-pdf-dir",
     422              :                           "Export PDF Directory Name",
     423              :                           "A subdirectory for exporting PDF reports which is "
     424              :                           "appended to the target directory when writing them "
     425              :                           "out. It is retrieved from preferences and stored on "
     426              :                           "each 'Owner' object which prints items after "
     427              :                           "printing.",
     428              :                           NULL,
     429              :                           G_PARAM_READWRITE));
     430              : 
     431            8 :     g_object_class_install_property(
     432              :        gobject_class,
     433              :        PROP_LAST_POSTED,
     434              :        g_param_spec_boxed("invoice-last-posted-account",
     435              :                           "Invoice Last Posted Account",
     436              :                           "The last account to which an invoice belonging to "
     437              :                           "this owner was posted.",
     438              :                           GNC_TYPE_GUID,
     439              :                           G_PARAM_READWRITE));
     440              : 
     441            8 :     g_object_class_install_property(
     442              :        gobject_class,
     443              :        PROP_PAYMENT_LAST_ACCT,
     444              :        g_param_spec_boxed("payment-last-account",
     445              :                           "Payment Last Account",
     446              :                           "The last account to which an payment belonging to "
     447              :                           "this owner was posted.",
     448              :                           GNC_TYPE_GUID,
     449              :                           G_PARAM_READWRITE));
     450            8 : }
     451              : 
     452              : /* Create/Destroy Functions */
     453           27 : GncVendor *gncVendorCreate (QofBook *book)
     454              : {
     455              :     GncVendor *vendor;
     456              : 
     457           27 :     if (!book) return NULL;
     458              : 
     459           26 :     vendor = g_object_new (GNC_TYPE_VENDOR, NULL);
     460           26 :     qof_instance_init_data (&vendor->inst, _GNC_MOD_NAME, book);
     461              : 
     462           26 :     vendor->id = CACHE_INSERT ("");
     463           26 :     vendor->name = CACHE_INSERT ("");
     464           26 :     vendor->notes = CACHE_INSERT ("");
     465           26 :     vendor->addr = gncAddressCreate (book, &vendor->inst);
     466           26 :     vendor->taxincluded = GNC_TAXINCLUDED_USEGLOBAL;
     467           26 :     vendor->active = TRUE;
     468           26 :     vendor->jobs = NULL;
     469           26 :     vendor->balance = NULL;
     470              : 
     471           26 :     if (vend_qof_event_handler_id == 0)
     472            8 :         vend_qof_event_handler_id = qof_event_register_handler (vend_handle_qof_events, NULL);
     473              : 
     474           26 :     qof_event_gen (&vendor->inst, QOF_EVENT_CREATE, NULL);
     475              : 
     476           26 :     return vendor;
     477              : }
     478              : 
     479           13 : void gncVendorDestroy (GncVendor *vendor)
     480              : {
     481           13 :     if (!vendor) return;
     482           13 :     qof_instance_set_destroying(vendor, TRUE);
     483           13 :     gncVendorCommitEdit (vendor);
     484              : }
     485              : 
     486           13 : static void gncVendorFree (GncVendor *vendor)
     487              : {
     488           13 :     if (!vendor) return;
     489              : 
     490           13 :     qof_event_gen (&vendor->inst, QOF_EVENT_DESTROY, NULL);
     491              : 
     492           13 :     CACHE_REMOVE (vendor->id);
     493           13 :     CACHE_REMOVE (vendor->name);
     494           13 :     CACHE_REMOVE (vendor->notes);
     495           13 :     gncAddressBeginEdit (vendor->addr);
     496           13 :     gncAddressDestroy (vendor->addr);
     497              : 
     498           13 :     gncJobFreeList (vendor->jobs);
     499           13 :     g_list_free (vendor->jobs);
     500           13 :     g_free (vendor->balance);
     501              : 
     502           13 :     if (!qof_book_shutting_down (qof_instance_get_book (QOF_INSTANCE(vendor))))
     503              :     {
     504            4 :         if (vendor->terms)
     505            0 :             gncBillTermDecRef (vendor->terms);
     506            4 :         if (vendor->taxtable)
     507            0 :             gncTaxTableDecRef (vendor->taxtable);
     508              :     }
     509              : 
     510              :     /* qof_instance_release (&vendor->inst); */
     511           13 :     g_object_unref (vendor);
     512              : }
     513              : 
     514              : /* ============================================================== */
     515              : /* Set Functions */
     516              : 
     517              : #define SET_STR(obj, member, str) { \
     518              :         if (!g_strcmp0 (member, str)) return; \
     519              :         gncVendorBeginEdit (obj); \
     520              :         CACHE_REPLACE (member, str); \
     521              :         }
     522              : 
     523           17 : void gncVendorSetID (GncVendor *vendor, const char *id)
     524              : {
     525           17 :     if (!vendor) return;
     526           17 :     if (!id) return;
     527           17 :     SET_STR(vendor, vendor->id, id);
     528           17 :     mark_vendor (vendor);
     529           17 :     gncVendorCommitEdit (vendor);
     530              : }
     531              : 
     532           11 : void gncVendorSetName (GncVendor *vendor, const char *name)
     533              : {
     534           11 :     if (!vendor) return;
     535           11 :     if (!name) return;
     536           11 :     SET_STR(vendor, vendor->name, name);
     537           11 :     mark_vendor (vendor);
     538           11 :     gncVendorCommitEdit (vendor);
     539              : }
     540              : 
     541            7 : void gncVendorSetNotes (GncVendor *vendor, const char *notes)
     542              : {
     543            7 :     if (!vendor) return;
     544            7 :     if (!notes) return;
     545            7 :     SET_STR(vendor, vendor->notes, notes);
     546            6 :     mark_vendor (vendor);
     547            6 :     gncVendorCommitEdit (vendor);
     548              : }
     549              : 
     550            0 : void gncVendorSetTerms (GncVendor *vendor, GncBillTerm *terms)
     551              : {
     552            0 :     if (!vendor) return;
     553            0 :     if (vendor->terms == terms) return;
     554              : 
     555            0 :     gncVendorBeginEdit (vendor);
     556            0 :     if (vendor->terms)
     557            0 :         gncBillTermDecRef (vendor->terms);
     558            0 :     vendor->terms = terms;
     559            0 :     if (vendor->terms)
     560            0 :         gncBillTermIncRef (vendor->terms);
     561            0 :     mark_vendor (vendor);
     562            0 :     gncVendorCommitEdit (vendor);
     563              : }
     564              : 
     565            8 : void gncVendorSetTaxIncluded (GncVendor *vendor, GncTaxIncluded taxincl)
     566              : {
     567            8 :     if (!vendor) return;
     568            8 :     if (taxincl == vendor->taxincluded) return;
     569            5 :     gncVendorBeginEdit (vendor);
     570            5 :     vendor->taxincluded = taxincl;
     571            5 :     mark_vendor (vendor);
     572            5 :     gncVendorCommitEdit (vendor);
     573              : }
     574              : 
     575           16 : void gncVendorSetCurrency (GncVendor *vendor, gnc_commodity *currency)
     576              : {
     577           16 :     if (!vendor || !currency) return;
     578           16 :     if (vendor->currency &&
     579            0 :             gnc_commodity_equal (vendor->currency, currency))
     580            0 :         return;
     581           16 :     gncVendorBeginEdit (vendor);
     582           16 :     vendor->currency = currency;
     583           16 :     mark_vendor (vendor);
     584           16 :     gncVendorCommitEdit (vendor);
     585              : }
     586              : 
     587           11 : void gncVendorSetActive (GncVendor *vendor, gboolean active)
     588              : {
     589           11 :     if (!vendor) return;
     590           11 :     if (active == vendor->active) return;
     591            6 :     gncVendorBeginEdit (vendor);
     592            6 :     vendor->active = active;
     593            6 :     mark_vendor (vendor);
     594            6 :     gncVendorCommitEdit (vendor);
     595              : }
     596              : 
     597            4 : void gncVendorSetTaxTableOverride (GncVendor *vendor, gboolean override)
     598              : {
     599            4 :     if (!vendor) return;
     600            4 :     if (vendor->taxtable_override == override) return;
     601            0 :     gncVendorBeginEdit (vendor);
     602            0 :     vendor->taxtable_override = override;
     603            0 :     mark_vendor (vendor);
     604            0 :     gncVendorCommitEdit (vendor);
     605              : }
     606              : 
     607            0 : void gncVendorSetTaxTable (GncVendor *vendor, GncTaxTable *table)
     608              : {
     609            0 :     if (!vendor) return;
     610            0 :     if (vendor->taxtable == table) return;
     611            0 :     gncVendorBeginEdit (vendor);
     612            0 :     if (vendor->taxtable)
     613            0 :         gncTaxTableDecRef (vendor->taxtable);
     614            0 :     if (table)
     615            0 :         gncTaxTableIncRef (table);
     616            0 :     vendor->taxtable = table;
     617            0 :     mark_vendor (vendor);
     618            0 :     gncVendorCommitEdit (vendor);
     619              : }
     620              : 
     621              : static void
     622            1 : qofVendorSetAddr (GncVendor *vendor, QofInstance *addr_ent)
     623              : {
     624              :     GncAddress *addr;
     625              : 
     626            1 :     if (!vendor || !addr_ent)
     627              :     {
     628            0 :         return;
     629              :     }
     630            1 :     addr = (GncAddress*)addr_ent;
     631            1 :     if (addr == vendor->addr)
     632              :     {
     633            0 :         return;
     634              :     }
     635            1 :     if (vendor->addr != NULL)
     636              :     {
     637            1 :         gncAddressBeginEdit(vendor->addr);
     638            1 :         gncAddressDestroy(vendor->addr);
     639              :     }
     640            1 :     gncVendorBeginEdit(vendor);
     641            1 :     vendor->addr = addr;
     642            1 :     gncVendorCommitEdit(vendor);
     643              : }
     644              : 
     645              : static void
     646            1 : qofVendorSetTaxIncluded(GncVendor *vendor, const char* type_string)
     647              : {
     648              :     GncTaxIncluded inc;
     649              : 
     650            1 :     if (!gncTaxIncludedStringToType(type_string, &inc))
     651              :     {
     652            0 :         return;
     653              :     }
     654            1 :     gncVendorBeginEdit(vendor);
     655            1 :     vendor->taxincluded = inc;
     656            1 :     gncVendorCommitEdit(vendor);
     657              : }
     658              : 
     659              : /* ============================================================== */
     660              : /* Get Functions */
     661              : 
     662            8 : const char * gncVendorGetID (const GncVendor *vendor)
     663              : {
     664            8 :     if (!vendor) return NULL;
     665            8 :     return vendor->id;
     666              : }
     667              : 
     668           33 : const char * gncVendorGetName (const GncVendor *vendor)
     669              : {
     670           33 :     if (!vendor) return NULL;
     671           33 :     return vendor->name;
     672              : }
     673              : 
     674           14 : GncAddress * gncVendorGetAddr (const GncVendor *vendor)
     675              : {
     676           14 :     if (!vendor) return NULL;
     677           14 :     return vendor->addr;
     678              : }
     679              : 
     680            3 : const char * gncVendorGetNotes (const GncVendor *vendor)
     681              : {
     682            3 :     if (!vendor) return NULL;
     683            3 :     return vendor->notes;
     684              : }
     685              : 
     686            5 : GncBillTerm * gncVendorGetTerms (const GncVendor *vendor)
     687              : {
     688            5 :     if (!vendor) return 0;
     689            5 :     return vendor->terms;
     690              : }
     691              : 
     692            2 : GncTaxIncluded gncVendorGetTaxIncluded (const GncVendor *vendor)
     693              : {
     694            2 :     if (!vendor) return GNC_TAXINCLUDED_USEGLOBAL;
     695            2 :     return vendor->taxincluded;
     696              : }
     697              : 
     698            3 : gnc_commodity * gncVendorGetCurrency (const GncVendor *vendor)
     699              : {
     700            3 :     if (!vendor) return NULL;
     701            3 :     return vendor->currency;
     702              : }
     703              : 
     704           12 : gboolean gncVendorGetActive (const GncVendor *vendor)
     705              : {
     706           12 :     if (!vendor) return FALSE;
     707           12 :     return vendor->active;
     708              : }
     709              : 
     710            2 : gboolean gncVendorGetTaxTableOverride (const GncVendor *vendor)
     711              : {
     712            2 :     if (!vendor) return FALSE;
     713            2 :     return vendor->taxtable_override;
     714              : }
     715              : 
     716            5 : GncTaxTable* gncVendorGetTaxTable (const GncVendor *vendor)
     717              : {
     718            5 :     if (!vendor) return NULL;
     719            5 :     return vendor->taxtable;
     720              : }
     721              : 
     722              : static const char*
     723            1 : qofVendorGetTaxIncluded(const GncVendor *vendor)
     724              : {
     725            1 :     return gncTaxIncludedTypeToString(vendor->taxincluded);
     726              : }
     727              : 
     728              : /* Note that JobList changes do not affect the "dirtiness" of the vendor */
     729            2 : void gncVendorAddJob (GncVendor *vendor, GncJob *job)
     730              : {
     731            2 :     if (!vendor) return;
     732            2 :     if (!job) return;
     733              : 
     734            2 :     if (g_list_index(vendor->jobs, job) == -1)
     735            2 :         vendor->jobs = g_list_insert_sorted (vendor->jobs, job,
     736              :                                              (GCompareFunc)gncJobCompare);
     737              : 
     738            2 :     qof_event_gen (&vendor->inst, QOF_EVENT_MODIFY, NULL);
     739              : }
     740              : 
     741            2 : void gncVendorRemoveJob (GncVendor *vendor, GncJob *job)
     742              : {
     743              :     GList *node;
     744              : 
     745            2 :     if (!vendor) return;
     746            2 :     if (!job) return;
     747              : 
     748            2 :     node = g_list_find (vendor->jobs, job);
     749            2 :     if (!node)
     750              :     {
     751              :         /*    PERR ("split not in account"); */
     752              :     }
     753              :     else
     754              :     {
     755            2 :         vendor->jobs = g_list_remove_link (vendor->jobs, node);
     756            2 :         g_list_free_1 (node);
     757              :     }
     758              : 
     759            2 :     qof_event_gen (&vendor->inst, QOF_EVENT_MODIFY, NULL);
     760              : }
     761              : 
     762          108 : void gncVendorBeginEdit (GncVendor *vendor)
     763              : {
     764          108 :     qof_begin_edit(&vendor->inst);
     765          108 : }
     766              : 
     767            0 : static void gncVendorOnError (QofInstance *vendor, QofBackendError errcode)
     768              : {
     769            0 :     PERR("Vendor QofBackend Failure: %d", errcode);
     770            0 :     gnc_engine_signal_commit_error( errcode );
     771            0 : }
     772              : 
     773           48 : static void gncVendorOnDone (QofInstance *inst)
     774              : {
     775           48 :     GncVendor *vendor = (GncVendor *) inst;
     776           48 :     gncAddressClearDirty (vendor->addr);
     777           48 : }
     778              : 
     779           13 : static void vendor_free (QofInstance *inst)
     780              : {
     781           13 :     GncVendor *vendor = (GncVendor *) inst;
     782           13 :     gncVendorFree (vendor);
     783           13 : }
     784              : 
     785          108 : void gncVendorCommitEdit (GncVendor *vendor)
     786              : {
     787          108 :     if (!qof_commit_edit (QOF_INSTANCE(vendor))) return;
     788           61 :     qof_commit_edit_part2 (&vendor->inst, gncVendorOnError,
     789              :                            gncVendorOnDone, vendor_free);
     790              : }
     791              : 
     792              : /* ============================================================== */
     793              : /* Other functions */
     794              : 
     795            0 : int gncVendorCompare (const GncVendor *a, const GncVendor *b)
     796              : {
     797            0 :     if (!a && !b) return 0;
     798            0 :     if (!a && b) return 1;
     799            0 :     if (a && !b) return -1;
     800              : 
     801            0 :     return(strcmp(a->name, b->name));
     802              : }
     803              : 
     804            1 : gboolean gncVendorEqual(const GncVendor *a, const GncVendor *b)
     805              : {
     806            1 :     if (a == NULL && b == NULL) return TRUE;
     807            1 :     if (a == NULL ||  b == NULL) return FALSE;
     808              : 
     809            1 :     g_return_val_if_fail(GNC_IS_VENDOR(a), FALSE);
     810            1 :     g_return_val_if_fail(GNC_IS_VENDOR(b), FALSE);
     811              : 
     812            1 :     if (g_strcmp0(a->id, b->id) != 0)
     813              :     {
     814            0 :         PWARN("IDs differ: %s vs %s", a->id, b->id);
     815            0 :         return FALSE;
     816              :     }
     817              : 
     818            1 :     if (g_strcmp0(a->name, b->name) != 0)
     819              :     {
     820            0 :         PWARN("Names differ: %s vs %s", a->name, b->name);
     821            0 :         return FALSE;
     822              :     }
     823              : 
     824            1 :     if (g_strcmp0(a->notes, b->notes) != 0)
     825              :     {
     826            0 :         PWARN("Notes differ");
     827            0 :         return FALSE;
     828              :     }
     829              : 
     830            1 :     if (!gncBillTermEqual(a->terms, b->terms))
     831              :     {
     832            0 :         PWARN("BillTerms differ");
     833            0 :         return FALSE;
     834              :     }
     835              : 
     836            1 :     if (!gncAddressEqual(a->addr, b->addr))
     837              :     {
     838            0 :         PWARN("Addresses differ");
     839            0 :         return FALSE;
     840              :     }
     841              : 
     842            1 :     if (!gnc_commodity_equal(a->currency, b->currency))
     843              :     {
     844            0 :         PWARN("Currencies differ");
     845            0 :         return FALSE;
     846              :     }
     847              : 
     848            1 :     if (!gncTaxTableEqual(a->taxtable, b->taxtable))
     849              :     {
     850            0 :         PWARN("Tax tables differ");
     851            0 :         return FALSE;
     852              :     }
     853              : 
     854            1 :     if (a->taxtable_override != b->taxtable_override)
     855              :     {
     856            0 :         PWARN("Tax table override flags differ");
     857            0 :         return FALSE;
     858              :     }
     859              : 
     860            1 :     if (a->taxincluded != b->taxincluded)
     861              :     {
     862            0 :         PWARN("Tax included flags differ");
     863            0 :         return FALSE;
     864              :     }
     865              : 
     866            1 :     if (a->active != b->active)
     867              :     {
     868            0 :         PWARN("Active flags differ");
     869            0 :         return FALSE;
     870              :     }
     871              : 
     872              : //    GList *         jobs;
     873            1 :     return TRUE;
     874              : }
     875              : 
     876              : gboolean
     877            8 : gncVendorIsDirty (const GncVendor *vendor)
     878              : {
     879            8 :     if (!vendor) return FALSE;
     880            8 :     return (qof_instance_get_dirty_flag(vendor)
     881            8 :             || gncAddressIsDirty (vendor->addr));
     882              : }
     883              : 
     884              : /**
     885              :  * Listen for qof events.
     886              :  *
     887              :  * - If the address of a vendor has changed, mark the vendor as dirty.
     888              :  * - If a lot related to a vendor has changed, clear the vendor's
     889              :  *   cached balance as it likely has become invalid.
     890              :  *
     891              :  * @param entity Entity for the event
     892              :  * @param event_type Event type
     893              :  * @param user_data User data registered with the handler
     894              :  * @param event_data Event data passed with the event.
     895              :  */
     896              : static void
     897       191857 : vend_handle_qof_events (QofInstance *entity, QofEventId event_type,
     898              :                         gpointer user_data, gpointer event_data)
     899              : {
     900              :     /* Handle address change events */
     901       191857 :     if ((GNC_IS_ADDRESS (entity) &&
     902           54 :         (event_type & QOF_EVENT_MODIFY) != 0))
     903              :     {
     904           31 :         if (GNC_IS_VENDOR (event_data))
     905              :         {
     906           18 :             GncVendor* vend = GNC_VENDOR (event_data);
     907           18 :             gncVendorBeginEdit (vend);
     908           18 :             mark_vendor (vend);
     909           18 :             gncVendorCommitEdit (vend);
     910              :         }
     911           31 :         return;
     912              :     }
     913              : 
     914              :     /* Handle lot change events */
     915       191826 :     if (GNC_IS_LOT (entity))
     916              :     {
     917          343 :         GNCLot *lot = GNC_LOT (entity);
     918              :         GncOwner lot_owner;
     919          343 :         const GncOwner *end_owner = NULL;
     920          343 :         GncInvoice *invoice = gncInvoiceGetInvoiceFromLot (lot);
     921              : 
     922              :         /* Determine the owner associated with the lot */
     923          343 :         if (invoice)
     924              :             /* Invoice lots */
     925          210 :             end_owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice));
     926          133 :         else if (gncOwnerGetOwnerFromLot (lot, &lot_owner))
     927              :             /* Pre-payment lots */
     928           36 :             end_owner = gncOwnerGetEndOwner (&lot_owner);
     929              : 
     930          343 :         if (gncOwnerGetType (end_owner) == GNC_OWNER_VENDOR)
     931              :         {
     932              :             /* Clear the cached balance */
     933           44 :             GncVendor* vend = gncOwnerGetVendor (end_owner);
     934           44 :             g_free (vend->balance);
     935           44 :             vend->balance = NULL;
     936              :         }
     937          343 :         return;
     938              :     }
     939              : }
     940              : 
     941              : /* ============================================================== */
     942              : /* Package-Private functions */
     943              : 
     944            1 : static const char * _gncVendorPrintable (gpointer item)
     945              : {
     946            1 :     GncVendor *v = item;
     947            1 :     if (!item) return NULL;
     948            1 :     return v->name;
     949              : }
     950              : 
     951              : static void
     952            9 : destroy_vendor_on_book_close(QofInstance *ent, gpointer data)
     953              : {
     954            9 :     GncVendor* v = GNC_VENDOR(ent);
     955              : 
     956            9 :     gncVendorBeginEdit(v);
     957            9 :     gncVendorDestroy(v);
     958            9 : }
     959              : 
     960              : /** Handles book end - frees all vendors from the book
     961              :  *
     962              :  * @param book Book being closed
     963              :  */
     964              : static void
     965          180 : gnc_vendor_book_end(QofBook* book)
     966              : {
     967              :     QofCollection *col;
     968              : 
     969          180 :     col = qof_book_get_collection(book, GNC_ID_VENDOR);
     970          180 :     qof_collection_foreach(col, destroy_vendor_on_book_close, NULL);
     971          180 : }
     972              : 
     973              : static QofObject gncVendorDesc =
     974              : {
     975              :     DI(.interface_version = ) QOF_OBJECT_VERSION,
     976              :     DI(.e_type            = ) _GNC_MOD_NAME,
     977              :     DI(.type_label        = ) "Vendor",
     978              :     DI(.create            = ) (gpointer)gncVendorCreate,
     979              :     DI(.book_begin        = ) NULL,
     980              :     DI(.book_end          = ) gnc_vendor_book_end,
     981              :     DI(.is_dirty          = ) qof_collection_is_dirty,
     982              :     DI(.mark_clean        = ) qof_collection_mark_clean,
     983              :     DI(.foreach           = ) qof_collection_foreach,
     984              :     DI(.printable         = ) _gncVendorPrintable,
     985              :     DI(.version_cmp       = ) (int (*)(gpointer, gpointer)) qof_instance_version_cmp,
     986              : };
     987              : 
     988           84 : gboolean gncVendorRegister (void)
     989              : {
     990              :     static QofParam params[] =
     991              :     {
     992              :         { VENDOR_ID, QOF_TYPE_NATURAL, (QofAccessFunc)gncVendorGetID, (QofSetterFunc)gncVendorSetID },
     993              :         { VENDOR_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncVendorGetName, (QofSetterFunc)gncVendorSetName },
     994              :         { VENDOR_ADDR,    GNC_ID_ADDRESS, (QofAccessFunc)gncVendorGetAddr, (QofSetterFunc)qofVendorSetAddr },
     995              :         { VENDOR_NOTES,   QOF_TYPE_STRING, (QofAccessFunc)gncVendorGetNotes, (QofSetterFunc)gncVendorSetNotes },
     996              :         { VENDOR_TERMS,   GNC_ID_BILLTERM, (QofAccessFunc)gncVendorGetTerms, (QofSetterFunc)gncVendorSetTerms },
     997              :         {
     998              :             VENDOR_TAX_OVERRIDE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncVendorGetTaxTableOverride,
     999              :             (QofSetterFunc)gncVendorSetTaxTableOverride
    1000              :         },
    1001              :         {
    1002              :             VENDOR_TAX_TABLE, GNC_ID_TAXTABLE, (QofAccessFunc)gncVendorGetTaxTable,
    1003              :             (QofSetterFunc)gncVendorSetTaxTable
    1004              :         },
    1005              :         {
    1006              :             VENDOR_TAX_INC, QOF_TYPE_STRING, (QofAccessFunc)qofVendorGetTaxIncluded,
    1007              :             (QofSetterFunc)qofVendorSetTaxIncluded
    1008              :         },
    1009              :         { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
    1010              :         { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
    1011              :         { QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncVendorGetActive, NULL },
    1012              :         { NULL },
    1013              :     };
    1014              : 
    1015           84 :     qof_class_register (_GNC_MOD_NAME, (QofSortFunc)gncVendorCompare, params);
    1016              : 
    1017           84 :     return qof_object_register (&gncVendorDesc);
    1018              : }
    1019              : 
    1020            0 : gchar *gncVendorNextID (QofBook *book)
    1021              : {
    1022            0 :     return qof_book_increment_and_format_counter (book, _GNC_MOD_NAME);
    1023              : }
    1024              : 
    1025              : const gnc_numeric*
    1026            0 : gncVendorGetCachedBalance (GncVendor *vend)
    1027              : {
    1028            0 :     return vend->balance;
    1029              : }
    1030              : 
    1031            0 : void gncVendorSetCachedBalance (GncVendor *vend, const gnc_numeric *new_bal)
    1032              : {
    1033            0 :     if (!new_bal)
    1034              :     {
    1035            0 :         if (vend->balance)
    1036              :         {
    1037            0 :             g_free (vend->balance);
    1038            0 :             vend->balance = NULL;
    1039              :         }
    1040            0 :         return;
    1041              :     }
    1042              : 
    1043            0 :     if (!vend->balance)
    1044            0 :         vend->balance = g_new0 (gnc_numeric, 1);
    1045              : 
    1046            0 :     *vend->balance = *new_bal;
    1047              : }
        

Generated by: LCOV version 2.0-1