]> Dogcows Code - chaz/homebank/blobdiff - src/rep-budget.c
Merge branch 'upstream'
[chaz/homebank] / src / rep-budget.c
similarity index 91%
rename from src/rep_budget.c
rename to src/rep-budget.c
index 47048deefe45d42cafcc158a8d5284cdf06e74d6..60984e12ed28383124a02baf65b346f54ae24b81 100644 (file)
@@ -1,5 +1,5 @@
 /*  HomeBank -- Free, easy, personal accounting for everyone.
- *  Copyright (C) 1995-2018 Maxime DOYEN
+ *  Copyright (C) 1995-2019 Maxime DOYEN
  *
  *  This file is part of HomeBank.
  *
 
 #include "homebank.h"
 
-#include "rep_budget.h"
+#include "rep-budget.h"
 
-#include "list_operation.h"
-#include "gtk-chart-stack.h"
+#include "list-operation.h"
+#include "gtk-chart-progress.h"
 #include "gtk-dateentry.h"
 
-#include "dsp_mainwindow.h"
+#include "dsp-mainwindow.h"
 #include "ui-transaction.h"
 
 
@@ -67,14 +67,9 @@ static void repbudget_update_daterange(GtkWidget *widget, gpointer user_data);
 
 static GString *ui_list_repbudget_to_string(GtkTreeView *treeview, gboolean clipboard);
 
-gchar *CYA_BUDGSELECT[] = { N_("Category"), N_("Subcategory"), NULL };
 
-gchar *CYA_KIND[] = { N_("Exp. & Inc."), N_("Expense"), N_("Income"), NULL };
-
-gchar *CYA_BUDGETSELECT[] = { N_("Spent & Budget"), N_("Spent"), N_("Budget"), N_("Result"), NULL };
-
-
-//extern gchar *CYA_FLT_SELECT[];
+extern gchar *CYA_CATSUBCAT[];
+extern gchar *CYA_KIND[];
 
 
 static GtkRadioActionEntry radio_entries[] = {
@@ -85,7 +80,7 @@ static guint n_radio_entries = G_N_ELEMENTS (radio_entries);
 
 
 static GtkActionEntry entries[] = {
-  { "Refresh" , ICONNAME_REFRESH, N_("Refresh"), NULL,   N_("Refresh results"), G_CALLBACK (repbudget_action_refresh) },
+  { "Refresh" , ICONNAME_HB_REFRESH, N_("Refresh"), NULL,   N_("Refresh results"), G_CALLBACK (repbudget_action_refresh) },
 
 //  { "Export"  , ICONNAME_HB_FILE_EXPORT , N_("Export")  , NULL,   N_("Export as CSV"), G_CALLBACK (repbudget_action_export) },
 };
@@ -432,7 +427,7 @@ gint tmpfor;
        //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
 
        tmpfor  = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_for));
-       name = g_strdup_printf("hb-repbudget_%s.csv", CYA_BUDGSELECT[tmpfor]);
+       name = g_strdup_printf("hb-repbudget_%s.csv", CYA_CATSUBCAT[tmpfor]);
 
        if( ui_file_chooser_csv(GTK_WINDOW(data->window), GTK_FILE_CHOOSER_ACTION_SAVE, &filename, name) == TRUE )
        {
@@ -486,7 +481,7 @@ gint tmpfor;
        //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
 
        tmpfor  = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_for));
-       name = g_strdup_printf("hb-repstat-detail_%s.csv", CYA_BUDGSELECT[tmpfor]);
+       name = g_strdup_printf("hb-repstat-detail_%s.csv", CYA_CATSUBCAT[tmpfor]);
 
        if( ui_file_chooser_csv(GTK_WINDOW(data->window), GTK_FILE_CHOOSER_ACTION_SAVE, &filename, name) == TRUE )
        {
@@ -554,13 +549,13 @@ GtkTreeIter  iter;
                        //filter here
                        if( ope->flags & OF_SPLIT )
                        {
-                       guint nbsplit = da_splits_count(ope->splits);
+                       guint nbsplit = da_splits_length(ope->splits);
                        Split *split;
                        guint i;
                        
                                for(i=0;i<nbsplit;i++)
                                {
-                                       split = ope->splits[i];
+                                       split = da_splits_get(ope->splits, i);
                                        switch(tmpfor)
                                        {
                                                case BUDG_CATEGORY:
@@ -625,6 +620,27 @@ next1:
 }
 
 
+static void repbudget_compute_cat_spent(guint32 key, gdouble amount, gdouble *tmp_spent, gdouble *tmp_budget)
+{
+Category *cat;
+
+       cat = da_cat_get(key);
+       if(cat)
+       {
+               DB( g_print(" -> affecting %.2f to cat %d sub=%d, bud=%.2f\n", amount, cat->key, (cat->flags & GF_SUB), tmp_budget[cat->key]) );
+               if( (cat->flags & GF_FORCED) || (cat->flags & GF_BUDGET) )
+                       tmp_spent[cat->key] += amount;
+               //#1814213 only count subcat with budget
+               //if( (cat->flags & GF_SUB) )
+               if( (cat->flags & GF_FORCED) || ((cat->flags & GF_SUB) && (cat->flags & GF_BUDGET)) )
+               {
+                       DB( g_print(" -> affecting %.2f to parent %d, bud=%.2f\n", amount, cat->parent, tmp_budget[cat->parent]) );
+                       tmp_spent[cat->parent] += amount;
+               }
+       }                               
+}
+
+
 static void repbudget_compute(GtkWidget *widget, gpointer user_data)
 {
 struct repbudget_data *data;
@@ -637,6 +653,7 @@ GtkTreeIter  iter;
 GList *list;
 guint n_result, id;
 gdouble *tmp_spent, *tmp_budget;
+gboolean *tmp_hassub;
 gint nbmonth = 1;
 gchar *title;
 
@@ -655,7 +672,6 @@ gchar *title;
        g_queue_free (data->txn_queue);
        data->txn_queue = hbfile_transaction_get_partial_budget(data->filter->mindate, data->filter->maxdate);
 
-
        DB( g_print(" for=%d, kind=%d\n", tmpfor, tmpkind) );
 
        nbmonth = countmonth(mindate, maxdate);
@@ -667,8 +683,9 @@ gchar *title;
        /* allocate some memory */
        tmp_spent  = g_malloc0((n_result+1) * sizeof(gdouble));
        tmp_budget = g_malloc0((n_result+1) * sizeof(gdouble));
+       tmp_hassub = g_malloc0((n_result+1) * sizeof(gboolean));
 
-       if(tmp_spent && tmp_budget)
+       if(tmp_spent && tmp_budget && tmp_hassub)
        {
        guint i = 0;
                /* compute the results */
@@ -682,8 +699,6 @@ gchar *title;
                for(i=1; i<=n_result; i++)
                {
                Category *entry;
-               //gchar buffer[128];
-               gint pos;
 
                        entry = da_cat_get(i);
                        if( entry == NULL)
@@ -693,34 +708,24 @@ gchar *title;
                                entry->key, entry->name, (entry->flags & GF_SUB), (entry->flags & GF_BUDGET), (entry->flags & GF_CUSTOM)) );
 
                        //debug
-                       #if MYDEBUG == 1
+                       /*#if MYDEBUG == 1
                        gint k;
                        g_print("    budget vector: ");
                        for(k=0;k<13;k++)
                                g_print( " %d:[%.2f]", k, entry->budget[k]);
                        g_print("\n");
-                       #endif
-
-                       pos = 0;
-                       switch(tmpfor)
-                       {
-                               case BUDG_CATEGORY:
-                                       {
-                                       Category *catentry = da_cat_get(i);
-                                               if(catentry)
-                                                       pos = (catentry->flags & GF_SUB) ? catentry->parent : catentry->key;
-                                       }
-                                       break;
-                               case BUDG_SUBCATEGORY:
-                                       pos = i;
-                                       break;
-                       }
+                       #endif*/
 
                        // same value each month ?
                        if(!(entry->flags & GF_CUSTOM))
                        {
                                DB( g_print("    - monthly %.2f\n", entry->budget[0]) );
-                               tmp_budget[pos] += entry->budget[0]*nbmonth;
+                               tmp_budget[entry->key] += entry->budget[0]*nbmonth;
+                               if( entry->flags & GF_SUB )
+                               {
+                                       tmp_budget[entry->parent] += entry->budget[0]*nbmonth;
+                                       tmp_hassub[entry->parent] = TRUE;
+                               }
                        }
                        //otherwise     sum each month from mindate month
                        else
@@ -731,88 +736,43 @@ gchar *title;
                                DB( g_print("    - custom each month for %d months\n", nbmonth) );
                                for(j=0;j<nbmonth;j++) {
                                        DB( g_print("      j=%d month=%d budg=%.2f\n", j, month, entry->budget[month]) );
-                                       tmp_budget[pos] += entry->budget[month];
-                                       month++;
-                                       if(month > 12) {
-                                               month = 1;
+                                       tmp_budget[entry->key] += entry->budget[month];
+                                       if( entry->flags & GF_SUB )
+                                       {
+                                               tmp_budget[entry->parent] += entry->budget[month];
+                                               tmp_hassub[entry->parent] = TRUE;
                                        }
+                                       month++;
+                                       if(month > 12) { month = 1; }
                                }
                        }
-
-                       //debug
-                       #if MYDEBUG == 1
-                       g_print("    final budget: %d:'%s' : budg[%d]=%.2f\n", entry->key, entry->name, pos, tmp_budget[pos] );
-                       #endif
                }
 
 
                // compute spent for each transaction */
                DB( g_print("\n+ compute spent from transactions\n") );
 
-
                list = g_queue_peek_head_link(data->txn_queue);
                while (list != NULL)
                {
                Transaction *ope = list->data;
-               gint pos = 0;
-               gdouble trn_amount;
 
-                       //DB( g_print("%d, get ope: %s :: acc=%d, cat=%d, mnt=%.2f\n", i, ope->memo, ope->account, ope->category, ope->amount) );
+                       DB( g_print("%d, get ope: %s :: acc=%d, cat=%d, mnt=%.2f\n", i, ope->memo, ope->kacc, ope->kcat, ope->amount) );
 
                        if( ope->flags & OF_SPLIT )
                        {
-                       guint nbsplit = da_splits_count(ope->splits);
+                       guint nbsplit = da_splits_length(ope->splits);
                        Split *split;
                        
                                for(i=0;i<nbsplit;i++)
                                {
-                                       split = ope->splits[i];
-                                       switch(tmpfor)
-                                       {
-                                               case BUDG_CATEGORY:
-                                                       {
-                                                       Category *catentry = da_cat_get(split->kcat);
-                                                               if(catentry)
-                                                                       pos = (catentry->flags & GF_SUB) ? catentry->parent : catentry->key;
-                                                       }
-                                                       break;
-                                               case BUDG_SUBCATEGORY:
-                                                       pos = split->kcat;
-                                                       break;
-                                       }
-
-                                       //trn_amount = split->amount;
-                                       trn_amount = hb_amount_base(split->amount, ope->kcur);
-
-                                       DB( g_print(" -> affecting split %.2f to cat pos %d\n", trn_amount, pos) );
-
-                                       tmp_spent[pos] += trn_amount;
-                               
+                                       split = da_splits_get(ope->splits, i);
+                                       repbudget_compute_cat_spent(split->kcat, hb_amount_base(split->amount, ope->kcur), tmp_spent, tmp_budget);
                                }
                        }
                        else
                        {
-                               switch(tmpfor)
-                               {
-                                       case BUDG_CATEGORY:
-                                               {
-                                               Category *catentry = da_cat_get(ope->kcat);
-                                                       if(catentry)
-                                                               pos = (catentry->flags & GF_SUB) ? catentry->parent : catentry->key;
-                                               }
-                                               break;
-                                       case BUDG_SUBCATEGORY:
-                                               pos = ope->kcat;
-                                               break;
-                               }
-
-                               //trn_amount = ope->amount;
-                               trn_amount = hb_amount_base(ope->amount, ope->kcur);
-
-                               DB( g_print(" -> affecting %.2f to cat pos %d\n", trn_amount, pos) );
-
-                               tmp_spent[pos] += trn_amount;
-
+                               repbudget_compute_cat_spent(ope->kcat, hb_amount_base(ope->amount, ope->kcur), tmp_spent, tmp_budget);
                        }
 
                        list = g_list_next(list);
@@ -827,36 +787,22 @@ gchar *title;
                g_object_ref(model); /* Make sure the model stays with us after the tree view unrefs it */
                gtk_tree_view_set_model(GTK_TREE_VIEW(data->LV_report), NULL); /* Detach model from view */
 
-               DB( g_print("\n+ insert into treeview\n") );
-
-               /* insert into the treeview */
                for(i=1, id=0; i<=n_result; i++)
                {
-               gchar *name, *fullcatname;
+               gchar *name;
                gboolean outofbudget;
                Category *entry;
 
-                       fullcatname = NULL;
-
                        entry = da_cat_get(i);
                        if( entry == NULL)
                                continue;
 
-                       if(entry->flags & GF_SUB)
-                       {
-                       Category *parent = da_cat_get( entry->parent);
-
-                               fullcatname = g_strdup_printf("%s:%s", parent->name, entry->name);
-                               name = fullcatname;
-                       }
-                       else
-                               name = entry->name;
-
-                       if(name == NULL) name  = "(None)";
+                       name = entry->key == 0 ? "(None)" : entry->fullname;
 
                        //#1553862
                        //if( (tmpfor == BUDG_CATEGORY && !(entry->flags & GF_SUB)) || (tmpfor == BUDG_SUBCATEGORY) )
-                       if( (tmpfor == BUDG_CATEGORY && !(entry->flags & GF_SUB)) || (tmpfor == BUDG_SUBCATEGORY && (entry->flags & GF_SUB)) )
+                       if( (tmpfor == BUDG_CATEGORY && !(entry->flags & GF_SUB)) || 
+                          (tmpfor == BUDG_SUBCATEGORY && ((entry->flags & GF_SUB) || !tmp_hassub[i]) ) )
                        {
                        guint pos;
 
@@ -876,7 +822,6 @@ gchar *title;
                                }
 
                                // display expense or income (filter on amount and not category hypothetical flag
-                               //if( tmpkind !=  (entry->flags & GF_INCOME)) continue;
                                if( tmpkind == 1 && tmp_budget[pos] > 0)
                                        continue;
 
@@ -901,26 +846,29 @@ gchar *title;
 
                                        status = "";
                                        outofbudget = FALSE;
-                                       if(rawrate > 1.0)
-                                       {
-                                               status = _(" over");
-                                               outofbudget = TRUE;
-                                       }
-                                       else
+                                       if( result )
                                        {
-                                               if(tmp_budget[pos] < 0.0)
-                                                       status = _(" left");
-                                               else if(tmp_budget[pos] > 0.0)
+                                               if(rawrate > 1.0)
                                                {
-                                                       status = _(" under");
+                                                       status = _(" over");
                                                        outofbudget = TRUE;
                                                }
+                                               else
+                                               {
+                                                       if(tmp_budget[pos] < 0.0)
+                                                               status = _(" left");
+                                                       else if(tmp_budget[pos] > 0.0)
+                                                       {
+                                                               status = _(" under");
+                                                               outofbudget = TRUE;
+                                                       }
+                                               }
                                        }
 
                                        if(tmponlyout == TRUE && outofbudget == FALSE)
                                                goto nextins;
 
-                                       DB( g_print(" => insert %.2f | %.2f = %.2f (%.2f) '%s'\n\n", tmp_spent[pos], tmp_budget[pos], result, rawrate, status ) );
+                                       DB( g_print(" => insert '%s' s:%.2f b:%.2f r:%.2f (%%%.2f) '%s' '%d'\n\n", name, tmp_spent[pos], tmp_budget[pos], result, rawrate, status, outofbudget ) );
 
                                        gtk_list_store_append (GTK_LIST_STORE(model), &iter);
                                        gtk_list_store_set (GTK_LIST_STORE(model), &iter,
@@ -938,14 +886,11 @@ gchar *title;
                                        data->total_budget += tmp_budget[pos];
                                }
                        }
-
-                       g_free(fullcatname);
-
                }
 
                /* update column 0 title */
                GtkTreeViewColumn *column = gtk_tree_view_get_column( GTK_TREE_VIEW(data->LV_report), 0);
-               gtk_tree_view_column_set_title(column, _(CYA_BUDGSELECT[tmpfor]));
+               gtk_tree_view_column_set_title(column, _(CYA_CATSUBCAT[tmpfor]));
 
                gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_report));
 
@@ -957,13 +902,13 @@ gchar *title;
                repbudget_update_total(widget, NULL);
 
                /* update stack chart */
-               title = g_strdup_printf(_("Budget for %s"), _(CYA_BUDGSELECT[tmpfor]) );
+               title = g_strdup_printf(_("Budget for %s"), _(CYA_CATSUBCAT[tmpfor]) );
 
-               ui_chart_stack_set_currency(GTK_CHARTSTACK(data->RE_stack), GLOBALS->kcur);
+               ui_chart_progress_set_currency(GTK_CHARTPROGRESS(data->RE_stack), GLOBALS->kcur);
 
                /* set chart color scheme */
-               ui_chart_stack_set_color_scheme(GTK_CHARTSTACK(data->RE_stack), PREFS->report_color_scheme);
-               ui_chart_stack_set_dualdatas(GTK_CHARTSTACK(data->RE_stack), model, _("Budget"), _("Result"), title, NULL);
+               ui_chart_progress_set_color_scheme(GTK_CHARTPROGRESS(data->RE_stack), PREFS->report_color_scheme);
+               ui_chart_progress_set_dualdatas(GTK_CHARTPROGRESS(data->RE_stack), model, _("Budget"), _("Result"), title, NULL);
 
                g_free(title);
        }
