]>
Dogcows Code - chaz/homebank/blob - hb-filter.c
4747704dd53b091ab6565b6aab8f7c4a2a4e13cb
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2017 Maxime DOYEN
4 * This file is part of HomeBank.
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.
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.
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/>.
21 #include "hb-filter.h"
23 /****************************************************************************/
25 /****************************************************************************/
34 /* our global datas */
35 extern struct HomeBank
*GLOBALS
;
36 extern struct Preferences
*PREFS
;
41 /* = = = = = = = = = = = = = = = = = = = = */
44 Filter
*da_filter_malloc(void)
46 return g_malloc0(sizeof(Filter
));
49 void da_filter_free(Filter
*flt
)
60 /* = = = = = = = = = = = = = = = = = = = = */
62 gchar
*filter_daterange_text_get(Filter
*flt
)
68 date
= g_date_new_julian(flt
->mindate
);
69 g_date_strftime (buffer1
, 128-1, PREFS
->date_format
, date
);
70 g_date_set_julian(date
, flt
->maxdate
);
71 g_date_strftime (buffer2
, 128-1, PREFS
->date_format
, date
);
74 return g_strdup_printf(_("<i>from</i> %s <i>to</i> %s"), buffer1
, buffer2
);
79 static void filter_default_date_set(Filter
*flt
)
81 flt
->mindate
= HB_MINDATE
;
82 flt
->maxdate
= HB_MAXDATE
;
86 static void filter_clear(Filter
*flt
)
90 for(i
=0;i
<FILTER_MAX
;i
++)
106 void filter_default_all_set(Filter
*flt
)
110 DB( g_print("(filter) reset %p\n", flt
) );
114 flt
->range
= FLT_RANGE_LAST12MONTHS
;
115 flt
->type
= FLT_TYPE_ALL
;
116 flt
->status
= FLT_STATUS_ALL
;
118 flt
->forceremind
= PREFS
->showremind
;
120 flt
->option
[FILTER_DATE
] = 1;
121 filter_default_date_set(flt
);
123 for(i
=0;i
<NUM_PAYMODE_MAX
;i
++)
124 flt
->paymode
[i
] = TRUE
;
126 filter_preset_daterange_set(flt
, flt
->range
, 0);
131 static void filter_set_date_bounds(Filter
*flt
, guint32 kacc
)
133 GList
*lst_acc
, *lnk_acc
;
136 DB( g_print("(filter) set date bounds %p\n", flt
) );
141 lst_acc
= g_hash_table_get_values(GLOBALS
->h_acc
);
142 lnk_acc
= g_list_first(lst_acc
);
143 while (lnk_acc
!= NULL
)
145 Account
*acc
= lnk_acc
->data
;
147 if( !(acc
->flags
& AF_CLOSED
) )
151 DB( g_print(" - do '%s'\n", acc
->name
) );
153 lnk_txn
= g_queue_peek_head_link(acc
->txn_queue
);
156 if( (kacc
== 0) || (txn
->kacc
== kacc
) )
158 if( flt
->mindate
== 0 )
159 flt
->mindate
= txn
->date
;
161 flt
->mindate
= MIN(flt
->mindate
, txn
->date
);
165 lnk_txn
= g_queue_peek_tail_link(acc
->txn_queue
);
168 if( (kacc
== 0) || (txn
->kacc
== kacc
) )
170 if( flt
->maxdate
== 0 )
171 flt
->maxdate
= txn
->date
;
173 flt
->maxdate
= MAX(flt
->maxdate
, txn
->date
);
178 lnk_acc
= g_list_next(lnk_acc
);
181 if( flt
->mindate
== 0 )
182 flt
->mindate
= HB_MINDATE
;
184 if( flt
->maxdate
== 0 )
185 flt
->maxdate
= HB_MAXDATE
;
187 g_list_free(lst_acc
);
191 void filter_preset_daterange_add_futuregap(Filter
*filter
, gint nbdays
)
197 switch( filter
->range
)
199 case FLT_RANGE_THISMONTH
:
200 case FLT_RANGE_THISQUARTER
:
201 case FLT_RANGE_THISYEAR
:
202 case FLT_RANGE_LAST30DAYS
:
203 case FLT_RANGE_LAST60DAYS
:
204 case FLT_RANGE_LAST90DAYS
:
205 case FLT_RANGE_LAST12MONTHS
:
206 filter
->maxdate
+= nbdays
;
213 void filter_preset_daterange_set(Filter
*flt
, gint range
, guint32 kacc
)
216 guint32 refjuliandate
, month
, year
, qnum
;
218 DB( g_print("(filter) daterange set %p %d\n", flt
, range
) );
220 //filter_default_date_set(flt);
221 filter_set_date_bounds(flt
, kacc
);
225 // by default refjuliandate is today
226 // but we adjust if to max transaction date found
228 refjuliandate
= GLOBALS
->today
;
229 /*if(flt->maxdate < refjuliandate)
230 refjuliandate = flt->maxdate;*/
232 date
= g_date_new_julian(refjuliandate
);
233 month
= g_date_get_month(date
);
234 year
= g_date_get_year(date
);
235 qnum
= ((month
- 1) / 3) + 1;
237 DB( g_print("m=%d, y=%d, qnum=%d\n", month
, year
, qnum
) );
241 case FLT_RANGE_THISMONTH
:
242 g_date_set_day(date
, 1);
243 flt
->mindate
= g_date_get_julian(date
);
244 g_date_add_days(date
, g_date_get_days_in_month(month
, year
)-1);
245 flt
->maxdate
= g_date_get_julian(date
);
248 case FLT_RANGE_LASTMONTH
:
249 g_date_set_day(date
, 1);
250 g_date_subtract_months(date
, 1);
251 flt
->mindate
= g_date_get_julian(date
);
252 month
= g_date_get_month(date
);
253 year
= g_date_get_year(date
);
254 g_date_add_days(date
, g_date_get_days_in_month(month
, year
)-1);
255 flt
->maxdate
= g_date_get_julian(date
);
258 case FLT_RANGE_THISQUARTER
:
259 g_date_set_day(date
, 1);
260 g_date_set_month(date
, (qnum
-1)*3+1);
261 flt
->mindate
= g_date_get_julian(date
);
262 g_date_add_months(date
, 3);
263 g_date_subtract_days(date
, 1);
264 flt
->maxdate
= g_date_get_julian(date
);
267 case FLT_RANGE_LASTQUARTER
:
268 g_date_set_day(date
, 1);
269 g_date_set_month(date
, (qnum
-1)*3+1);
270 g_date_subtract_months(date
, 3);
271 flt
->mindate
= g_date_get_julian(date
);
272 g_date_add_months(date
, 3);
273 g_date_subtract_days(date
, 1);
274 flt
->maxdate
= g_date_get_julian(date
);
277 case FLT_RANGE_THISYEAR
:
278 g_date_set_dmy(date
, PREFS
->fisc_year_day
, PREFS
->fisc_year_month
, year
);
279 if( refjuliandate
>= g_date_get_julian (date
))
281 flt
->mindate
= g_date_get_julian(date
);
285 g_date_set_dmy(date
, PREFS
->fisc_year_day
, PREFS
->fisc_year_month
, year
-1);
286 flt
->mindate
= g_date_get_julian(date
);
288 g_date_add_years (date
, 1);
289 g_date_subtract_days (date
, 1);
290 flt
->maxdate
= g_date_get_julian(date
);
293 case FLT_RANGE_LASTYEAR
:
294 g_date_set_dmy(date
, PREFS
->fisc_year_day
, PREFS
->fisc_year_month
, year
);
295 if( refjuliandate
>= g_date_get_julian (date
))
297 g_date_set_dmy(date
, PREFS
->fisc_year_day
, PREFS
->fisc_year_month
, year
-1);
298 flt
->mindate
= g_date_get_julian(date
);
302 g_date_set_dmy(date
, PREFS
->fisc_year_day
, PREFS
->fisc_year_month
, year
-2);
303 flt
->mindate
= g_date_get_julian(date
);
305 g_date_add_years (date
, 1);
306 g_date_subtract_days (date
, 1);
307 flt
->maxdate
= g_date_get_julian(date
);
310 case FLT_RANGE_LAST30DAYS
:
311 flt
->mindate
= refjuliandate
- 30;
312 flt
->maxdate
= refjuliandate
;
315 case FLT_RANGE_LAST60DAYS
:
316 flt
->mindate
= refjuliandate
- 60;
317 flt
->maxdate
= refjuliandate
;
320 case FLT_RANGE_LAST90DAYS
:
321 flt
->mindate
= refjuliandate
- 90;
322 flt
->maxdate
= refjuliandate
;
325 case FLT_RANGE_LAST12MONTHS
:
326 g_date_subtract_months(date
, 12);
327 flt
->mindate
= g_date_get_julian(date
);
328 flt
->maxdate
= refjuliandate
;
331 // case FLT_RANGE_OTHER:
333 // case FLT_RANGE_ALLDATE:
341 void filter_preset_type_set(Filter
*flt
, gint type
)
346 flt
->option
[FILTER_AMOUNT
] = 0;
347 flt
->minamount
= G_MINDOUBLE
;
348 flt
->maxamount
= G_MINDOUBLE
;
352 case FLT_TYPE_EXPENSE
:
353 flt
->option
[FILTER_AMOUNT
] = 1;
354 flt
->minamount
= -G_MAXDOUBLE
;
355 flt
->maxamount
= G_MINDOUBLE
;
358 case FLT_TYPE_INCOME
:
359 flt
->option
[FILTER_AMOUNT
] = 1;
360 flt
->minamount
= G_MINDOUBLE
;
361 flt
->maxamount
= G_MAXDOUBLE
;
368 void filter_preset_status_set(Filter
*flt
, gint status
)
374 flt
->status
= status
;
375 flt
->option
[FILTER_STATUS
] = 0;
376 flt
->reconciled
= TRUE
;
378 //#1602835 fautly set
379 //flt->forceadd = TRUE;
380 //flt->forcechg = TRUE;
382 flt
->option
[FILTER_CATEGORY
] = 0;
383 lcat
= list
= g_hash_table_get_values(GLOBALS
->h_cat
);
386 catitem
= list
->data
;
387 catitem
->filter
= FALSE
;
388 list
= g_list_next(list
);
394 case FLT_STATUS_UNCATEGORIZED
:
395 flt
->option
[FILTER_CATEGORY
] = 1;
396 catitem
= da_cat_get(0); // no category
397 catitem
->filter
= TRUE
;
400 case FLT_STATUS_UNRECONCILED
:
401 flt
->option
[FILTER_STATUS
] = 2;
402 flt
->reconciled
= TRUE
;
403 flt
->cleared
= FALSE
;
406 case FLT_STATUS_UNCLEARED
:
407 flt
->option
[FILTER_STATUS
] = 2;
408 flt
->reconciled
= FALSE
;
412 case FLT_STATUS_RECONCILED
:
413 flt
->option
[FILTER_STATUS
] = 1;
414 flt
->reconciled
= TRUE
;
415 flt
->cleared
= FALSE
;
418 case FLT_STATUS_CLEARED
:
419 flt
->option
[FILTER_STATUS
] = 1;
420 flt
->reconciled
= FALSE
;
428 static gint
filter_text_compare(gchar
*txntext
, gchar
*searchtext
, gboolean exact
)
434 if( g_strstr_len(txntext
, -1, searchtext
) != NULL
)
436 DB( g_print(" found case '%s'\n", searchtext
) );
442 gchar
*word
= g_utf8_casefold(txntext
, -1);
443 gchar
*needle
= g_utf8_casefold(searchtext
, -1);
445 if( g_strrstr(word
, needle
) != NULL
)
447 DB( g_print(" found nocase '%s'\n", needle
) );
458 /* used for quicksearch text into transaction */
459 gboolean
filter_txn_search_match(gchar
*needle
, Transaction
*txn
, gint flags
)
461 gboolean retval
= FALSE
;
466 if(flags
& FLT_QSEARCH_MEMO
)
469 if(txn
->flags
& OF_SPLIT
)
474 count
= da_splits_count(txn
->splits
);
479 split
= txn
->splits
[i
];
480 tmpinsert
= filter_text_compare(split
->memo
, needle
, FALSE
);
490 retval
|= filter_text_compare(txn
->wording
, needle
, FALSE
);
496 if(flags
& FLT_QSEARCH_INFO
)
500 retval
|= filter_text_compare(txn
->info
, needle
, FALSE
);
505 if(flags
& FLT_QSEARCH_PAYEE
)
507 payitem
= da_pay_get(txn
->kpay
);
510 retval
|= filter_text_compare(payitem
->name
, needle
, FALSE
);
515 if(flags
& FLT_QSEARCH_CATEGORY
)
518 if(txn
->flags
& OF_SPLIT
)
523 count
= da_splits_count(txn
->splits
);
528 split
= txn
->splits
[i
];
529 catitem
= da_cat_get(split
->kcat
);
532 gchar
*fullname
= da_cat_get_fullname (catitem
);
534 tmpinsert
= filter_text_compare(fullname
, needle
, FALSE
);
545 catitem
= da_cat_get(txn
->kcat
);
548 gchar
*fullname
= da_cat_get_fullname (catitem
);
550 retval
|= filter_text_compare(fullname
, needle
, FALSE
);
557 if(flags
& FLT_QSEARCH_TAGS
)
559 tags
= transaction_tags_tostring(txn
);
562 retval
|= filter_text_compare(tags
, needle
, FALSE
);
565 //if(retval) goto end;
574 gint
filter_test(Filter
*flt
, Transaction
*txn
)
581 //DB( g_print("(filter) test\n") );
585 /*** start filtering ***/
588 if(flt
->forceadd
== TRUE
&& (txn
->flags
& OF_ADDED
))
591 if(flt
->forcechg
== TRUE
&& (txn
->flags
& OF_CHANGED
))
594 /* force remind if not filter on status */
595 if(flt
->forceremind
== TRUE
&& (txn
->status
== TXN_STATUS_REMIND
))
599 if(flt
->option
[FILTER_DATE
]) {
600 insert
= ( (txn
->date
>= flt
->mindate
) && (txn
->date
<= flt
->maxdate
) ) ? 1 : 0;
601 if(flt
->option
[FILTER_DATE
] == 2) insert
^= 1;
603 if(!insert
) goto end
;
606 if(flt
->option
[FILTER_ACCOUNT
]) {
607 accitem
= da_acc_get(txn
->kacc
);
610 insert
= ( accitem
->filter
== TRUE
) ? 1 : 0;
611 if(flt
->option
[FILTER_ACCOUNT
] == 2) insert
^= 1;
614 if(!insert
) goto end
;
617 if(flt
->option
[FILTER_PAYEE
]) {
618 payitem
= da_pay_get(txn
->kpay
);
621 insert
= ( payitem
->filter
== TRUE
) ? 1 : 0;
622 if(flt
->option
[FILTER_PAYEE
] == 2) insert
^= 1;
625 if(!insert
) goto end
;
628 if(flt
->option
[FILTER_CATEGORY
]) {
629 if(txn
->flags
& OF_SPLIT
)
634 insert
= 0; //fix: 1151259
635 count
= da_splits_count(txn
->splits
);
640 split
= txn
->splits
[i
];
641 catitem
= da_cat_get(split
->kcat
);
644 tmpinsert
= ( catitem
->filter
== TRUE
) ? 1 : 0;
645 if(flt
->option
[FILTER_CATEGORY
] == 2) tmpinsert
^= 1;
652 catitem
= da_cat_get(txn
->kcat
);
655 insert
= ( catitem
->filter
== TRUE
) ? 1 : 0;
656 if(flt
->option
[FILTER_CATEGORY
] == 2) insert
^= 1;
660 if(!insert
) goto end
;
663 if(flt
->option
[FILTER_STATUS
]) {
664 gint insert1
= 0, insert2
= 0;
667 insert1
= ( txn
->status
== TXN_STATUS_RECONCILED
) ? 1 : 0;
669 insert2
= ( txn
->status
== TXN_STATUS_CLEARED
) ? 1 : 0;
671 insert
= insert1
| insert2
;
672 if(flt
->option
[FILTER_STATUS
] == 2) insert
^= 1;
674 if(!insert
) goto end
;
677 if(flt
->option
[FILTER_PAYMODE
]) {
678 insert
= ( flt
->paymode
[txn
->paymode
] == TRUE
) ? 1 : 0;
679 if(flt
->option
[FILTER_PAYMODE
] == 2) insert
^= 1;
681 if(!insert
) goto end
;
684 if(flt
->option
[FILTER_AMOUNT
]) {
685 insert
= ( (txn
->amount
>= flt
->minamount
) && (txn
->amount
<= flt
->maxamount
) ) ? 1 : 0;
687 if(flt
->option
[FILTER_AMOUNT
] == 2) insert
^= 1;
689 if(!insert
) goto end
;
691 /* info/wording/tag */
692 if(flt
->option
[FILTER_TEXT
])
695 gint insert1
, insert2
, insert3
;
697 insert1
= insert2
= insert3
= 0;
702 insert1
= filter_text_compare(txn
->info
, flt
->info
, flt
->exact
);
710 if(txn
->flags
& OF_SPLIT
)
715 count
= da_splits_count(txn
->splits
);
720 split
= txn
->splits
[i
];
721 tmpinsert
= filter_text_compare(split
->memo
, flt
->wording
, flt
->exact
);
722 insert2
|= tmpinsert
;
731 insert2
= filter_text_compare(txn
->wording
, flt
->wording
, flt
->exact
);
740 tags
= transaction_tags_tostring(txn
);
743 insert3
= filter_text_compare(tags
, flt
->tag
, flt
->exact
);
750 insert
= insert1
&& insert2
&& insert3
? 1 : 0;
752 if(flt
->option
[FILTER_TEXT
] == 2) insert
^= 1;
755 if(!insert
) goto end
;
758 // DB( g_print(" %d :: %d :: %d\n", flt->mindate, txn->date, flt->maxdate) );
759 // DB( g_print(" [%d] %s => %d (%d)\n", txn->account, txn->wording, insert, count) );
This page took 0.070245 seconds and 3 git commands to generate.