Branch data Line data Source code
1 : : /********************************************************************\
2 : : * assistant-acct-period.c - accounting period assistant for GnuCash*
3 : : * Copyright (C) 2001 Gnumatic, Inc. *
4 : : * Copyright (C) 2001 Dave Peticolas <dave@krondo.com> *
5 : : * Copyright (C) 2003 Linas Vepstas <linas@linas.org> *
6 : : * Copyright (C) 2011 Robert Fewell *
7 : : * *
8 : : * This program is free software; you can redistribute it and/or *
9 : : * modify it under the terms of the GNU General Public License as *
10 : : * published by the Free Software Foundation; either version 2 of *
11 : : * the License, or (at your option) any later version. *
12 : : * *
13 : : * This program is distributed in the hope that it will be useful, *
14 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 : : * GNU General Public License for more details. *
17 : : * *
18 : : * You should have received a copy of the GNU General Public License*
19 : : * along with this program; if not, contact: *
20 : : * *
21 : : * Free Software Foundation Voice: +1-617-542-5942 *
22 : : * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
23 : : * Boston, MA 02110-1301, USA gnu@gnu.org *
24 : : \********************************************************************/
25 : : /*************************************************************************\
26 : : * This is still a work in progress so may damage your data, to enable *
27 : : * for testing do the following :- *
28 : : * Add a define entry to gnc-plugin-basic-commands.c as below *
29 : : * #define CLOSE_BOOKS_ACTUALLY_WORKS 1 *
30 : : * *
31 : : * Add the following to gnc-plugin-basic-commands-ui.xml on line 43 *
32 : : * <menuitem name="ActionsCloseBooks" action="ActionsCloseBooksAction"/> *
33 : : \*************************************************************************/
34 : :
35 : : #include <config.h>
36 : :
37 : : #include <gtk/gtk.h>
38 : : #include <glib/gi18n.h>
39 : :
40 : : #include "Recurrence.h"
41 : : #include "Query.h"
42 : : #include "Scrub.h"
43 : : #include "Transaction.h"
44 : : #include "dialog-utils.h"
45 : : #include "assistant-acct-period.h"
46 : : #include "gnc-component-manager.h"
47 : : #include "qof.h"
48 : : #include "gnc-date.h"
49 : : #include "gnc-file.h"
50 : : #include "gnc-frequency.h"
51 : : #include "gnc-gui-query.h"
52 : : #include "gnc-ui-util.h"
53 : : #include "misc-gnome-utils.h"
54 : : #include "gnc-session.h"
55 : :
56 : : #define ASSISTANT_ACCT_PERIOD_CM_CLASS "assistant-acct-period"
57 : :
58 : : static QofLogModule log_module = GNC_MOD_ASSISTANT;
59 : :
60 : : /** structures *********************************************************/
61 : : typedef struct
62 : : {
63 : : GtkWidget * window;
64 : : GtkWidget * assistant;
65 : : GncFrequency *period_menu;
66 : : GtkWidget * period_remarks;
67 : : GtkWidget * close_results;
68 : : GtkWidget * book_details;
69 : : GtkWidget * book_title;
70 : : GtkTextView * book_notes;
71 : : GtkWidget * apply_label;
72 : : GtkWidget * summary;
73 : :
74 : : time64 earliest;
75 : : char * earliest_str;
76 : : GDate closing_date;
77 : : GDate prev_closing_date;
78 : : GList *period;
79 : : int close_status;
80 : :
81 : : } AcctPeriodInfo;
82 : :
83 : : /* =============================================================== */
84 : :
85 : : void ap_assistant_prepare (GtkAssistant *assistant, GtkWidget *page,
86 : : gpointer user_data);
87 : : void ap_assistant_menu_prepare (GtkAssistant *assistant, gpointer user_data);
88 : : void ap_assistant_book_prepare (GtkAssistant *assistant, gpointer user_data);
89 : : void ap_assistant_apply_prepare (GtkAssistant *assistant, gpointer user_data);
90 : : void ap_assistant_summary_prepare (GtkAssistant *assistant, gpointer user_data);
91 : :
92 : : gboolean ap_validate_menu (GtkAssistant *assistant, gpointer user_data);
93 : :
94 : : void ap_assistant_finish (GtkAssistant *gtkassistant, gpointer user_data);
95 : : void ap_assistant_cancel (GtkAssistant *gtkassistant, gpointer user_data);
96 : : void ap_assistant_close (GtkAssistant *gtkassistant, gpointer user_data);
97 : :
98 : : /* =============================================================== */
99 : : /* Find the earliest date occurring in the book. Do this by making
100 : : * a query and sorting by date. Since the truncated sort returns
101 : : * only the *last* search results, sort in decreasing order.
102 : : */
103 : : static time64
104 : 0 : get_earliest_in_book (QofBook *book)
105 : : {
106 : : QofQuery *q;
107 : : GSList *p1, *p2;
108 : : GList *res;
109 : : time64 earliest;
110 : :
111 : 0 : q = qof_query_create_for(GNC_ID_SPLIT);
112 : 0 : qof_query_set_max_results(q, 1);
113 : 0 : qof_query_set_book (q, book);
114 : :
115 : : /* Sort by transaction date */
116 : 0 : p1 = g_slist_prepend (NULL, TRANS_DATE_POSTED);
117 : 0 : p1 = g_slist_prepend (p1, SPLIT_TRANS);
118 : 0 : p2 = g_slist_prepend (NULL, QUERY_DEFAULT_SORT);
119 : 0 : qof_query_set_sort_order (q, p1, p2, NULL);
120 : :
121 : : /* Reverse the sort order */
122 : 0 : qof_query_set_sort_increasing (q, FALSE, FALSE, FALSE);
123 : :
124 : : /* Run the query, find the earliest transaction date */
125 : 0 : res = qof_query_run (q);
126 : :
127 : 0 : if (res)
128 : : {
129 : 0 : earliest = xaccQueryGetEarliestDateFound (q);
130 : : }
131 : : else
132 : : {
133 : : /* If no results, we don't want to bomb totally */
134 : 0 : earliest = gnc_time (NULL);
135 : : }
136 : :
137 : 0 : qof_query_destroy (q);
138 : 0 : return earliest;
139 : : }
140 : :
141 : : /* =============================================================== */
142 : : /* Find the number of transactions occurring before the indicated date.
143 : : * Do this by making a query and counting the results.
144 : : */
145 : :
146 : : static int
147 : 0 : get_num_xactions_before_date(QofBook *book, time64 close_date)
148 : : {
149 : : QofQuery *q;
150 : : GSList *param;
151 : : QofQueryPredData *pred;
152 : : GList *res, *n;
153 : 0 : int cnt = 0;
154 : :
155 : 0 : q = qof_query_create_for(GNC_ID_TRANS);
156 : 0 : qof_query_set_max_results(q, -1);
157 : 0 : qof_query_set_book (q, book);
158 : :
159 : : /* Look for transactions earlier than the closing date */
160 : 0 : param = g_slist_prepend (NULL, TRANS_DATE_POSTED);
161 : 0 : pred = qof_query_date_predicate (QOF_COMPARE_LTE, QOF_DATE_MATCH_NORMAL, close_date);
162 : 0 : qof_query_add_term (q, param, pred, QOF_QUERY_FIRST_TERM);
163 : :
164 : : /* Run the query, find how many transactions there are */
165 : 0 : res = qof_query_run (q);
166 : :
167 : 0 : cnt = 0;
168 : 0 : for (n = res; n; n = n->next) cnt ++;
169 : :
170 : 0 : qof_query_destroy (q);
171 : 0 : return cnt;
172 : : }
173 : :
174 : : /* =============================================================== */
175 : :
176 : : static const char *
177 : 0 : get_close_status_str (AcctPeriodInfo *info)
178 : : {
179 : : const char * str;
180 : :
181 : : /* Tell user about how the previous book closing went. */
182 : 0 : switch (info->close_status)
183 : : {
184 : 0 : case -1:
185 : 0 : str = "";
186 : 0 : break;
187 : 0 : case 0:
188 : 0 : str = _("The book was closed successfully.");
189 : 0 : break;
190 : 0 : default:
191 : 0 : str = "";
192 : 0 : break;
193 : : }
194 : 0 : return str;
195 : : }
196 : :
197 : : /* =============================================================== */
198 : :
199 : : static void
200 : 0 : ap_assistant_destroy_cb (GtkWidget *object, gpointer data)
201 : : {
202 : 0 : AcctPeriodInfo *info = data;
203 : :
204 : 0 : gnc_unregister_gui_component_by_data (ASSISTANT_ACCT_PERIOD_CM_CLASS, info);
205 : :
206 : : // do we need gnc_frequency_destroy or is this automatic ??
207 : 0 : recurrenceListFree(&info->period);
208 : 0 : g_free (info->earliest_str);
209 : 0 : g_free (info);
210 : 0 : }
211 : :
212 : : /* =============================================================== */
213 : :
214 : : void
215 : 0 : ap_assistant_cancel (GtkAssistant *assistant, gpointer user_data)
216 : : {
217 : 0 : AcctPeriodInfo *info = user_data;
218 : 0 : gnc_close_gui_component_by_data (ASSISTANT_ACCT_PERIOD_CM_CLASS, info);
219 : 0 : }
220 : :
221 : : /* =============================================================== */
222 : :
223 : : void
224 : 0 : ap_assistant_close (GtkAssistant *assistant, gpointer user_data)
225 : : {
226 : 0 : AcctPeriodInfo *info = user_data;
227 : 0 : gnc_close_gui_component_by_data (ASSISTANT_ACCT_PERIOD_CM_CLASS, info);
228 : 0 : }
229 : :
230 : : /* =============================================================== */
231 : :
232 : : void
233 : 0 : ap_assistant_prepare (GtkAssistant *assistant, GtkWidget *page,
234 : : gpointer user_data)
235 : : {
236 : 0 : gint currentpage = gtk_assistant_get_current_page(assistant);
237 : :
238 : 0 : switch (currentpage)
239 : : {
240 : 0 : case 1:
241 : : /* Current page is Menu page */
242 : 0 : ap_assistant_menu_prepare(assistant, user_data);
243 : 0 : break;
244 : 0 : case 2:
245 : : /* Current page is Book page */
246 : 0 : ap_assistant_book_prepare (assistant, user_data);
247 : 0 : break;
248 : 0 : case 3:
249 : : /* Current page is Apply page */
250 : 0 : ap_assistant_apply_prepare (assistant, user_data);
251 : 0 : break;
252 : 0 : case 4:
253 : : /* Current page is Summary page */
254 : 0 : ap_assistant_summary_prepare (assistant, user_data);
255 : 0 : break;
256 : : }
257 : 0 : }
258 : :
259 : : /* =============================================================== */
260 : :
261 : : void
262 : 0 : ap_assistant_menu_prepare (GtkAssistant *assistant, gpointer user_data)
263 : : {
264 : : int nperiods;
265 : : GDate period_begin, period_end, date_now;
266 : : char *str, *earliest_str;
267 : :
268 : 0 : AcctPeriodInfo *info = user_data;
269 : :
270 : 0 : ENTER ("info=%p", info);
271 : :
272 : : /* Pull info from widget, push into freq spec */
273 : : //gnc_frequency_save_state (info->period_menu, info->period, &info->closing_date);
274 : 0 : recurrenceListFree(&info->period);
275 : 0 : gnc_frequency_save_to_recurrence(info->period_menu, &info->period, &info->closing_date);
276 : :
277 : : /* Count the number of periods that would be generated. */
278 : 0 : g_date_clear (&period_begin, 1);
279 : 0 : g_date_clear (&period_end, 1);
280 : 0 : g_date_clear (&date_now, 1);
281 : 0 : nperiods = 0;
282 : 0 : period_end = info->closing_date;
283 : 0 : gnc_gdate_set_time64 (&date_now, gnc_time (NULL));
284 : :
285 : 0 : while (0 > g_date_compare(&period_end, &date_now ))
286 : : {
287 : 0 : nperiods ++;
288 : 0 : PINFO ("Period = %d and End date is %d/%d/%d", nperiods,
289 : : g_date_get_month(&period_end),
290 : : g_date_get_day(&period_end),
291 : : g_date_get_year(&period_end));
292 : 0 : period_begin = period_end;
293 : 0 : recurrenceListNextInstance(info->period, &period_begin, &period_end);
294 : :
295 : : /* FIXME Check for valid period_end, not sure why it won't be!!! */
296 : 0 : if (g_date_valid (&period_end) != TRUE)
297 : 0 : break;
298 : : }
299 : :
300 : : /* Find the date of the earliest transaction in the current book.
301 : : * Note that this could have changed since last time, since
302 : : * we may have closed books since last time. */
303 : 0 : info->earliest = get_earliest_in_book (gnc_get_current_book());
304 : 0 : info->earliest_str = qof_print_date(info->earliest);
305 : 0 : earliest_str = gnc_ctime (&info->earliest);
306 : 0 : PINFO ("Date of earliest transaction is %" G_GINT64_FORMAT " %s",
307 : : info->earliest, earliest_str);
308 : 0 : g_free (earliest_str);
309 : :
310 : : /* Display the results */
311 : 0 : str = g_strdup_printf (
312 : : /* Translators: %s is a date string. %d is the number of books
313 : : that will be created. This is a ngettext(3) message (but
314 : : only for the %d part). */
315 : 0 : ngettext("The earliest transaction date found in this book is %s. "
316 : : "Based on the selection made above, this book will be split "
317 : : "into %d book.",
318 : : "The earliest transaction date found in this book is %s. "
319 : : "Based on the selection made above, this book will be split "
320 : : "into %d books.",
321 : : nperiods),
322 : : info->earliest_str,
323 : : nperiods);
324 : 0 : gtk_label_set_text (GTK_LABEL(info->period_remarks), str);
325 : 0 : g_free (str);
326 : 0 : }
327 : :
328 : : /* =============================================================== */
329 : :
330 : : void
331 : 0 : ap_assistant_book_prepare (GtkAssistant *assistant, gpointer user_data)
332 : : {
333 : : QofBook *currbook;
334 : : char close_date_str[MAX_DATE_LENGTH];
335 : : char prev_close_date_str[MAX_DATE_LENGTH];
336 : : const char *period_text;
337 : : char *str;
338 : : const char *cstr;
339 : : int ntrans, nacc;
340 : : GtkTextBuffer *buffer;
341 : :
342 : 0 : AcctPeriodInfo *info = user_data;
343 : :
344 : 0 : ENTER ("info=%p", info);
345 : :
346 : : /* Tell user about how the previous book closing went. */
347 : 0 : cstr = get_close_status_str (info);
348 : 0 : gtk_label_set_text (GTK_LABEL(info->close_results), cstr);
349 : 0 : info->close_status = -1;
350 : :
351 : : /* Pull info from widget, push into freq spec */
352 : : //gnc_frequency_save_state (info->period_menu, info->period, &info->closing_date);
353 : 0 : recurrenceListFree(&info->period);
354 : 0 : gnc_frequency_save_to_recurrence(info->period_menu, &info->period, &info->closing_date);
355 : :
356 : 0 : qof_print_date_dmy_buff (close_date_str, MAX_DATE_LENGTH,
357 : 0 : g_date_get_day(&info->closing_date),
358 : 0 : g_date_get_month(&info->closing_date),
359 : 0 : g_date_get_year(&info->closing_date));
360 : :
361 : 0 : currbook = gnc_get_current_book();
362 : 0 : ntrans = get_num_xactions_before_date(currbook,
363 : 0 : gnc_time64_get_day_end_gdate (&info->closing_date));
364 : :
365 : 0 : nacc = gnc_account_n_descendants (gnc_book_get_root_account (currbook));
366 : :
367 : : /* Display the book info */
368 : :
369 : : period_text =
370 : : /* Translators: Run the assistant in your language to see GTK's translation of the button labels. */
371 : 0 : _("You have asked for a book to be created. This book "
372 : : "will contain all transactions up to midnight %s "
373 : : "(for a total of %d transactions spread over %d accounts).\n\n"
374 : : "Amend the Title and Notes or Click on \"Next\" to proceed.\n"
375 : : "Click on \"Back\" to adjust the dates or \"Cancel\".");
376 : 0 : str = g_strdup_printf (period_text, close_date_str, ntrans, nacc);
377 : 0 : gtk_label_set_text (GTK_LABEL(info->book_details), str);
378 : 0 : g_free (str);
379 : :
380 : 0 : gtk_widget_show (GTK_WIDGET (info->book_details));
381 : :
382 : : /* Create default settings for the title, notes fields */
383 : 0 : qof_print_date_dmy_buff (prev_close_date_str, MAX_DATE_LENGTH,
384 : 0 : g_date_get_day(&info->prev_closing_date),
385 : 0 : g_date_get_month(&info->prev_closing_date),
386 : 0 : g_date_get_year(&info->prev_closing_date));
387 : :
388 : 0 : str = g_strdup_printf (_("Period %s - %s"), prev_close_date_str, close_date_str);
389 : 0 : gtk_entry_set_text (GTK_ENTRY(info->book_title), str);
390 : :
391 : 0 : buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(info->book_notes));
392 : 0 : gtk_text_buffer_set_text(buffer, str, -1);
393 : :
394 : 0 : g_free (str);
395 : 0 : }
396 : :
397 : : /* =============================================================== */
398 : :
399 : : void
400 : 0 : ap_assistant_apply_prepare (GtkAssistant *assistant, gpointer user_data)
401 : : {
402 : 0 : AcctPeriodInfo *info = user_data;
403 : : const char *btitle;
404 : : char *str;
405 : : const char *apply_text =
406 : 0 : _("The book will be created with the title %s when you "
407 : : "click on \"Apply\". Click on \"Back\" to adjust, "
408 : : "or \"Cancel\" to not create any book.");
409 : :
410 : 0 : btitle = gtk_entry_get_text (GTK_ENTRY(info->book_title));
411 : 0 : str = g_strdup_printf (apply_text, btitle);
412 : 0 : gtk_label_set_text (GTK_LABEL(info->apply_label), str);
413 : 0 : g_free (str);
414 : 0 : }
415 : :
416 : : /* =============================================================== */
417 : :
418 : : static void
419 : 0 : ap_assistant_menu_changed_cb (GtkWidget *widget, gpointer user_data)
420 : : {
421 : 0 : AcctPeriodInfo *info = user_data;
422 : 0 : GtkAssistant *assistant = GTK_ASSISTANT(info->window);
423 : 0 : gint num = gtk_assistant_get_current_page (assistant);
424 : 0 : GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
425 : :
426 : 0 : ENTER ("info=%p", info);
427 : 0 : ap_assistant_menu_prepare (assistant, info);
428 : 0 : gtk_assistant_set_page_complete (assistant, page, ap_validate_menu (assistant, user_data));
429 : 0 : }
430 : :
431 : : /* =============================================================== */
432 : :
433 : : gboolean
434 : 0 : ap_validate_menu (GtkAssistant *assistant, gpointer user_data)
435 : : {
436 : : GDate date_now;
437 : 0 : AcctPeriodInfo *info = user_data;
438 : 0 : ENTER("info=%p", info);
439 : :
440 : : /* Pull info from widget, push into freq spec */
441 : : //gnc_frequency_save_state (info->period_menu, info->period, &info->closing_date);
442 : 0 : recurrenceListFree(&info->period);
443 : 0 : gnc_frequency_save_to_recurrence(info->period_menu, &info->period, &info->closing_date);
444 : :
445 : 0 : if (0 <= g_date_compare(&info->prev_closing_date, &info->closing_date))
446 : : {
447 : : /* Closing date must be greater than closing date of previous book */
448 : 0 : return FALSE;
449 : : }
450 : :
451 : 0 : g_date_clear (&date_now, 1);
452 : 0 : gnc_gdate_set_today (&date_now);
453 : 0 : if (0 < g_date_compare(&info->closing_date, &date_now))
454 : : {
455 : : /* Closing date must be in the future */
456 : 0 : return FALSE;
457 : : }
458 : 0 : return TRUE;
459 : : }
460 : :
461 : : /* =============================================================== */
462 : :
463 : : void
464 : 0 : ap_assistant_finish (GtkAssistant *assistant, gpointer user_data)
465 : : {
466 : 0 : AcctPeriodInfo *info = user_data;
467 : : GtkTextBuffer * buffer;
468 : : GtkTextIter startiter, enditer;
469 : : gint len;
470 : : const char *btitle;
471 : : char *bnotes;
472 : :
473 : 0 : ENTER("info=%p", info);
474 : :
475 : 0 : btitle = gtk_entry_get_text (GTK_ENTRY(info->book_title));
476 : 0 : buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(info->book_notes));
477 : 0 : len = gtk_text_buffer_get_char_count (buffer);
478 : 0 : gtk_text_buffer_get_iter_at_offset(buffer, &startiter, 0);
479 : 0 : gtk_text_buffer_get_iter_at_offset(buffer, &enditer, len);
480 : :
481 : 0 : bnotes = gtk_text_buffer_get_text(buffer, &startiter, &enditer , 0);
482 : 0 : PINFO("Book title is - %s\n", btitle);
483 : :
484 : 0 : g_free(bnotes);
485 : :
486 : : /* Report the status back to the user. */
487 : 0 : info->close_status = 0; /* XXX fixme success or failure? */
488 : :
489 : : /* Find the next closing date ... */
490 : 0 : info->prev_closing_date = info->closing_date;
491 : 0 : recurrenceListNextInstance (info->period, &info->prev_closing_date,
492 : : &info->closing_date);
493 : :
494 : :
495 : : /* FIXME Test for valid closing date, not sure why it won't be!!! */
496 : 0 : if (g_date_valid(&info->closing_date) == TRUE)
497 : : {
498 : : /* If the next closing date is in the future, then we are done. */
499 : 0 : if (gnc_time (NULL) >
500 : 0 : gnc_time64_get_day_end_gdate (&info->closing_date))
501 : : {
502 : : /* Load up the GUI for the next closing period. */
503 : 0 : gnc_frequency_setup_recurrence (info->period_menu, NULL,
504 : 0 : &info->closing_date);
505 : : /* Jump back to the Close Book page. */
506 : 0 : gtk_assistant_set_current_page (GTK_ASSISTANT(info->window), 1);
507 : : }
508 : : }
509 : 0 : }
510 : :
511 : : /* =============================================================== */
512 : :
513 : : void
514 : 0 : ap_assistant_summary_prepare (GtkAssistant *assistant, gpointer user_data)
515 : : {
516 : : const char *msg;
517 : : char *str;
518 : 0 : AcctPeriodInfo *info = user_data;
519 : 0 : ENTER ("info=%p", info);
520 : :
521 : : /* Translation FIXME: Can this %s-containing message please be
522 : : replaced by one single message? Either this closing went
523 : : successfully ("success", "congratulations") or something else
524 : : should be displayed anyway. */
525 : 0 : msg = _("%s\nCongratulations! You are done closing books!\n");
526 : :
527 : 0 : str = g_strdup_printf (msg, get_close_status_str (info));
528 : 0 : gtk_label_set_text (GTK_LABEL(info->summary), str);
529 : 0 : g_free (str);
530 : :
531 : 0 : }
532 : :
533 : : /* =============================================================== */
534 : :
535 : : static GtkWidget *
536 : 0 : ap_assistant_create (AcctPeriodInfo *info)
537 : : {
538 : : GtkBuilder *builder;
539 : : GtkWidget *window;
540 : : GtkWidget *box;
541 : : gchar *earliest_str;
542 : :
543 : 0 : builder = gtk_builder_new();
544 : 0 : gnc_builder_add_from_file (builder , "assistant-acct-period.glade", "account_period_assistant");
545 : 0 : window = GTK_WIDGET(gtk_builder_get_object (builder, "account_period_assistant"));
546 : 0 : info->window = window;
547 : :
548 : : // Set the name for this assistant so it can be easily manipulated with css
549 : 0 : gtk_widget_set_name (GTK_WIDGET(window), "gnc-id-assistant-account-period");
550 : :
551 : : /* Enable all pages except menu page. */
552 : 0 : gtk_assistant_set_page_complete (GTK_ASSISTANT (window),
553 : 0 : GTK_WIDGET(gtk_builder_get_object(builder, "start_page")),
554 : : TRUE);
555 : 0 : gtk_assistant_set_page_complete (GTK_ASSISTANT (window),
556 : 0 : GTK_WIDGET(gtk_builder_get_object(builder, "book_page")),
557 : : TRUE);
558 : 0 : gtk_assistant_set_page_complete (GTK_ASSISTANT (window),
559 : 0 : GTK_WIDGET(gtk_builder_get_object(builder, "finish_page")),
560 : : TRUE);
561 : 0 : gtk_assistant_set_page_complete (GTK_ASSISTANT (window),
562 : 0 : GTK_WIDGET(gtk_builder_get_object(builder, "summary_page")),
563 : : TRUE);
564 : :
565 : 0 : info->close_status = -1;
566 : :
567 : : /* Find the date of the earliest transaction in the book.
568 : : * Add a year minus a day as the first guess for book closing,
569 : : * and use that to set up the freq spec widget. */
570 : 0 : info->earliest = get_earliest_in_book (gnc_get_current_book());
571 : 0 : info->earliest_str = qof_print_date(info->earliest);
572 : 0 : earliest_str = gnc_ctime (&info->earliest);
573 : 0 : PINFO ("date of earliest transaction is %" G_GINT64_FORMAT " %s",
574 : : info->earliest, earliest_str);
575 : 0 : g_free (earliest_str);
576 : :
577 : 0 : g_date_clear (&info->closing_date, 1);
578 : 0 : gnc_gdate_set_time64 (&info->closing_date, info->earliest);
579 : 0 : g_date_clear (&info->prev_closing_date, 1);
580 : 0 : info->prev_closing_date = info->closing_date;
581 : 0 : g_date_add_years (&info->closing_date, 1);
582 : :
583 : : {
584 : 0 : Recurrence *r = g_new0(Recurrence, 1);
585 : 0 : recurrenceSet(r, 1, PERIOD_MONTH, &info->closing_date, WEEKEND_ADJ_NONE);
586 : 0 : info->period = NULL;
587 : 0 : info->period = g_list_append(info->period, r);
588 : : }
589 : :
590 : 0 : info->period_menu = GNC_FREQUENCY(
591 : 0 : gnc_frequency_new_from_recurrence(info->period, &info->closing_date));
592 : :
593 : : /* Change the text so that its more mainingful for this assistant */
594 : 0 : gnc_frequency_set_frequency_label_text(info->period_menu, _("Period"));
595 : 0 : gnc_frequency_set_date_label_text(info->period_menu, _("Closing Date"));
596 : :
597 : : /* Reparent to the correct location */
598 : :
599 : 0 : box = GTK_WIDGET(gtk_builder_get_object(builder, "period_hbox"));
600 : 0 : gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (info->period_menu), TRUE, TRUE, 0);
601 : 0 : g_signal_connect (info->period_menu, "changed",
602 : : G_CALLBACK (ap_assistant_menu_changed_cb), info);
603 : :
604 : : /* Get handles to all of the other widgets we'll need */
605 : 0 : info->period_remarks = GTK_WIDGET(gtk_builder_get_object(builder, "remarks_label"));
606 : :
607 : 0 : info->close_results = GTK_WIDGET(gtk_builder_get_object(builder, "results_label"));
608 : :
609 : 0 : info->book_details = GTK_WIDGET(gtk_builder_get_object(builder, "book_label"));
610 : :
611 : 0 : info->book_title = GTK_WIDGET(gtk_builder_get_object(builder, "book_title_entry"));
612 : :
613 : 0 : info->book_notes = GTK_TEXT_VIEW(gtk_builder_get_object(builder, "book_notes_view"));
614 : :
615 : 0 : info->apply_label = GTK_WIDGET(gtk_builder_get_object(builder, "finish_page"));
616 : :
617 : 0 : info->summary = GTK_WIDGET(gtk_builder_get_object(builder, "summary_label"));
618 : :
619 : 0 : g_signal_connect (G_OBJECT(window), "destroy",
620 : : G_CALLBACK (ap_assistant_destroy_cb), info);
621 : :
622 : 0 : gtk_builder_connect_signals(builder, info);
623 : 0 : g_object_unref(G_OBJECT(builder));
624 : 0 : return window;
625 : : }
626 : :
627 : : /* =============================================================== */
628 : :
629 : : static void
630 : 0 : ap_close_handler (gpointer user_data)
631 : : {
632 : 0 : AcctPeriodInfo *info = user_data;
633 : :
634 : 0 : gtk_widget_destroy (info->window);
635 : 0 : }
636 : :
637 : : /********************************************************************\
638 : : * gnc_acct_period_dialog *
639 : : * opens up a assistant to configure accounting periods *
640 : : * *
641 : : * Args: none *
642 : : * Return: nothing *
643 : : \********************************************************************/
644 : :
645 : : void
646 : 0 : gnc_acct_period_dialog (void)
647 : : {
648 : : AcctPeriodInfo *info;
649 : :
650 : 0 : info = g_new0 (AcctPeriodInfo, 1);
651 : :
652 : 0 : ap_assistant_create (info);
653 : :
654 : 0 : gnc_register_gui_component (ASSISTANT_ACCT_PERIOD_CM_CLASS,
655 : : NULL, ap_close_handler, info);
656 : :
657 : 0 : gtk_widget_show_all (info->window);
658 : :
659 : 0 : gnc_window_adjust_for_screen (GTK_WINDOW(info->window));
660 : 0 : }
|