GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-invoice-sql.c
Go to the documentation of this file.
1 /********************************************************************\
2  * gnc-invoice-sql.c - invoice sql backend *
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 [email protected] *
20  * *
21 \********************************************************************/
22 
31 #include "config.h"
32 
33 #include <glib.h>
34 #include <stdlib.h>
35 #include <string.h>
36 
37 #include "gnc-commodity.h"
38 
39 #include "gnc-backend-sql.h"
40 #include "gnc-commodity-sql.h"
41 #include "gnc-slots-sql.h"
42 
43 #include "gncBillTermP.h"
44 #include "gncInvoiceP.h"
45 #include "gnc-invoice-sql.h"
46 #include "gnc-owner-sql.h"
47 #include "gnc-bill-term-sql.h"
48 
49 #define _GNC_MOD_NAME GNC_ID_INVOICE
50 
51 static QofLogModule log_module = G_LOG_DOMAIN;
52 
53 #define TABLE_NAME "invoices"
54 #define TABLE_VERSION 3
55 
56 #define MAX_ID_LEN 2048
57 #define MAX_NOTES_LEN 2048
58 #define MAX_BILLING_ID_LEN 2048
59 
60 static GncSqlColumnTableEntry col_table[] =
61 {
62  { "guid", CT_GUID, 0, COL_NNUL | COL_PKEY, "guid" },
63  { "id", CT_STRING, MAX_ID_LEN, COL_NNUL, NULL, INVOICE_ID },
64  { "date_opened", CT_TIMESPEC, 0, 0, NULL, INVOICE_OPENED },
65  { "date_posted", CT_TIMESPEC, 0, 0, NULL, INVOICE_POSTED },
66  { "notes", CT_STRING, MAX_NOTES_LEN, COL_NNUL, "notes" },
67  { "active", CT_BOOLEAN, 0, COL_NNUL, NULL, QOF_PARAM_ACTIVE },
68  {
69  "currency", CT_COMMODITYREF, 0, COL_NNUL, NULL, NULL,
70  (QofAccessFunc)gncInvoiceGetCurrency, (QofSetterFunc)gncInvoiceSetCurrency
71  },
72  {
73  "owner", CT_OWNERREF, 0, 0, NULL, NULL,
74  (QofAccessFunc)gncInvoiceGetOwner, (QofSetterFunc)gncInvoiceSetOwner
75  },
76  { "terms", CT_BILLTERMREF, 0, 0, NULL, INVOICE_TERMS },
77  { "billing_id", CT_STRING, MAX_BILLING_ID_LEN, 0, NULL, INVOICE_BILLINGID },
78  { "post_txn", CT_TXREF, 0, 0, NULL, INVOICE_POST_TXN },
79  {
80  "post_lot", CT_LOTREF, 0, 0, NULL, NULL,
81  (QofAccessFunc)gncInvoiceGetPostedLot, (QofSetterFunc)gncInvoiceSetPostedLot
82  },
83  { "post_acc", CT_ACCOUNTREF, 0, 0, NULL, INVOICE_ACC },
84  {
85  "billto", CT_OWNERREF, 0, 0, NULL, NULL,
86  (QofAccessFunc)gncInvoiceGetBillTo, (QofSetterFunc)gncInvoiceSetBillTo
87  },
88  {
89  "charge_amt", CT_NUMERIC, 0, 0, NULL, NULL,
90  (QofAccessFunc)gncInvoiceGetToChargeAmount, (QofSetterFunc)gncInvoiceSetToChargeAmount
91  },
92  { NULL }
93 };
94 
95 static GncInvoice*
96 load_single_invoice( GncSqlBackend* be, GncSqlRow* row )
97 {
98  const GncGUID* guid;
99  GncInvoice* pInvoice;
100 
101  g_return_val_if_fail( be != NULL, NULL );
102  g_return_val_if_fail( row != NULL, NULL );
103 
104  guid = gnc_sql_load_guid( be, row );
105  pInvoice = gncInvoiceLookup( be->book, guid );
106  if ( pInvoice == NULL )
107  {
108  pInvoice = gncInvoiceCreate( be->book );
109  }
110  gnc_sql_load_object( be, row, GNC_ID_INVOICE, pInvoice, col_table );
111  qof_instance_mark_clean( QOF_INSTANCE(pInvoice) );
112 
113  return pInvoice;
114 }
115 
116 static void
117 load_all_invoices( GncSqlBackend* be )
118 {
119  GncSqlStatement* stmt;
120  GncSqlResult* result;
121 
122  g_return_if_fail( be != NULL );
123 
124  stmt = gnc_sql_create_select_statement( be, TABLE_NAME );
125  result = gnc_sql_execute_select_statement( be, stmt );
126  gnc_sql_statement_dispose( stmt );
127  if ( result != NULL )
128  {
129  GncSqlRow* row;
130  GList* list = NULL;
131 
132  row = gnc_sql_result_get_first_row( result );
133  while ( row != NULL )
134  {
135  GncInvoice* pInvoice = load_single_invoice( be, row );
136  if ( pInvoice != NULL )
137  {
138  list = g_list_append( list, pInvoice );
139  }
140  row = gnc_sql_result_get_next_row( result );
141  }
142  gnc_sql_result_dispose( result );
143 
144  if ( list != NULL )
145  {
146  gnc_sql_slots_load_for_list( be, list );
147  g_list_free( list );
148  }
149  }
150 }
151 
152 /* ================================================================= */
153 static void
154 create_invoice_tables( GncSqlBackend* be )
155 {
156  gint version;
157 
158  g_return_if_fail( be != NULL );
159 
160  version = gnc_sql_get_table_version( be, TABLE_NAME );
161  if ( version == 0 )
162  {
163  gnc_sql_create_table( be, TABLE_NAME, TABLE_VERSION, col_table );
164  }
165  else if ( version < TABLE_VERSION )
166  {
167  /* Upgrade:
168  1->2: 64 bit int handling
169  2->3: invoice open date can be NULL
170  */
171  gnc_sql_upgrade_table( be, TABLE_NAME, col_table );
172  gnc_sql_set_table_version( be, TABLE_NAME, TABLE_VERSION );
173 
174  PINFO("Invoices table upgraded from version %d to version %d\n", version, TABLE_VERSION);
175  }
176 }
177 
178 /* ================================================================= */
179 static gboolean
180 save_invoice( GncSqlBackend* be, QofInstance* inst )
181 {
182  const GncGUID* guid;
183  GncInvoice* invoice;
184  gint op;
185  gboolean is_infant;
186  gboolean is_ok = TRUE;
187 
188  g_return_val_if_fail( inst != NULL, FALSE );
189  g_return_val_if_fail( GNC_IS_INVOICE(inst), FALSE );
190  g_return_val_if_fail( be != NULL, FALSE );
191 
192  invoice = GNC_INVOICE(inst);
193 
194  is_infant = qof_instance_get_infant( inst );
195  if ( qof_instance_get_destroying( inst ) )
196  {
197  op = OP_DB_DELETE;
198  }
199  else if ( be->is_pristine_db || is_infant )
200  {
201  op = OP_DB_INSERT;
202  }
203  else
204  {
205  op = OP_DB_UPDATE;
206  }
207  if ( op != OP_DB_DELETE )
208  {
209  // Ensure the commodity is in the db
210  is_ok = gnc_sql_save_commodity( be, gncInvoiceGetCurrency( invoice ) );
211  }
212 
213  if ( is_ok )
214  {
215  is_ok = gnc_sql_do_db_operation( be, op, TABLE_NAME, GNC_ID_INVOICE, inst, col_table );
216  }
217 
218  if ( is_ok )
219  {
220  // Now, commit or delete any slots
221  guid = qof_instance_get_guid( inst );
222  if ( !qof_instance_get_destroying(inst) )
223  {
224  is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) );
225  }
226  else
227  {
228  is_ok = gnc_sql_slots_delete( be, guid );
229  }
230  }
231 
232  return is_ok;
233 }
234 
235 /* ================================================================= */
236 static gboolean
237 invoice_should_be_saved( GncInvoice *invoice )
238 {
239  const char *id;
240 
241  g_return_val_if_fail( invoice != NULL, FALSE );
242 
243  /* make sure this is a valid invoice before we save it -- should have an ID */
244  id = gncInvoiceGetID( invoice );
245  if ( id == NULL || *id == '\0' )
246  {
247  return FALSE;
248  }
249 
250  return TRUE;
251 }
252 
253 static void
254 write_single_invoice( QofInstance *term_p, gpointer data_p )
255 {
256  write_objects_t* s = (write_objects_t*)data_p;
257 
258  g_return_if_fail( term_p != NULL );
259  g_return_if_fail( GNC_IS_INVOICE(term_p) );
260  g_return_if_fail( data_p != NULL );
261 
262  if ( s->is_ok && invoice_should_be_saved( GNC_INVOICE(term_p) ) )
263  {
264  s->is_ok = save_invoice( s->be, term_p );
265  }
266 }
267 
268 static gboolean
269 write_invoices( GncSqlBackend* be )
270 {
271  write_objects_t data;
272 
273  g_return_val_if_fail( be != NULL, FALSE );
274 
275  data.be = be;
276  data.is_ok = TRUE;
277  qof_object_foreach( GNC_ID_INVOICE, be->book, write_single_invoice, &data );
278 
279  return data.is_ok;
280 }
281 
282 /* ================================================================= */
283 static void
284 load_invoice_guid( const GncSqlBackend* be, GncSqlRow* row,
285  QofSetterFunc setter, gpointer pObject,
286  const GncSqlColumnTableEntry* table_row )
287 {
288  const GValue* val;
289  GncGUID guid;
290  GncInvoice* invoice = NULL;
291 
292  g_return_if_fail( be != NULL );
293  g_return_if_fail( row != NULL );
294  g_return_if_fail( pObject != NULL );
295  g_return_if_fail( table_row != NULL );
296 
297  val = gnc_sql_row_get_value_at_col_name( row, table_row->col_name );
298  if ( val != NULL && G_VALUE_HOLDS_STRING( val ) && g_value_get_string( val ) != NULL )
299  {
300  string_to_guid( g_value_get_string( val ), &guid );
301  invoice = gncInvoiceLookup( be->book, &guid );
302  if ( invoice != NULL )
303  {
304  if ( table_row->gobj_param_name != NULL )
305  {
306  qof_instance_increase_editlevel (pObject);
307  g_object_set( pObject, table_row->gobj_param_name, invoice, NULL );
308  qof_instance_decrease_editlevel (pObject);
309  }
310  else
311  {
312  (*setter)( pObject, (const gpointer)invoice );
313  }
314  }
315  else
316  {
317  PWARN( "Invoice ref '%s' not found", g_value_get_string( val ) );
318  }
319  }
320 }
321 
322 static GncSqlColumnTypeHandler invoice_guid_handler
323 = { load_invoice_guid,
327  };
328 /* ================================================================= */
329 void
330 gnc_invoice_sql_initialize( void )
331 {
332  static GncSqlObjectBackend be_data =
333  {
334  GNC_SQL_BACKEND_VERSION,
335  GNC_ID_INVOICE,
336  save_invoice, /* commit */
337  load_all_invoices, /* initial_load */
338  create_invoice_tables, /* create_tables */
339  NULL, NULL, NULL,
340  write_invoices /* write */
341  };
342 
343  qof_object_register_backend( GNC_ID_INVOICE, GNC_SQL_BACKEND, &be_data );
344 
345  gnc_sql_register_col_type_handler( CT_INVOICEREF, &invoice_guid_handler );
346 }
347 /* ========================== END OF FILE ===================== */
gboolean qof_object_register_backend(QofIdTypeConst type_name, const char *backend_name, gpointer be_data)
const GncGUID * qof_instance_get_guid(gconstpointer)
gint gnc_sql_get_table_version(const GncSqlBackend *be, const gchar *table_name)
void gnc_sql_upgrade_table(GncSqlBackend *be, const gchar *table_name, const GncSqlColumnTableEntry *col_table)
#define G_LOG_DOMAIN
Functions providing the SX List as a plugin page.
#define PINFO(format, args...)
Definition: qoflog.h:249
load and save data to SQL
void gnc_sql_add_colname_to_list(const GncSqlColumnTableEntry *table_row, GList **pList)
load and save accounts data to SQL
GncSqlStatement * gnc_sql_create_select_statement(GncSqlBackend *be, const gchar *table_name)
#define COL_NNUL
gboolean qof_instance_get_destroying(gconstpointer ptr)
gboolean string_to_guid(const gchar *string, GncGUID *guid)
gboolean gnc_sql_create_table(GncSqlBackend *be, const gchar *table_name, gint table_version, const GncSqlColumnTableEntry *col_table)
load and save data to SQL
void gnc_sql_register_col_type_handler(const gchar *colType, const GncSqlColumnTypeHandler *handler)
void gnc_sql_add_objectref_guid_col_info_to_list(const GncSqlBackend *be, const GncSqlColumnTableEntry *table_row, GList **pList)
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
Definition: qofclass.h:177
load and save accounts data to SQL
QofBook * book
Definition: guid.h:65
#define COL_PKEY
#define PWARN(format, args...)
Definition: qoflog.h:243
const GncGUID * gnc_sql_load_guid(const GncSqlBackend *be, GncSqlRow *row)
gboolean gnc_sql_set_table_version(GncSqlBackend *be, const gchar *table_name, gint version)
load and save owner data to SQL
void gnc_sql_add_gvalue_objectref_guid_to_slist(const GncSqlBackend *be, QofIdTypeConst obj_name, const gpointer pObject, const GncSqlColumnTableEntry *table_row, GSList **pList)
void gnc_sql_slots_load_for_list(GncSqlBackend *be, GList *list)
void qof_object_foreach(QofIdTypeConst type_name, QofBook *book, QofInstanceForeachCB cb, gpointer user_data)
GncSqlResult * gnc_sql_execute_select_statement(GncSqlBackend *be, GncSqlStatement *stmt)
void gnc_sql_load_object(const GncSqlBackend *be, GncSqlRow *row, QofIdTypeConst obj_name, gpointer pObject, const GncSqlColumnTableEntry *table)
const gchar * gobj_param_name
gboolean gnc_sql_slots_delete(GncSqlBackend *be, const GncGUID *guid)
gboolean is_pristine_db
void(* QofSetterFunc)(gpointer, gpointer)
Definition: qofclass.h:184
gboolean gnc_sql_do_db_operation(GncSqlBackend *be, E_DB_OPERATION op, const gchar *table_name, QofIdTypeConst obj_name, gpointer pObject, const GncSqlColumnTableEntry *table)
load and save invoice data to SQL
Commodity handling public routines.
gboolean gnc_sql_slots_save(GncSqlBackend *be, const GncGUID *guid, gboolean is_infant, KvpFrame *pFrame)
const gchar * QofLogModule
Definition: qofid.h:89