1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2014 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-archive.h"
26 /****************************************************************************/
28 /****************************************************************************/
37 /* our global datas */
38 extern struct HomeBank
*GLOBALS
;
41 /* = = = = = = = = = = = = = = = = = = = = */
44 Archive
*da_archive_malloc(void)
46 return rc_alloc(sizeof(Archive
));
49 Archive
*da_archive_clone(Archive
*src_item
)
51 Archive
*new_item
= rc_dup(src_item
, sizeof(Archive
));
55 //duplicate the string
56 new_item
->wording
= g_strdup(src_item
->wording
);
61 void da_archive_free(Archive
*item
)
65 if(item
->wording
!= NULL
)
66 g_free(item
->wording
);
72 void da_archive_destroy(GList
*list
)
74 GList
*tmplist
= g_list_first(list
);
76 while (tmplist
!= NULL
)
78 Archive
*item
= tmplist
->data
;
79 da_archive_free(item
);
80 tmplist
= g_list_next(tmplist
);
85 static gint
da_archive_glist_compare_func(Archive
*a
, Archive
*b
)
87 return hb_string_utf8_compare(a
->wording
, b
->wording
);
91 GList
*da_archive_sort(GList
*list
)
93 return g_list_sort(list
, (GCompareFunc
)da_archive_glist_compare_func
);
96 guint
da_archive_length(void)
98 return g_list_length(GLOBALS
->arc_list
);
101 void da_archive_consistency(Archive
*item
)
107 // check category exists
108 cat
= da_cat_get(item
->kcat
);
111 g_warning("arc consistency: fixed invalid cat %d", item
->kcat
);
115 // check payee exists
116 pay
= da_pay_get(item
->kpay
);
119 g_warning("arc consistency: fixed invalid pay %d", item
->kpay
);
123 // reset dst acc for non xfer transaction
124 if( item
->paymode
!= PAYMODE_INTXFER
)
127 // remove automation if dst_acc not exists
128 if(item
->paymode
== PAYMODE_INTXFER
)
130 acc
= da_acc_get(item
->kxferacc
);
133 item
->flags
&= ~(OF_AUTO
); //remove flag
139 /* = = = = = = = = = = = = = = = = = = = = */
141 static guint32
_sched_date_get_next_post(Archive
*arc
, guint32 nextdate
)
144 guint32 nextpostdate
= nextdate
;
146 tmpdate
= g_date_new_julian(nextpostdate
);
150 g_date_add_days(tmpdate
, arc
->every
);
153 g_date_add_days(tmpdate
, 7 * arc
->every
);
155 case AUTO_UNIT_MONTH
:
156 g_date_add_months(tmpdate
, arc
->every
);
159 g_date_add_years(tmpdate
, arc
->every
);
163 /* get the final post date and free */
164 nextpostdate
= g_date_get_julian(tmpdate
);
165 g_date_free(tmpdate
);
167 /* check limit, update and maybe break */
168 if(arc
->flags
& OF_LIMIT
)
173 arc
->flags
^= (OF_LIMIT
| OF_AUTO
); // invert flags
182 gboolean
scheduled_is_postable(Archive
*arc
)
186 value
= arrondi(arc
->amount
, 2);
187 if( (arc
->flags
& OF_AUTO
) && (arc
->kacc
> 0) && (value
!= 0.0) )
194 guint32
scheduled_get_postdate(Archive
*arc
, guint32 postdate
)
198 guint32 finalpostdate
;
201 finalpostdate
= postdate
;
203 tmpdate
= g_date_new_julian(finalpostdate
);
204 /* manage weekend exception */
205 if( arc
->weekend
> 0 )
207 wday
= g_date_get_weekday(tmpdate
);
209 DB( g_print(" %s wday=%d\n", arc
->wording
, wday
) );
211 if( wday
>= G_DATE_SATURDAY
)
215 case 1: /* shift before : sun 7-5=+2 , sat 6-5=+1 */
216 shift
= wday
- G_DATE_FRIDAY
;
217 DB( g_print("sub=%d\n", shift
) );
218 g_date_subtract_days (tmpdate
, shift
);
221 case 2: /* shift after : sun 8-7=1 , sat 8-6=2 */
223 DB( g_print("add=%d\n", shift
) );
224 g_date_add_days (tmpdate
, shift
);
230 /* get the final post date and free */
231 finalpostdate
= g_date_get_julian(tmpdate
);
232 g_date_free(tmpdate
);
234 return finalpostdate
;
241 guint32
scheduled_get_latepost_count(Archive
*arc
, guint32 jrefdate
)
244 guint32 curdate
= arc
->nextdate
;
246 while(curdate
<= jrefdate
)
248 curdate
= _sched_date_get_next_post(arc
, curdate
);
250 // break at 11 max (to display +10)
259 /* return 0 is max number of post is reached */
260 guint32
scheduled_date_advance(Archive
*arc
)
262 arc
->nextdate
= _sched_date_get_next_post(arc
, arc
->nextdate
);
263 return arc
->nextdate
;
268 * return the maximum date a scheduled txn can be posted to
270 guint32
scheduled_date_get_post_max(void)
273 GDate
*today
, *maxdate
;
275 DB( g_print("\n[scheduled] date_get_post_max\n") );
277 //add until xx of the next month (excluded)
278 if(GLOBALS
->auto_smode
== 0)
280 DB( g_print(" - max is %d of next month\n", GLOBALS
->auto_weekday
) );
282 today
= g_date_new_julian(GLOBALS
->today
);
284 //we compute user xx weekday of next month
285 maxdate
= g_date_new_julian(GLOBALS
->today
);
286 g_date_set_day(maxdate
, GLOBALS
->auto_weekday
);
287 if(g_date_get_day (today
) >= GLOBALS
->auto_weekday
)
288 g_date_add_months(maxdate
, 1);
290 nbdays
= g_date_days_between(today
, maxdate
);
292 g_date_free(maxdate
);
297 nbdays
= GLOBALS
->auto_nbdays
;
300 DB( hb_print_date(GLOBALS
->today
, "today") );
301 DB( g_print(" - %d nbdays\n", nbdays
) );
302 DB( hb_print_date(GLOBALS
->today
+ nbdays
, "maxpostdate") );
304 return GLOBALS
->today
+ nbdays
;
308 gint
scheduled_post_all_pending(void)
315 DB( g_print("\n[scheduled] post_all_pending\n") );
319 maxpostdate
= scheduled_date_get_post_max();
321 txn
= da_transaction_malloc();
323 list
= g_list_first(GLOBALS
->arc_list
);
326 Archive
*arc
= list
->data
;
328 DB( g_print("\n eval %d for '%s'\n", scheduled_is_postable(arc
), arc
->wording
) );
330 if(scheduled_is_postable(arc
) == TRUE
)
332 DB( g_print(" - every %d limit %d (to %d)\n", arc
->every
, arc
->flags
& OF_LIMIT
, arc
->limit
) );
333 DB( hb_print_date(arc
->nextdate
, "next post") );
335 if(arc
->nextdate
< maxpostdate
)
337 guint32 mydate
= arc
->nextdate
;
339 while(mydate
< maxpostdate
)
341 DB( hb_print_date(mydate
, arc
->wording
) );
343 da_transaction_init_from_template(txn
, arc
);
344 txn
->date
= scheduled_get_postdate(arc
, mydate
);
345 /* todo: ? fill in cheque number */
347 transaction_add(txn
, NULL
, 0);
348 GLOBALS
->changes_count
++;
351 da_transaction_clean(txn
);
353 mydate
= scheduled_date_advance(arc
);
355 //DB( hb_print_date(mydate, "next on") );
364 list
= g_list_next(list
);
367 da_transaction_free (txn
);