GnuCash c935c2f+
Loading...
Searching...
No Matches
dialog-order.c
1/*
2 * dialog-order.c -- Dialog for Order entry
3 * Copyright (C) 2001,2002 Derek Atkins
4 * Author: Derek Atkins <warlord@MIT.EDU>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, contact:
18 *
19 * Free Software Foundation Voice: +1-617-542-5942
20 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
21 * Boston, MA 02110-1301, USA gnu@gnu.org
22 */
23
24#include <config.h>
25
26#include <gtk/gtk.h>
27#include <glib/gi18n.h>
28#include <stdint.h>
29
30#include "dialog-utils.h"
31#include "gnc-component-manager.h"
32#include "gnc-date-edit.h"
33#include "gnc-ui.h"
34#include "gnc-gui-query.h"
35#include "gnc-ui-util.h"
36#include "qof.h"
37#include "gnucash-register.h"
38#include "gnucash-sheet.h"
39#include "dialog-search.h"
40#include "search-param.h"
41
42#include "gncOrder.h"
43#include "gncOrderP.h"
44
45#include "gncEntryLedger.h"
46
47#include "dialog-order.h"
48#include "dialog-invoice.h"
49#include "business-gnome-utils.h"
50#include "dialog-date-close.h"
51#include "gnc-general-search.h"
52
53#define DIALOG_NEW_ORDER_CM_CLASS "dialog-new-order"
54#define DIALOG_EDIT_ORDER_CM_CLASS "dialog-edit-order"
55#define DIALOG_VIEW_ORDER_CM_CLASS "dialog-view-order"
56
57#define GNC_PREFS_GROUP_SEARCH "dialogs.business.order-search"
58
59void gnc_order_window_ok_cb (GtkWidget *widget, gpointer data);
60void gnc_order_window_cancel_cb (GtkWidget *widget, gpointer data);
61void gnc_order_window_help_cb (GtkWidget *widget, gpointer data);
62void gnc_order_window_invoice_cb (GtkWidget *widget, gpointer data);
63void gnc_order_window_close_order_cb (GtkWidget *widget, gpointer data);
64void gnc_order_window_destroy_cb (GtkWidget *widget, gpointer data);
65
66typedef enum
67{
68 NEW_ORDER,
69 EDIT_ORDER,
70 VIEW_ORDER
71} OrderDialogType;
72
74{
75 QofBook *book;
76 GncOwner *owner;
77 QofQuery *q;
78 GncOwner owner_def;
79};
80
82{
83 GtkWidget * dialog;
84
85 GtkWidget * id_entry;
86 GtkWidget * ref_entry;
87 GtkWidget * notes_text;
88 GtkWidget * opened_date;
89 GtkWidget * closed_date;
90 GtkWidget * active_check;
91
92 GtkWidget * cd_label;
93 GtkWidget * close_order_button;
94
95 GtkWidget * owner_box;
96 GtkWidget * owner_label;
97 GtkWidget * owner_choice;
98
99 GnucashRegister * reg;
100 GncEntryLedger * ledger;
101
102 OrderDialogType dialog_type;
103 GncGUID order_guid;
104 gint component_id;
105 QofBook * book;
106 GncOrder * created_order;
107 GncOwner owner;
108
109};
110
111static void gnc_order_update_window (OrderWindow *ow);
112
113static GncOrder *
114ow_get_order (OrderWindow *ow)
115{
116 if (!ow)
117 return NULL;
118
119 return gncOrderLookup (ow->book, &ow->order_guid);
120}
121
122static void gnc_ui_to_order (OrderWindow *ow, GncOrder *order)
123{
124 GtkTextBuffer* text_buffer;
125 GtkTextIter start, end;
126 gchar *text;
127 time64 tt;
128
129 /* Do nothing if this is view only */
130 if (ow->dialog_type == VIEW_ORDER)
131 return;
132
133 gnc_suspend_gui_refresh ();
134 gncOrderBeginEdit (order);
135
136 gncOrderSetID (order, gtk_entry_get_text (GTK_ENTRY (ow->id_entry)));
137
138 text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(ow->notes_text));
139 gtk_text_buffer_get_bounds (text_buffer, &start, &end);
140 text = gtk_text_buffer_get_text (text_buffer, &start, &end, FALSE);
141 gncOrderSetNotes (order, text);
142
143 gncOrderSetReference (order, gtk_entry_get_text (GTK_ENTRY (ow->ref_entry)));
144
145 tt = gnc_date_edit_get_date (GNC_DATE_EDIT (ow->opened_date));
146 gncOrderSetDateOpened (order, tt);
147
148 if (ow->active_check)
149 gncOrderSetActive (order, gtk_toggle_button_get_active
150 (GTK_TOGGLE_BUTTON (ow->active_check)));
151
152 gnc_owner_get_owner (ow->owner_choice, &(ow->owner));
153 gncOrderSetOwner (order, &(ow->owner));
154
155 gncOrderCommitEdit (order);
156 gnc_resume_gui_refresh ();
157 g_free (text);
158}
159
160static gboolean
161gnc_order_window_verify_ok (OrderWindow *ow)
162{
163 const char *res;
164
165 /* Check the ID */
166 res = gtk_entry_get_text (GTK_ENTRY (ow->id_entry));
167 if (g_strcmp0 (res, "") == 0)
168 {
169 gnc_error_dialog (GTK_WINDOW (ow->dialog), "%s",
170 _("The Order must be given an ID."));
171 return FALSE;
172 }
173
174 /* Check the Owner */
175 gnc_owner_get_owner (ow->owner_choice, &(ow->owner));
176 res = gncOwnerGetName (&(ow->owner));
177 if (res == NULL || g_strcmp0 (res, "") == 0)
178 {
179 gnc_error_dialog (GTK_WINDOW (ow->dialog), "%s",
180 _("You need to supply Billing Information."));
181 return FALSE;
182 }
183
184 return TRUE;
185}
186
187static gboolean
188gnc_order_window_ok_save (OrderWindow *ow)
189{
190 if (!gnc_entry_ledger_check_close (ow->dialog, ow->ledger))
191 return FALSE;
192
193 if (!gnc_order_window_verify_ok (ow))
194 return FALSE;
195
196 /* Now save it off */
197 {
198 GncOrder *order = ow_get_order (ow);
199 if (order)
200 {
201 gnc_ui_to_order (ow, order);
202
203 }
204 ow->created_order = order;
205 }
206 return TRUE;
207}
208
209void
210gnc_order_window_ok_cb (GtkWidget *widget, gpointer data)
211{
212 OrderWindow *ow = data;
213
214 if (!gnc_order_window_ok_save (ow))
215 return;
216
217 /* Ok, we don't need this anymore */
218 ow->order_guid = *guid_null ();
219
220 gnc_close_gui_component (ow->component_id);
221}
222
223void
224gnc_order_window_cancel_cb (GtkWidget *widget, gpointer data)
225{
226 OrderWindow *ow = data;
227
228 gnc_close_gui_component (ow->component_id);
229}
230
231void
232gnc_order_window_help_cb (GtkWidget *widget, gpointer data)
233{
234 OrderWindow *ow = data;
235 gnc_gnome_help (GTK_WINDOW(ow->dialog), DF_MANUAL, DL_USAGE_BILL);
236}
237
238void
239gnc_order_window_invoice_cb (GtkWidget *widget, gpointer data)
240{
241 OrderWindow *ow = data;
242
243 /* make sure we're ok */
244 if (!gnc_order_window_verify_ok (ow))
245 return;
246
247 /* Ok, go make an invoice */
248 gnc_invoice_search (gtk_window_get_transient_for(GTK_WINDOW(ow->dialog)), NULL, &(ow->owner), ow->book);
249
250 /* refresh the window */
251 gnc_order_update_window (ow);
252}
253
254void
255gnc_order_window_close_order_cb (GtkWidget *widget, gpointer data)
256{
257 OrderWindow *ow = data;
258 GncOrder *order;
259 GList *entries;
260 char *message, *label;
261 gboolean non_inv = FALSE;
262 time64 t = gnc_time (NULL);
263
264 /* Make sure the order is ok */
265 if (!gnc_order_window_verify_ok (ow))
266 return;
267
268 /* Make sure the order exists */
269 order = ow_get_order (ow);
270 if (!order)
271 return;
272
273 /* Check that there is at least one Entry */
274 if (gncOrderGetEntries (order) == NULL)
275 {
276 gnc_error_dialog (GTK_WINDOW (ow->dialog), "%s",
277 _("The Order must have at least one Entry."));
278 return;
279 }
280
281 /* Make sure we can close the order. Are there any uninvoiced entries? */
282 entries = gncOrderGetEntries (order);
283 for ( ; entries ; entries = entries->next)
284 {
285 GncEntry *entry = entries->data;
286 if (gncEntryGetInvoice (entry) == NULL)
287 {
288 non_inv = TRUE;
289 break;
290 }
291 }
292
293 if (non_inv)
294 {
295 /* Damn; yes. Well, ask the user to make sure they REALLY want to
296 * close this order!
297 */
298
299 message = _("This order contains entries that have not been invoiced. "
300 "Are you sure you want to close it out before "
301 "you invoice all the entries?");
302
303 if (gnc_verify_dialog (GTK_WINDOW (ow->dialog), FALSE, "%s", message) == FALSE)
304 return;
305 }
306
307 /* Ok, we can close this. Ask for verification and set the closed date */
308 message = _("Do you really want to close the order?");
309 label = _("Close Date");
310
311 if (!gnc_dialog_date_close_parented (ow->dialog, message, label, TRUE, &t))
312 return;
313
314 gncOrderSetDateClosed (order, t);
315
316 /* save it off */
317 gnc_order_window_ok_save (ow);
318
319 /* Reset the type; change to read-only */
320 ow->dialog_type = VIEW_ORDER;
321 gnc_entry_ledger_set_readonly (ow->ledger, TRUE);
322
323 /* And redisplay the window */
324 gnc_order_update_window (ow);
325}
326
327void
328gnc_order_window_destroy_cb (GtkWidget *widget, gpointer data)
329{
330 OrderWindow *ow = data;
331 GncOrder *order = ow_get_order (ow);
332
333 gnc_suspend_gui_refresh ();
334
335 if (ow->dialog_type == NEW_ORDER && order != NULL)
336 {
337 gncOrderBeginEdit (order);
338 gncOrderDestroy (order);
339 ow->order_guid = *guid_null ();
340 }
341
342 if (ow->ledger)
343 gnc_entry_ledger_destroy (ow->ledger);
344 gnc_unregister_gui_component (ow->component_id);
345 gnc_resume_gui_refresh ();
346
347 g_free (ow);
348}
349
350static int
351gnc_order_owner_changed_cb (GtkWidget *widget, gpointer data)
352{
353 OrderWindow *ow = data;
354 GncOrder *order;
355
356 if (!ow)
357 return FALSE;
358
359 if (ow->dialog_type == VIEW_ORDER)
360 return FALSE;
361
362 gnc_owner_get_owner (ow->owner_choice, &(ow->owner));
363
364 /* Set the Order's owner now! */
365 order = ow_get_order (ow);
366 gncOrderSetOwner (order, &(ow->owner));
367
368 if (ow->dialog_type == EDIT_ORDER)
369 return FALSE;
370
371 /* Only set the reference during the New Job dialog */
372 switch (gncOwnerGetType (&(ow->owner)))
373 {
374 case GNC_OWNER_JOB:
375 {
376 char const *msg = gncJobGetReference (gncOwnerGetJob (&(ow->owner)));
377 gtk_entry_set_text (GTK_ENTRY (ow->ref_entry), msg ? msg : "");
378 break;
379 }
380 default:
381 gtk_entry_set_text (GTK_ENTRY (ow->ref_entry), "");
382 break;
383 }
384
385 return FALSE;
386}
387
388static void
389gnc_order_window_close_handler (gpointer user_data)
390{
391 OrderWindow *ow = user_data;
392
393 gtk_widget_destroy (ow->dialog);
394}
395
396static void
397gnc_order_window_refresh_handler (GHashTable *changes, gpointer user_data)
398{
399 OrderWindow *ow = user_data;
400 const EventInfo *info;
401 GncOrder *order = ow_get_order (ow);
402
403 /* If there isn't a order behind us, close down */
404 if (!order)
405 {
406 gnc_close_gui_component (ow->component_id);
407 return;
408 }
409
410 /* Next, close if this is a destroy event */
411 if (changes)
412 {
413 info = gnc_gui_get_entity_events (changes, &ow->order_guid);
414 if (info && (info->event_mask & QOF_EVENT_DESTROY))
415 {
416 gnc_close_gui_component (ow->component_id);
417 return;
418 }
419 }
420}
421
422static void
423gnc_order_update_window (OrderWindow *ow)
424{
425 GncOrder *order;
426 GncOwner *owner;
427 gboolean hide_cd = FALSE;
428
429 order = ow_get_order (ow);
430 owner = gncOrderGetOwner (order);
431
432 if (ow->owner_choice)
433 {
434 gtk_container_remove (GTK_CONTAINER (ow->owner_box), ow->owner_choice);
435 gtk_widget_destroy (ow->owner_choice);
436 }
437
438 switch (ow->dialog_type)
439 {
440 case VIEW_ORDER:
441 case EDIT_ORDER:
442 ow->owner_choice =
443 gnc_owner_edit_create (ow->owner_label, ow->owner_box, ow->book,
444 owner);
445 break;
446 case NEW_ORDER:
447 ow->owner_choice =
448 gnc_owner_select_create (ow->owner_label, ow->owner_box, ow->book,
449 owner);
450 break;
451 }
452
453 g_signal_connect (ow->owner_choice, "changed",
454 G_CALLBACK (gnc_order_owner_changed_cb),
455 ow);
456
457 gtk_widget_show_all (ow->dialog);
458
459 {
460 GtkTextBuffer* text_buffer;
461 const char *string;
462 time64 tt;
463
464 gtk_entry_set_text (GTK_ENTRY (ow->ref_entry),
465 gncOrderGetReference (order));
466
467 string = gncOrderGetNotes (order);
468 text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(ow->notes_text));
469 gtk_text_buffer_set_text (text_buffer, string, -1);
470
471 tt = gncOrderGetDateOpened (order);
472 if (tt == INT64_MAX)
473 {
474 gnc_date_edit_set_time (GNC_DATE_EDIT (ow->opened_date),
475 gnc_time (NULL));
476 }
477 else
478 {
479 gnc_date_edit_set_time (GNC_DATE_EDIT (ow->opened_date), tt);
480 }
481
482 /* If this is a "New Order Window" we can stop here! */
483 if (ow->dialog_type == NEW_ORDER)
484 return;
485
486 tt = gncOrderGetDateClosed (order);
487 if (tt == INT64_MAX)
488 {
489 gnc_date_edit_set_time (GNC_DATE_EDIT (ow->closed_date),
490 gnc_time (NULL));
491 hide_cd = TRUE;
492 }
493 else
494 {
495 gnc_date_edit_set_time (GNC_DATE_EDIT (ow->closed_date), tt);
496 }
497
498 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ow->active_check),
499 gncOrderGetActive (order));
500
501 }
502
503 gnc_gui_component_watch_entity_type (ow->component_id,
504 GNC_ORDER_MODULE_NAME,
505 QOF_EVENT_MODIFY | QOF_EVENT_DESTROY);
506
508
509 if (hide_cd)
510 {
511 gtk_widget_hide (ow->closed_date);
512 gtk_widget_hide (ow->cd_label);
513 }
514
515 if (ow->dialog_type == VIEW_ORDER)
516 {
517 /* Setup viewer for read-only access */
518 gtk_widget_set_sensitive (ow->id_entry, FALSE);
519 gtk_widget_set_sensitive (ow->opened_date, FALSE);
520 gtk_widget_set_sensitive (ow->closed_date, FALSE);
521 gtk_widget_set_sensitive (ow->notes_text, FALSE); /* XXX: Should notes remain writable? */
522
523 /* Hide the 'close order' button */
524 gtk_widget_hide (ow->close_order_button);
525 }
526}
527
528static gboolean
529find_handler (gpointer find_data, gpointer user_data)
530{
531 const GncGUID *order_guid = find_data;
532 OrderWindow *ow = user_data;
533
534 return(ow && guid_equal(&ow->order_guid, order_guid));
535}
536
537static OrderWindow *
538gnc_order_new_window (GtkWindow *parent, QofBook *bookp, OrderDialogType type,
539 GncOrder *order, GncOwner *owner)
540{
541 OrderWindow *ow;
542 GtkBuilder *builder;
543 GtkWidget *vbox, *regWidget, *hbox, *date;
544 GncEntryLedger *entry_ledger = NULL;
545 const char * class_name;
546
547 switch (type)
548 {
549 case EDIT_ORDER:
550 class_name = DIALOG_EDIT_ORDER_CM_CLASS;
551 break;
552 case VIEW_ORDER:
553 default:
554 class_name = DIALOG_VIEW_ORDER_CM_CLASS;
555 break;
556 }
557
558 /*
559 * Find an existing window for this order. If found, bring it to
560 * the front.
561 */
562 if (order)
563 {
564 GncGUID order_guid;
565
566 order_guid = *gncOrderGetGUID(order);
567 ow = gnc_find_first_gui_component (class_name, find_handler,
568 &order_guid);
569 if (ow)
570 {
571 gtk_window_present (GTK_WINDOW(ow->dialog));
572 gtk_window_set_transient_for (GTK_WINDOW(ow->dialog), parent);
573 return(ow);
574 }
575 }
576
577 /*
578 * No existing order window found. Build a new one.
579 */
580 ow = g_new0 (OrderWindow, 1);
581 ow->book = bookp;
582 ow->dialog_type = type;
583
584 /* Save this for later */
585 gncOwnerCopy (owner, &(ow->owner));
586
587 /* Find the dialog */
588 builder = gtk_builder_new();
589 gnc_builder_add_from_file (builder, "dialog-order.glade", "order_entry_dialog");
590 ow->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "order_entry_dialog"));
591 gtk_window_set_transient_for (GTK_WINDOW(ow->dialog), parent);
592
593 // Set the name for this dialog so it can be easily manipulated with css
594 gtk_widget_set_name (GTK_WIDGET(ow->dialog), "gnc-id-order");
595 gnc_widget_style_context_add_class (GTK_WIDGET(ow->dialog), "gnc-class-orders");
596
597 /* Grab the widgets */
598 ow->id_entry = GTK_WIDGET(gtk_builder_get_object (builder, "id_entry"));
599 ow->ref_entry = GTK_WIDGET(gtk_builder_get_object (builder, "ref_entry"));
600 ow->notes_text = GTK_WIDGET(gtk_builder_get_object (builder, "notes_text"));
601 ow->active_check = GTK_WIDGET(gtk_builder_get_object (builder, "active_check"));
602 ow->owner_box = GTK_WIDGET(gtk_builder_get_object (builder, "owner_hbox"));
603 ow->owner_label = GTK_WIDGET(gtk_builder_get_object (builder, "owner_label"));
604
605 ow->cd_label = GTK_WIDGET(gtk_builder_get_object (builder, "cd_label"));
606 ow->close_order_button = GTK_WIDGET(gtk_builder_get_object (builder, "close_order_button"));
607
608
609 /* Setup Date Widgets */
610 hbox = GTK_WIDGET(gtk_builder_get_object (builder, "opened_date_hbox"));
611 date = gnc_date_edit_new (time (NULL), FALSE, FALSE);
612 gtk_box_pack_start (GTK_BOX (hbox), date, TRUE, TRUE, 0);
613 gtk_widget_show (date);
614 ow->opened_date = date;
615
616 hbox = GTK_WIDGET(gtk_builder_get_object (builder, "closed_date_hbox"));
617 date = gnc_date_edit_new (time (NULL), FALSE, FALSE);
618 gtk_box_pack_start (GTK_BOX (hbox), date, TRUE, TRUE, 0);
619 gtk_widget_show (date);
620 ow->closed_date = date;
621
622 /* Build the ledger */
623 switch (type)
624 {
625 case EDIT_ORDER:
626 entry_ledger = gnc_entry_ledger_new (ow->book, GNCENTRY_ORDER_ENTRY);
627 break;
628 case VIEW_ORDER:
629 default:
630 entry_ledger = gnc_entry_ledger_new (ow->book, GNCENTRY_ORDER_VIEWER);
631 break;
632 }
633
634 /* Save the entry ledger for later */
635 ow->ledger = entry_ledger;
636
637 /* Set the order for the entry_ledger */
638 gnc_entry_ledger_set_default_order (entry_ledger, order);
639
640 /* Set watches on entries */
641 // entries = gncOrderGetEntries (order);
642 // gnc_entry_ledger_load (entry_ledger, entries);
643
644 /* Watch the order of operations, here... */
645 regWidget = gnucash_register_new (gnc_entry_ledger_get_table (entry_ledger),
646 NULL);
647 ow->reg = GNUCASH_REGISTER (regWidget);
648 gnucash_sheet_set_window (gnucash_register_get_sheet (ow->reg), ow->dialog);
649 gnc_entry_ledger_set_parent (entry_ledger, ow->dialog);
650
651 vbox = GTK_WIDGET(gtk_builder_get_object (builder, "ledger_vbox"));
652 gtk_box_pack_start (GTK_BOX(vbox), regWidget, TRUE, TRUE, 2);
653
654 /* Setup signals */
655 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, ow);
656
657 /* Setup initial values */
658 ow->order_guid = *gncOrderGetGUID (order);
659
660 gtk_entry_set_text (GTK_ENTRY (ow->id_entry), gncOrderGetID (order));
661
662 ow->component_id =
663 gnc_register_gui_component (class_name,
664 gnc_order_window_refresh_handler,
665 gnc_order_window_close_handler,
666 ow);
667
668 gnc_table_realize_gui (gnc_entry_ledger_get_table (entry_ledger));
669
670 /* Now fill in a lot of the pieces and display properly */
671 gnc_order_update_window (ow);
672
673 /* Maybe set the reference */
674 gnc_order_owner_changed_cb (ow->owner_choice, ow);
675
676 g_object_unref(G_OBJECT(builder));
677
678 return ow;
679}
680
681static OrderWindow *
682gnc_order_window_new_order (GtkWindow *parent, QofBook *bookp, GncOwner *owner)
683{
684 OrderWindow *ow;
685 GtkBuilder *builder;
686 GncOrder *order;
687 gchar *string;
688 GtkWidget *hbox, *date;
689
690 ow = g_new0 (OrderWindow, 1);
691 ow->book = bookp;
692 ow->dialog_type = NEW_ORDER;
693
694 order = gncOrderCreate (bookp);
695 gncOrderSetOwner (order, owner);
696
697 /* Save this for later */
698 gncOwnerCopy (owner, &(ow->owner));
699
700 /* Find the dialog */
701 builder = gtk_builder_new();
702 gnc_builder_add_from_file (builder, "dialog-order.glade", "new_order_dialog");
703
704 ow->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "new_order_dialog"));
705 gtk_window_set_transient_for (GTK_WINDOW(ow->dialog), parent);
706
707 // Set the name for this dialog so it can be easily manipulated with css
708 gtk_widget_set_name (GTK_WIDGET(ow->dialog), "gnc-id-new-order");
709 gnc_widget_style_context_add_class (GTK_WIDGET(ow->dialog), "gnc-class-orders");
710
711 g_object_set_data (G_OBJECT (ow->dialog), "dialog_info", ow);
712
713 /* Grab the widgets */
714 ow->id_entry = GTK_WIDGET(gtk_builder_get_object (builder, "entry_id"));
715 ow->ref_entry = GTK_WIDGET(gtk_builder_get_object (builder, "entry_ref"));
716 ow->notes_text = GTK_WIDGET(gtk_builder_get_object (builder, "text_notes"));
717 ow->owner_box = GTK_WIDGET(gtk_builder_get_object (builder, "bill_owner_hbox"));
718 ow->owner_label = GTK_WIDGET(gtk_builder_get_object (builder, "bill_owner_label"));
719
720 /* Setup date Widget */
721 hbox = GTK_WIDGET(gtk_builder_get_object (builder, "date_opened_hbox"));
722 date = gnc_date_edit_new (time (NULL), FALSE, FALSE);
723 gtk_box_pack_start (GTK_BOX (hbox), date, TRUE, TRUE, 0);
724 gtk_widget_show (date);
725 ow->opened_date = date;
726
727 /* Setup signals */
728 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, ow);
729
730 /* Setup initial values */
731 ow->order_guid = *gncOrderGetGUID (order);
732 string = gncOrderNextID(bookp);
733 gtk_entry_set_text (GTK_ENTRY (ow->id_entry), string);
734 g_free(string);
735
736 ow->component_id =
737 gnc_register_gui_component (DIALOG_NEW_ORDER_CM_CLASS,
738 gnc_order_window_refresh_handler,
739 gnc_order_window_close_handler,
740 ow);
741
742 /* Now fill in a lot of the pieces and display properly */
743 gnc_order_update_window (ow);
744
745 // The customer choice widget should have keyboard focus
746 if (GNC_IS_GENERAL_SEARCH(ow->owner_choice))
747 {
748 gnc_general_search_grab_focus(GNC_GENERAL_SEARCH(ow->owner_choice));
749 }
750
751 /* Maybe set the reference */
752 gnc_order_owner_changed_cb (ow->owner_choice, ow);
753
754 g_object_unref(G_OBJECT(builder));
755
756 return ow;
757}
758
759OrderWindow *
760gnc_ui_order_edit (GtkWindow *parent, GncOrder *order)
761{
762 OrderWindow *ow;
763 OrderDialogType type;
764
765 if (!order) return NULL;
766
767 type = EDIT_ORDER;
768 if (gncOrderGetDateClosed (order) == INT64_MAX)
769 type = VIEW_ORDER;
770
771 ow = gnc_order_new_window (parent, gncOrderGetBook(order), type, order,
772 gncOrderGetOwner (order));
773
774 return ow;
775}
776
777OrderWindow *
778gnc_ui_order_new (GtkWindow *parent, GncOwner *ownerp, QofBook *bookp)
779{
780 OrderWindow *ow;
781 GncOwner owner;
782
783 if (ownerp)
784 {
785 switch (gncOwnerGetType (ownerp))
786 {
787 case GNC_OWNER_CUSTOMER:
788 case GNC_OWNER_VENDOR:
789 case GNC_OWNER_JOB:
790 gncOwnerCopy (ownerp, &owner);
791 break;
792 default:
793 g_warning ("Cannot deal with unknown Owner types");
794 /* XXX: popup a warning? */
795 return NULL;
796 }
797 }
798 else
799 gncOwnerInitJob (&owner, NULL); /* XXX: pass in the owner type? */
800
801 /* Make sure required options exist */
802 if (!bookp) return NULL;
803
804 ow = gnc_order_window_new_order (parent, bookp, &owner);
805
806 return ow;
807}
808
809/* Functions for order selection widgets */
810
811static void
812edit_order_cb (GtkWindow *dialog, gpointer *order_p, gpointer user_data)
813{
814 GncOrder *order;
815
816 g_return_if_fail (order_p && user_data);
817
818 order = *order_p;
819
820 if (order)
821 gnc_ui_order_edit (dialog, order);
822
823 return;
824}
825
826static gpointer
827new_order_cb (GtkWindow *dialog, gpointer user_data)
828{
829 struct _order_select_window *sw = user_data;
830 OrderWindow *ow;
831
832 g_return_val_if_fail (user_data, NULL);
833
834 ow = gnc_ui_order_new (dialog, sw->owner, sw->book);
835 return ow_get_order (ow);
836}
837
838static void
839free_order_cb (gpointer user_data)
840{
841 struct _order_select_window *sw = user_data;
842
843 g_return_if_fail (sw);
844
845 qof_query_destroy (sw->q);
846 g_free (sw);
847}
848
849GNCSearchWindow *
850gnc_order_search (GtkWindow *parent, GncOrder *start, GncOwner *owner, QofBook *book)
851{
852 QofIdType type = GNC_ORDER_MODULE_NAME;
853 struct _order_select_window *sw;
854 QofQuery *q, *q2 = NULL;
855 static GList *params = NULL;
856 static GList *columns = NULL;
857 static GNCSearchCallbackButton buttons[] =
858 {
859 { N_("View/Edit Order"), edit_order_cb, NULL, TRUE},
860 { NULL },
861 };
862
863 g_return_val_if_fail (book, NULL);
864
865 /* Build parameter list in reverse order */
866 if (params == NULL)
867 {
868 params = gnc_search_param_prepend (params, _("Order Notes"), NULL, type,
869 ORDER_NOTES, NULL);
870 params = gnc_search_param_prepend (params, _("Date Closed"), NULL, type,
871 ORDER_CLOSED, NULL);
872 params = gnc_search_param_prepend (params, _("Is Closed?"), NULL, type,
873 ORDER_IS_CLOSED, NULL);
874 params = gnc_search_param_prepend (params, _("Date Opened"), NULL, type,
875 ORDER_OPENED, NULL);
876 params = gnc_search_param_prepend (params, _("Owner Name"), NULL, type,
877 ORDER_OWNER, OWNER_NAME, NULL);
878 params = gnc_search_param_prepend (params, _("Order ID"), NULL, type,
879 ORDER_ID, NULL);
880 }
881
882 /* Build the column list in reverse order */
883 if (columns == NULL)
884 {
885 columns = gnc_search_param_prepend (columns, _("Billing ID"), NULL, type,
886 ORDER_REFERENCE, NULL);
887 columns = gnc_search_param_prepend (columns, _("Company"), NULL, type,
888 ORDER_OWNER, OWNER_PARENT,
889 OWNER_NAME, NULL);
890 columns = gnc_search_param_prepend (columns, _("Closed"), NULL, type,
891 ORDER_CLOSED, NULL);
892 columns = gnc_search_param_prepend (columns, _("Opened"), NULL, type,
893 ORDER_OPENED, NULL);
894 columns = gnc_search_param_prepend (columns, _("Num"), NULL, type,
895 ORDER_ID, NULL);
896 }
897
898 /* Build the queries */
899 q = qof_query_create_for (type);
900 qof_query_set_book (q, book);
901
902 /* If owner is supplied, limit all searches to orders who's owner
903 * (or parent) is the supplied owner!
904 */
905 if (owner && gncOwnerGetGUID (owner))
906 {
907 QofQuery *tmp, *q3;
908
909 q3 = qof_query_create_for (type);
910 qof_query_add_guid_match (q3, g_slist_prepend
911 (g_slist_prepend (NULL, QOF_PARAM_GUID),
912 ORDER_OWNER),
913 gncOwnerGetGUID (owner), QOF_QUERY_OR);
914 qof_query_add_guid_match (q3, g_slist_prepend
915 (g_slist_prepend (NULL, OWNER_PARENTG),
916 ORDER_OWNER),
917 gncOwnerGetGUID (owner), QOF_QUERY_OR);
918
919 tmp = qof_query_merge (q, q3, QOF_QUERY_AND);
922 q = tmp;
923 q2 = qof_query_copy (q);
924 }
925
926#if 0
927 if (start)
928 {
929 if (q2 == NULL)
930 q2 = qof_query_copy (q);
931
932 qof_query_add_guid_match (q2, g_slist_prepend (NULL, QOF_PARAM_GUID),
933 gncOrderGetGUID (start), QOF_QUERY_AND);
934 }
935#endif
936
937 /* launch select dialog and return the result */
938 sw = g_new0 (struct _order_select_window, 1);
939
940 if (owner)
941 {
942 gncOwnerCopy (owner, &(sw->owner_def));
943 sw->owner = &(sw->owner_def);
944 }
945 sw->book = book;
946 sw->q = q;
947
948 return gnc_search_dialog_create (parent, type, _("Find Order"),
949 params, columns, q, q2,
950 buttons, NULL, new_order_cb,
951 sw, free_order_cb, GNC_PREFS_GROUP_SEARCH,
952 NULL, "gnc-class-orders");
953}
954
955GNCSearchWindow *
956gnc_order_search_select (GtkWindow *parent, gpointer start, gpointer book)
957{
958 GncOrder *o = start;
959 GncOwner owner, *ownerp;
960
961 if (!book) return NULL;
962
963 if (o)
964 {
965 ownerp = gncOrderGetOwner (o);
966 gncOwnerCopy (ownerp, &owner);
967 }
968 else
969 gncOwnerInitCustomer (&owner, NULL); /* XXX */
970
971 return gnc_order_search (parent, start, NULL, book);
972}
973
974GNCSearchWindow *
975gnc_order_search_edit (GtkWindow *parent, gpointer start, gpointer book)
976{
977 if (start)
978 gnc_ui_order_edit (parent, start);
979
980 return NULL;
981}
utility functions for the GnuCash UI
Public declarations of GnucashRegister class.
GncEntryLedger * gnc_entry_ledger_new(QofBook *book, GncEntryLedgerType type)
Create and return a new GncEntry Ledger.
void gnc_entry_ledger_destroy(GncEntryLedger *ledger)
Destroy the GncEntry Ledger.
Table * gnc_entry_ledger_get_table(GncEntryLedger *ledger)
Get the Table.
void gnc_entry_ledger_set_default_order(GncEntryLedger *ledger, GncOrder *order)
Set the default order for this ledger.
gboolean gnc_entry_ledger_check_close(GtkWidget *parent, GncEntryLedger *ledger)
This will ask the user if they really want to make a change.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition gnc-date.h:87
time64 gnc_time(time64 *tbuf)
get the current time
Definition gnc-date.cpp:262
const gchar * QofIdType
QofIdType declaration.
Definition qofid.h:80
const GncGUID * guid_null(void)
Returns a GncGUID which is guaranteed to never reference any entity.
Definition guid.cpp:165
gboolean guid_equal(const GncGUID *guid_1, const GncGUID *guid_2)
Given two GUIDs, return TRUE if they are non-NULL and equal.
Definition guid.cpp:237
GtkWidget * gnucash_register_new(Table *table, const gchar *state_section)
this already has scrollbars attached
void gnc_gnome_help(GtkWindow *parent, const char *file_name, const char *anchor)
Launch the systems default help browser, gnome's yelp for linux, and open to a given link within a gi...
GncJob * gncOwnerGetJob(const GncOwner *owner)
If the given owner is of type GNC_OWNER_JOB, returns the pointer to the job object.
Definition gncOwner.c:376
const GncGUID * gncOwnerGetGUID(const GncOwner *owner)
Get the GncGUID of the immediate owner.
Definition gncOwner.c:518
GncOwnerType gncOwnerGetType(const GncOwner *owner)
Returns the GncOwnerType of this owner.
Definition gncOwner.c:200
void qof_query_add_guid_match(QofQuery *q, QofQueryParamList *param_list, const GncGUID *guid, QofQueryOp op)
DOCUMENT ME !!
QofQuery * qof_query_merge(QofQuery *q1, QofQuery *q2, QofQueryOp op)
Combine two queries together using the Boolean set (logical) operator 'op'.
QofQuery * qof_query_copy(QofQuery *q)
Make a copy of the indicated query.
void qof_query_set_book(QofQuery *query, QofBook *book)
Set the book to be searched.
void qof_query_destroy(QofQuery *query)
Frees the resources associate with a Query object.
void gnc_table_refresh_gui(Table *table, gboolean do_scroll)
Refresh the whole GUI from the table.
The type used to store guids in C.
Definition guid.h:75
QofBook reference.
Definition qofbook-p.hpp:47
A Query.
Definition qofquery.cpp:75