GnuCash 2.4.99
gnc-invoice-sql.c
Go to the documentation of this file.
00001 /********************************************************************\
00002  * gnc-invoice-sql.c - invoice sql backend                          *
00003  *                                                                  *
00004  * This program is free software; you can redistribute it and/or    *
00005  * modify it under the terms of the GNU General Public License as   *
00006  * published by the Free Software Foundation; either version 2 of   *
00007  * the License, or (at your option) any later version.              *
00008  *                                                                  *
00009  * This program is distributed in the hope that it will be useful,  *
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00012  * GNU General Public License for more details.                     *
00013  *                                                                  *
00014  * You should have received a copy of the GNU General Public License*
00015  * along with this program; if not, contact:                        *
00016  *                                                                  *
00017  * Free Software Foundation           Voice:  +1-617-542-5942       *
00018  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
00019  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
00020  *                                                                  *
00021 \********************************************************************/
00022 
00031 #include "config.h"
00032 
00033 #include <glib.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036 
00037 #include "gnc-commodity.h"
00038 
00039 #include "gnc-backend-sql.h"
00040 #include "gnc-commodity-sql.h"
00041 #include "gnc-slots-sql.h"
00042 
00043 #include "gncBillTermP.h"
00044 #include "gncInvoiceP.h"
00045 #include "gnc-invoice-sql.h"
00046 #include "gnc-owner-sql.h"
00047 #include "gnc-bill-term-sql.h"
00048 
00049 #define _GNC_MOD_NAME   GNC_ID_INVOICE
00050 
00051 static QofLogModule log_module = G_LOG_DOMAIN;
00052 
00053 #define TABLE_NAME "invoices"
00054 #define TABLE_VERSION 3
00055 
00056 #define MAX_ID_LEN 2048
00057 #define MAX_NOTES_LEN 2048
00058 #define MAX_BILLING_ID_LEN 2048
00059 
00060 static GncSqlColumnTableEntry col_table[] =
00061 {
00062     { "guid",         CT_GUID,         0,                  COL_NNUL | COL_PKEY, "guid" },
00063     { "id",           CT_STRING,       MAX_ID_LEN,         COL_NNUL,          NULL, INVOICE_ID },
00064     { "date_opened",  CT_TIMESPEC,     0,                  0,                 NULL, INVOICE_OPENED },
00065     { "date_posted",  CT_TIMESPEC,     0,                  0,                 NULL, INVOICE_POSTED },
00066     { "notes",        CT_STRING,       MAX_NOTES_LEN,      COL_NNUL,          "notes" },
00067     { "active",       CT_BOOLEAN,      0,                  COL_NNUL,          NULL, QOF_PARAM_ACTIVE },
00068     {
00069         "currency",     CT_COMMODITYREF, 0,                  COL_NNUL,          NULL, NULL,
00070         (QofAccessFunc)gncInvoiceGetCurrency, (QofSetterFunc)gncInvoiceSetCurrency
00071     },
00072     {
00073         "owner",        CT_OWNERREF,     0,                  0,                 NULL, NULL,
00074         (QofAccessFunc)gncInvoiceGetOwner, (QofSetterFunc)gncInvoiceSetOwner
00075     },
00076     { "terms",        CT_BILLTERMREF,  0,                  0,                 NULL, INVOICE_TERMS },
00077     { "billing_id",   CT_STRING,       MAX_BILLING_ID_LEN, 0,                 NULL, INVOICE_BILLINGID },
00078     { "post_txn",     CT_TXREF,        0,                  0,                 NULL, INVOICE_POST_TXN },
00079     {
00080         "post_lot",     CT_LOTREF,       0,                  0,                 NULL, NULL,
00081         (QofAccessFunc)gncInvoiceGetPostedLot, (QofSetterFunc)gncInvoiceSetPostedLot
00082     },
00083     { "post_acc",     CT_ACCOUNTREF,   0,                  0,                 NULL, INVOICE_ACC },
00084     {
00085         "billto",       CT_OWNERREF,     0,                  0,                 NULL, NULL,
00086         (QofAccessFunc)gncInvoiceGetBillTo, (QofSetterFunc)gncInvoiceSetBillTo
00087     },
00088     {
00089         "charge_amt",   CT_NUMERIC,      0,                  0,                 NULL, NULL,
00090         (QofAccessFunc)gncInvoiceGetToChargeAmount, (QofSetterFunc)gncInvoiceSetToChargeAmount
00091     },
00092     { NULL }
00093 };
00094 
00095 static GncInvoice*
00096 load_single_invoice( GncSqlBackend* be, GncSqlRow* row )
00097 {
00098     const GncGUID* guid;
00099     GncInvoice* pInvoice;
00100 
00101     g_return_val_if_fail( be != NULL, NULL );
00102     g_return_val_if_fail( row != NULL, NULL );
00103 
00104     guid = gnc_sql_load_guid( be, row );
00105     pInvoice = gncInvoiceLookup( be->book, guid );
00106     if ( pInvoice == NULL )
00107     {
00108         pInvoice = gncInvoiceCreate( be->book );
00109     }
00110     gnc_sql_load_object( be, row, GNC_ID_INVOICE, pInvoice, col_table );
00111     qof_instance_mark_clean( QOF_INSTANCE(pInvoice) );
00112 
00113     return pInvoice;
00114 }
00115 
00116 static void
00117 load_all_invoices( GncSqlBackend* be )
00118 {
00119     GncSqlStatement* stmt;
00120     GncSqlResult* result;
00121     QofBook* pBook;
00122 
00123     g_return_if_fail( be != NULL );
00124 
00125     pBook = be->book;
00126 
00127     stmt = gnc_sql_create_select_statement( be, TABLE_NAME );
00128     result = gnc_sql_execute_select_statement( be, stmt );
00129     gnc_sql_statement_dispose( stmt );
00130     if ( result != NULL )
00131     {
00132         GncSqlRow* row;
00133         GList* list = NULL;
00134 
00135         row = gnc_sql_result_get_first_row( result );
00136         while ( row != NULL )
00137         {
00138             GncInvoice* pInvoice = load_single_invoice( be, row );
00139             if ( pInvoice != NULL )
00140             {
00141                 list = g_list_append( list, pInvoice );
00142             }
00143             row = gnc_sql_result_get_next_row( result );
00144         }
00145         gnc_sql_result_dispose( result );
00146 
00147         if ( list != NULL )
00148         {
00149             gnc_sql_slots_load_for_list( be, list );
00150             g_list_free( list );
00151         }
00152     }
00153 }
00154 
00155 /* ================================================================= */
00156 static void
00157 create_invoice_tables( GncSqlBackend* be )
00158 {
00159     gint version;
00160 
00161     g_return_if_fail( be != NULL );
00162 
00163     version = gnc_sql_get_table_version( be, TABLE_NAME );
00164     if ( version == 0 )
00165     {
00166         gnc_sql_create_table( be, TABLE_NAME, TABLE_VERSION, col_table );
00167     }
00168     else if ( version < TABLE_VERSION )
00169     {
00170         /* Upgrade:
00171              1->2: 64 bit int handling
00172                  2->3: invoice open date can be NULL
00173         */
00174         gnc_sql_upgrade_table( be, TABLE_NAME, col_table );
00175         gnc_sql_set_table_version( be, TABLE_NAME, TABLE_VERSION );
00176 
00177         PINFO("Invoices table upgraded from version %d to version %d\n", version, TABLE_VERSION);
00178     }
00179 }
00180 
00181 /* ================================================================= */
00182 static gboolean
00183 save_invoice( GncSqlBackend* be, QofInstance* inst )
00184 {
00185     const GncGUID* guid;
00186     GncInvoice* invoice;
00187     gint op;
00188     gboolean is_infant;
00189     gboolean is_ok = TRUE;
00190 
00191     g_return_val_if_fail( inst != NULL, FALSE );
00192     g_return_val_if_fail( GNC_IS_INVOICE(inst), FALSE );
00193     g_return_val_if_fail( be != NULL, FALSE );
00194 
00195     invoice = GNC_INVOICE(inst);
00196 
00197     is_infant = qof_instance_get_infant( inst );
00198     if ( qof_instance_get_destroying( inst ) )
00199     {
00200         op = OP_DB_DELETE;
00201     }
00202     else if ( be->is_pristine_db || is_infant )
00203     {
00204         op = OP_DB_INSERT;
00205     }
00206     else
00207     {
00208         op = OP_DB_UPDATE;
00209     }
00210     if ( op != OP_DB_DELETE )
00211     {
00212         // Ensure the commodity is in the db
00213         is_ok = gnc_sql_save_commodity( be, gncInvoiceGetCurrency( invoice ) );
00214     }
00215 
00216     if ( is_ok )
00217     {
00218         is_ok = gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_INVOICE, inst, col_table );
00219     }
00220 
00221     if ( is_ok )
00222     {
00223         // Now, commit or delete any slots
00224         guid = qof_instance_get_guid( inst );
00225         if ( !qof_instance_get_destroying(inst) )
00226         {
00227             is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
00228         }
00229         else
00230         {
00231             is_ok = gnc_sql_slots_delete( be, guid );
00232         }
00233     }
00234 
00235     return is_ok;
00236 }
00237 
00238 /* ================================================================= */
00239 static gboolean
00240 invoice_should_be_saved( GncInvoice *invoice )
00241 {
00242     const char *id;
00243 
00244     g_return_val_if_fail( invoice != NULL, FALSE );
00245 
00246     /* make sure this is a valid invoice before we save it -- should have an ID */
00247     id = gncInvoiceGetID( invoice );
00248     if ( id == NULL || *id == '\0' )
00249     {
00250         return FALSE;
00251     }
00252 
00253     return TRUE;
00254 }
00255 
00256 static void
00257 write_single_invoice( QofInstance *term_p, gpointer data_p )
00258 {
00259     write_objects_t* s = (write_objects_t*)data_p;
00260 
00261     g_return_if_fail( term_p != NULL );
00262     g_return_if_fail( GNC_IS_INVOICE(term_p) );
00263     g_return_if_fail( data_p != NULL );
00264 
00265     if ( s->is_ok && invoice_should_be_saved( GNC_INVOICE(term_p) ) )
00266     {
00267         s->is_ok = save_invoice( s->be, term_p );
00268     }
00269 }
00270 
00271 static gboolean
00272 write_invoices( GncSqlBackend* be )
00273 {
00274     write_objects_t data;
00275 
00276     g_return_val_if_fail( be != NULL, FALSE );
00277 
00278     data.be = be;
00279     data.is_ok = TRUE;
00280     qof_object_foreach( GNC_ID_INVOICE, be->book, write_single_invoice, &data );
00281 
00282     return data.is_ok;
00283 }
00284 
00285 /* ================================================================= */
00286 static void
00287 load_invoice_guid( const GncSqlBackend* be, GncSqlRow* row,
00288                    QofSetterFunc setter, gpointer pObject,
00289                    const GncSqlColumnTableEntry* table_row )
00290 {
00291     const GValue* val;
00292     GncGUID guid;
00293     GncInvoice* invoice = NULL;
00294 
00295     g_return_if_fail( be != NULL );
00296     g_return_if_fail( row != NULL );
00297     g_return_if_fail( pObject != NULL );
00298     g_return_if_fail( table_row != NULL );
00299 
00300     val = gnc_sql_row_get_value_at_col_name( row, table_row->col_name );
00301     if ( val != NULL && G_VALUE_HOLDS_STRING( val ) && g_value_get_string( val ) != NULL )
00302     {
00303         string_to_guid( g_value_get_string( val ), &guid );
00304         invoice = gncInvoiceLookup( be->book, &guid );
00305         if ( invoice != NULL )
00306         {
00307             if ( table_row->gobj_param_name != NULL )
00308             {
00309                 g_object_set( pObject, table_row->gobj_param_name, invoice, NULL );
00310             }
00311             else
00312             {
00313                 (*setter)( pObject, (const gpointer)invoice );
00314             }
00315         }
00316         else
00317         {
00318             PWARN( "Invoice ref '%s' not found", g_value_get_string( val ) );
00319         }
00320     }
00321 }
00322 
00323 static GncSqlColumnTypeHandler invoice_guid_handler
00324 = { load_invoice_guid,
00325     gnc_sql_add_objectref_guid_col_info_to_list,
00326     gnc_sql_add_colname_to_list,
00327     gnc_sql_add_gvalue_objectref_guid_to_slist
00328   };
00329 /* ================================================================= */
00330 void
00331 gnc_invoice_sql_initialize( void )
00332 {
00333     static GncSqlObjectBackend be_data =
00334     {
00335         GNC_SQL_BACKEND_VERSION,
00336         GNC_ID_INVOICE,
00337         save_invoice,                                           /* commit */
00338         load_all_invoices,                                      /* initial_load */
00339         create_invoice_tables,                          /* create_tables */
00340         NULL, NULL, NULL,
00341         write_invoices                                          /* write */
00342     };
00343 
00344     qof_object_register_backend( GNC_ID_INVOICE, GNC_SQL_BACKEND, &be_data );
00345 
00346     gnc_sql_register_col_type_handler( CT_INVOICEREF, &invoice_guid_handler );
00347 }
00348 /* ========================== END OF FILE ===================== */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines