]> Dogcows Code - chaz/homebank/blob - src/hub-scheduled.c
import homebank-5.2.4
[chaz/homebank] / src / hub-scheduled.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2019 Maxime DOYEN
3 *
4 * This file is part of HomeBank.
5 *
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * HomeBank 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, see <http://www.gnu.org/licenses/>.
18 */
19
20
21 #include "homebank.h"
22
23 #include "dsp-mainwindow.h"
24 #include "list-scheduled.h"
25 #include "hub-scheduled.h"
26
27 #include "ui-transaction.h"
28
29
30 /****************************************************************************/
31 /* Debug macros */
32 /****************************************************************************/
33 #define MYDEBUG 0
34
35 #if MYDEBUG
36 #define DB(x) (x);
37 #else
38 #define DB(x);
39 #endif
40
41 /* our global datas */
42 extern struct HomeBank *GLOBALS;
43 extern struct Preferences *PREFS;
44
45 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
46 /* scheduled */
47 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
48 static Archive *
49 ui_hub_scheduled_get_selected_item(GtkTreeView *treeview)
50 {
51 GtkTreeSelection *treeselection;
52 GtkTreeModel *model;
53 GtkTreeIter iter;
54
55 treeselection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
56 if( gtk_tree_selection_get_selected(treeselection, &model, &iter) )
57 {
58 Archive *arc;
59
60 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, LST_DSPUPC_DATAS, &arc, -1);
61 return arc;
62 }
63
64 return NULL;
65 }
66
67
68 static void ui_hub_scheduled_onRowActivated (GtkTreeView *treeview,
69 GtkTreePath *path,
70 GtkTreeViewColumn *col,
71 gpointer userdata)
72 {
73 //struct hbfile_data *data;
74 Archive *arc;
75
76 DB( g_print ("\n[hub-scheduled] row double-clicked\n") );
77
78 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(treeview, GTK_TYPE_WINDOW)), "inst_data");
79
80 arc = ui_hub_scheduled_get_selected_item(treeview);
81 ui_mainwindow_defarchive(arc);
82 }
83
84
85 static void ui_hub_scheduled_do_post(Archive *arc, gboolean doedit, gpointer user_data)
86 {
87 struct hbfile_data *data = user_data;
88 GtkWidget *window;
89 gint result;
90 Transaction *txn;
91
92 DB( g_print("\n[hub-scheduled] do post\n") );
93
94
95 window = create_deftransaction_window(GTK_WINDOW(data->window), TRANSACTION_EDIT_ADD, TRUE, 0);
96
97 /* fill in the transaction */
98 txn = da_transaction_malloc();
99 da_transaction_init_from_template(txn, arc);
100 txn->date = scheduled_get_postdate(arc, arc->nextdate);
101
102 deftransaction_set_transaction(window, txn);
103
104 result = gtk_dialog_run (GTK_DIALOG (window));
105
106 DB( g_print(" - dialog result is %d\n", result) );
107
108 if(result == HB_RESPONSE_ADD || result == GTK_RESPONSE_ACCEPT)
109 {
110 deftransaction_get(window, NULL);
111 transaction_add(GTK_WINDOW(GLOBALS->mainwindow), txn);
112 GLOBALS->changes_count++;
113
114 scheduled_date_advance(arc);
115
116 DB( g_print(" - added 1 transaction to %d\n", txn->kacc) );
117 }
118
119 da_transaction_free(txn);
120
121 deftransaction_dispose(window, NULL);
122 gtk_widget_destroy (window);
123
124 }
125
126
127 static void ui_hub_scheduled_editpost_cb(GtkWidget *widget, gpointer user_data)
128 {
129 struct hbfile_data *data = user_data;
130
131 DB( g_print("\n[hub-scheduled] editpost\n") );
132
133 Archive *arc = ui_hub_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
134
135 if( (arc != NULL) )
136 {
137 ui_hub_scheduled_do_post(arc, TRUE, data);
138 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE|UF_REFRESHALL));
139 }
140 }
141
142
143 static void ui_hub_scheduled_post_cb(GtkWidget *widget, gpointer user_data)
144 {
145 struct hbfile_data *data = user_data;
146
147 DB( g_print("\n[hub-scheduled] post\n") );
148
149 Archive *arc = ui_hub_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
150
151 if( (arc != NULL) )
152 {
153 if( scheduled_is_postable(arc) )
154 {
155 Transaction *txn = da_transaction_malloc ();
156
157 da_transaction_init_from_template(txn, arc);
158 txn->date = scheduled_get_postdate(arc, arc->nextdate);
159 transaction_add(GTK_WINDOW(GLOBALS->mainwindow), txn);
160
161 GLOBALS->changes_count++;
162 scheduled_date_advance(arc);
163
164 da_transaction_free (txn);
165 }
166 else
167 {
168 ui_hub_scheduled_do_post(arc, FALSE, data);
169 }
170
171 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE|UF_REFRESHALL));
172 }
173 }
174
175
176 static void ui_hub_scheduled_skip_cb(GtkWidget *widget, gpointer user_data)
177 {
178 struct hbfile_data *data = user_data;
179
180 DB( g_print("\n[hub-scheduled] skip\n") );
181
182 Archive *arc = ui_hub_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
183 if( (arc != NULL) && (arc->flags & OF_AUTO) )
184 {
185 GLOBALS->changes_count++;
186 scheduled_date_advance(arc);
187
188 ui_hub_scheduled_populate(GLOBALS->mainwindow, NULL);
189 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE));
190 }
191 }
192
193
194
195 static void ui_hub_scheduled_update(GtkWidget *widget, gpointer user_data)
196 {
197 struct hbfile_data *data;
198 //gint filter;
199
200 DB( g_print("\n[hub-scheduled] update\n") );
201
202 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
203
204 //filter = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_sched_filter));
205
206 Archive *arc = ui_hub_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
207
208 if(arc)
209 {
210 DB( g_print("archive is %s\n", arc->memo) );
211
212 gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_skip), TRUE);
213 gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_post), TRUE);
214 gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_editpost), TRUE);
215 }
216 else
217 {
218 gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_skip), FALSE);
219 gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_post), FALSE);
220 gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_editpost), FALSE);
221 }
222
223 }
224
225
226
227 static void ui_hub_scheduled_selection_cb(GtkTreeSelection *treeselection, gpointer user_data)
228 {
229 ui_hub_scheduled_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection)), GINT_TO_POINTER(UF_SENSITIVE));
230 }
231
232
233
234 /*
235 ** called after load, importamiga, on demand
236 */
237 void ui_hub_scheduled_postall(GtkWidget *widget, gpointer user_data)
238 {
239 //struct hbfile_data *data;
240 gint count;
241 gint usermode = GPOINTER_TO_INT(user_data);
242
243 DB( g_print("\n[hub-scheduled] post all\n") );
244
245 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
246
247 count = scheduled_post_all_pending();
248
249 //inform the user
250 if(usermode == TRUE)
251 {
252 gchar *txt;
253
254 //#125534
255 if( count > 0 )
256 {
257 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_REFRESHALL));
258 }
259
260 if(count == 0)
261 txt = _("No transaction to add");
262 else
263 txt = _("transaction added: %d");
264
265 ui_dialog_msg_infoerror(GTK_WINDOW(GLOBALS->mainwindow), GTK_MESSAGE_INFO,
266 _("Check scheduled transactions result"),
267 txt,
268 count);
269 }
270
271 }
272
273
274 void ui_hub_scheduled_populate(GtkWidget *widget, gpointer user_data)
275 {
276 struct hbfile_data *data;
277 GtkTreeModel *model;
278 GtkTreeIter iter;
279 GList *list;
280 gdouble totexp = 0;
281 gdouble totinc = 0;
282 gint count = 0;
283 gchar buffer[256];
284 guint32 maxpostdate;
285 GDate *date;
286 //Account *acc;
287
288 DB( g_print("\n[hub-scheduled] populate\n") );
289
290 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
291
292 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_upc));
293 gtk_list_store_clear (GTK_LIST_STORE(model));
294
295 homebank_app_date_get_julian();
296
297 maxpostdate = scheduled_date_get_post_max();
298
299 date = g_date_new_julian (maxpostdate);
300 g_date_strftime (buffer, 256-1, PREFS->date_format, date);
301 g_date_free(date);
302
303 gtk_label_set_text(GTK_LABEL(data->LB_maxpostdate), buffer);
304
305
306 list = g_list_first(GLOBALS->arc_list);
307 while (list != NULL)
308 {
309 Archive *arc = list->data;
310 Account *acc;
311 gdouble inc, exp;
312 guint nbdays, nblate;
313
314 if((arc->flags & OF_AUTO) ) //&& arc->kacc > 0)
315 {
316 count++;
317 nbdays = arc->nextdate - maxpostdate;
318 nblate = scheduled_get_latepost_count(arc, GLOBALS->today);
319
320 DB( g_print(" - append '%s' : %d\n", arc->memo, nbdays) );
321
322 if(arc->flags & OF_INCOME)
323 {
324 inc = arc->amount;
325 exp = 0.0;
326 }
327 else
328 {
329 exp = arc->amount;
330 inc = 0.0;
331 }
332
333 /* insert normal txn */
334 acc = da_acc_get(arc->kacc);
335 if( acc)
336 {
337 totinc += hb_amount_base(inc, acc->kcur);
338 totexp += hb_amount_base(exp, acc->kcur);
339 }
340 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
341 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
342 LST_DSPUPC_DATAS, arc,
343 LST_DSPUPC_NEXT, nbdays,
344 LST_DSPUPC_ACCOUNT, acc,
345 LST_DSPUPC_MEMO, arc->memo,
346 LST_DSPUPC_EXPENSE, exp,
347 LST_DSPUPC_INCOME, inc,
348 LST_DSPUPC_NB_LATE, nblate,
349 -1);
350
351 /* insert internal xfer txn : 1378836 */
352 if(arc->paymode == PAYMODE_INTXFER)
353 {
354 acc = da_acc_get(arc->kxferacc);
355 if( acc)
356 {
357 totinc += hb_amount_base(-inc, acc->kcur);
358 totexp += hb_amount_base(-exp, acc->kcur);
359 }
360 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
361 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
362 LST_DSPUPC_DATAS, arc,
363 LST_DSPUPC_NEXT, nbdays,
364 LST_DSPUPC_ACCOUNT, acc,
365 LST_DSPUPC_MEMO, arc->memo,
366 LST_DSPUPC_EXPENSE, -inc,
367 LST_DSPUPC_INCOME, -exp,
368 LST_DSPUPC_NB_LATE, nblate,
369 -1);
370 }
371
372 }
373 list = g_list_next(list);
374 }
375
376 // insert total
377 if(count > 0 )
378 {
379 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
380 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
381 LST_DSPUPC_DATAS, NULL,
382 LST_DSPUPC_ACCOUNT, NULL,
383 LST_DSPUPC_MEMO, _("Total"),
384 LST_DSPUPC_EXPENSE, totexp,
385 LST_DSPUPC_INCOME, totinc,
386 -1);
387 }
388
389 ui_hub_scheduled_update(widget, NULL);
390
391 }
392
393
394 GtkWidget *ui_hub_scheduled_create(struct hbfile_data *data)
395 {
396 GtkWidget *hub, *hbox, *vbox, *bbox, *sw, *tbar;
397 GtkWidget *label, *widget;
398 GtkToolItem *toolitem;
399
400 DB( g_print("\n[hub-scheduled] create\n") );
401
402 hub = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
403 gtk_container_set_border_width(GTK_CONTAINER(hub), SPACING_SMALL);
404 //data->GR_upc = hub;
405
406 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
407 //gtk_widget_set_margin_top(GTK_WIDGET(vbox), 0);
408 //gtk_widget_set_margin_bottom(GTK_WIDGET(vbox), SPACING_SMALL);
409 //gtk_widget_set_margin_start(GTK_WIDGET(vbox), 2*SPACING_SMALL);
410 //gtk_widget_set_margin_end(GTK_WIDGET(vbox), SPACING_SMALL);
411 gtk_box_pack_start (GTK_BOX (hub), vbox, TRUE, TRUE, 0);
412
413 sw = gtk_scrolled_window_new (NULL, NULL);
414 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_ETCHED_IN);
415 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
416 gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
417
418 widget = (GtkWidget *)create_list_upcoming();
419 data->LV_upc = widget;
420 gtk_container_add (GTK_CONTAINER (sw), widget);
421
422 tbar = gtk_toolbar_new();
423 gtk_toolbar_set_icon_size (GTK_TOOLBAR(tbar), GTK_ICON_SIZE_MENU);
424 gtk_toolbar_set_style(GTK_TOOLBAR(tbar), GTK_TOOLBAR_ICONS);
425 gtk_style_context_add_class (gtk_widget_get_style_context (tbar), GTK_STYLE_CLASS_INLINE_TOOLBAR);
426 gtk_box_pack_start (GTK_BOX (vbox), tbar, FALSE, FALSE, 0);
427
428 label = make_label_group(_("Scheduled transactions"));
429 toolitem = gtk_tool_item_new();
430 gtk_container_add (GTK_CONTAINER(toolitem), label);
431 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
432
433 toolitem = gtk_separator_tool_item_new ();
434 gtk_tool_item_set_expand (toolitem, FALSE);
435 gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
436 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
437
438
439 bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
440 toolitem = gtk_tool_item_new();
441 gtk_container_add (GTK_CONTAINER(toolitem), bbox);
442 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
443
444 widget = gtk_button_new_with_label(_("Skip"));
445 data->BT_sched_skip = widget;
446 gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
447
448 widget = gtk_button_new_with_label(_("Edit & Post"));
449 data->BT_sched_editpost = widget;
450 gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
451
452 //TRANSLATORS: Posting a scheduled transaction is the action to materialize it into its target account.
453 //TRANSLATORS: Before that action the automated transaction occurrence is pending and not yet really existing.
454 widget = gtk_button_new_with_label (_("Post"));
455 data->BT_sched_post = widget;
456 gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
457
458 toolitem = gtk_separator_tool_item_new ();
459 gtk_tool_item_set_expand (toolitem, FALSE);
460 gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
461 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
462
463 hbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
464 gtk_widget_set_valign (hbox, GTK_ALIGN_CENTER);
465 toolitem = gtk_tool_item_new();
466 gtk_container_add (GTK_CONTAINER(toolitem), hbox);
467 gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
468
469 label = make_label(_("maximum post date"), 0.0, 0.7);
470 gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
471 gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, -1);
472 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
473
474 label = make_label(NULL, 0.0, 0.7);
475 data->LB_maxpostdate = label;
476 gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
477 gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, -1);
478 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
479
480
481 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_upc)), "changed", G_CALLBACK (ui_hub_scheduled_selection_cb), NULL);
482 g_signal_connect (GTK_TREE_VIEW(data->LV_upc), "row-activated", G_CALLBACK (ui_hub_scheduled_onRowActivated), NULL);
483 g_signal_connect (G_OBJECT (data->BT_sched_skip), "clicked", G_CALLBACK (ui_hub_scheduled_skip_cb), data);
484 g_signal_connect (G_OBJECT (data->BT_sched_editpost), "clicked", G_CALLBACK (ui_hub_scheduled_editpost_cb), data);
485 g_signal_connect (G_OBJECT (data->BT_sched_post), "clicked", G_CALLBACK (ui_hub_scheduled_post_cb), data);
486
487
488
489 return hub;
490 }
This page took 0.054754 seconds and 4 git commands to generate.