|
GnuCash 2.4.99
|
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 ===================== */
1.7.4