@@ -971,6 +916,7 @@ gchar *title;
        //DB( g_print(" inserting %i, %f %f\n", i, total_expense, total_income) );
 
        /* free our memory */
+       g_free(tmp_hassub);
        g_free(tmp_spent);
        g_free(tmp_budget);
 
@@ -1042,7 +988,7 @@ gboolean minor;
        gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_report));
 
        minor = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_minor));
-       ui_chart_stack_show_minor(GTK_CHARTSTACK(data->RE_stack), minor);
+       ui_chart_progress_show_minor(GTK_CHARTPROGRESS(data->RE_stack), minor);
 
 }
 
@@ -1052,8 +998,8 @@ static void repbudget_setup(struct repbudget_data *data)
 
        data->txn_queue = g_queue_new ();
 
-       data->filter = da_filter_malloc();
-       filter_default_all_set(data->filter);
+       data->filter = da_flt_malloc();
+       filter_reset(data->filter);
 
        data->detail = PREFS->budg_showdetail;
        data->legend = 1;
@@ -1108,7 +1054,7 @@ struct WinGeometry *wg;
 
        g_queue_free (data->txn_queue);
 
-       da_filter_free(data->filter);
+       da_flt_free(data->filter);
        
        g_free(data);
 
@@ -1188,15 +1134,15 @@ GError *error = NULL;
        gtk_grid_attach (GTK_GRID (table), label, 0, row, 3, 1);
 
        row++;
-       label = make_label_widget(_("_For:"));
+       label = make_label_widget(_("_View by:"));
        gtk_grid_attach (GTK_GRID (table), label, 1, row, 1, 1);
-       widget = make_cycle(label, CYA_BUDGSELECT);
+       widget = make_cycle(label, CYA_CATSUBCAT);
        data->CY_for = widget;
        gtk_grid_attach (GTK_GRID (table), data->CY_for, 2, row, 1, 1);
 
 
        row++;
-       label = make_label_widget(_("_Kind:"));
+       label = make_label_widget(_("_Type:"));
        gtk_grid_attach (GTK_GRID (table), label, 1, row, 1, 1);
        widget = make_cycle(label, CYA_KIND);
        data->CY_kind = widget;
@@ -1394,7 +1340,7 @@ GError *error = NULL;
 
        //page: 2d bar
        //widget = gtk_chart_new(CHART_TYPE_COL);
-       widget = ui_chart_stack_new();
+       widget = ui_chart_progress_new();
        data->RE_stack = widget;
        gtk_notebook_append_page(GTK_NOTEBOOK(notebook), widget, NULL);
 
@@ -1569,12 +1515,8 @@ gchar *entry1, *entry2;
        gtk_tree_model_get(model, b, LST_BUDGET_NAME, &entry2, -1);
 
        retval = hb_string_utf8_compare(entry1, entry2);
-       //retval = (entry1->flags & GF_INCOME) - (entry2->flags & GF_INCOME);
-       //if(!retval)
-       //{
-       //      retval = hb_string_utf8_compare(entry1->name, entry2->name);
-       //}
-       //leak
+
+
        g_free(entry2);
        g_free(entry1);
 
This page took 0.041079 seconds and 4 git commands to generate.