Factor out some code from gnc-budget into Recurrence so that the budget

estimation code can use stand-alone recurrences to estimate budget values.
  Also, tweak the initial budget so that it begins at the beginning of the 
  current month.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@13092 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Chris Shoemaker
2006-02-04 15:12:09 +00:00
parent bbb8d1be33
commit edb52e4d32
3 changed files with 54 additions and 37 deletions
+32
View File
@@ -27,6 +27,8 @@
#include "gnc-date.h"
#include "qof.h"
#include "gnc-engine.h"
#include "gnc-gdate-utils.h"
#include "Account.h"
static QofLogModule log_module = GNC_MOD_ENGINE;
@@ -228,6 +230,36 @@ recurrenceNthInstance(const Recurrence *r, guint n, GDate *date)
}
}
time_t
recurrenceGetPeriodTime(const Recurrence *r, guint period_num, gboolean end)
{
GDate date;
recurrenceNthInstance(r, period_num + (end ? 1 : 0), &date);
if (end) {
g_date_subtract_days(&date, 1);
return gnc_timet_get_day_end_gdate(&date);
} else {
return gnc_timet_get_day_start_gdate(&date);
}
}
gnc_numeric
recurrenceGetAccountPeriodValue(const Recurrence *r, Account *acc, guint n)
{
gnc_numeric num1, num2;
time_t t1, t2;
// FIXME: maybe zero is not best error return val.
g_return_val_if_fail(r && acc, gnc_numeric_zero());
t1 = recurrenceGetPeriodTime(r, n, FALSE);
t2 = recurrenceGetPeriodTime(r, n, TRUE);
num1 = xaccAccountGetBalanceAsOfDateInCurrency(acc, t1, NULL, TRUE);
num2 = xaccAccountGetBalanceAsOfDateInCurrency(acc, t2, NULL, TRUE);
return gnc_numeric_sub(num2, num1, GNC_DENOM_AUTO, GNC_HOW_DENOM_FIXED);
}
void
recurrenceListNextInstance(const GList *rlist, const GDate *ref, GDate *next)
{
+12 -1
View File
@@ -45,6 +45,8 @@
#define RECURRENCE_H
#include <glib.h>
#include "Account.h"
#include "gnc-numeric.h"
typedef enum {
PERIOD_ONCE, /* Not a true period at all, but convenient here. */
@@ -69,7 +71,7 @@ typedef struct {
/* recurrenceSet() will enforce internal consistency by overriding
inconsistent inputs so that 'r' will _always_ end up being valid
inconsistent inputs so that 'r' will _always_ end up being a valid
recurrence.
- if the period type is invalid, PERIOD_MONTH is used.
@@ -122,6 +124,15 @@ void recurrenceNextInstance(const Recurrence *r, const GDate *refDate,
/* Zero-based. n == 1 gets the instance after the start date. */
void recurrenceNthInstance(const Recurrence *r, guint n, GDate *date);
/* Get a time coresponding to the beginning (or end if 'end' is true)
of the nth instance of the recurrence. Also zero-based. */
time_t recurrenceGetPeriodTime(const Recurrence *r, guint n, gboolean end);
/* Get the amount that an Account's value changed between the
beginning and end of the nth instance of the recurrence. */
gnc_numeric recurrenceGetAccountPeriodValue(const Recurrence *r,
Account *acct, guint n);
/* Get the earliest of the next occurances -- a "composite" recurrence */
void recurrenceListNextInstance(const GList *r, const GDate *refDate,
GDate *nextDate);
+10 -36
View File
@@ -25,7 +25,7 @@
#include <glib.h>
#include <glib/gprintf.h>
#include <glib/gi18n.h>
#include <time.h>
#include "qof.h"
#include "Account.h"
@@ -50,14 +50,16 @@ GncBudget*
gnc_budget_new(QofBook *book)
{
GncBudget* budget;
GDate date;
g_return_val_if_fail(book, NULL);
ENTER(" ");
budget = g_new0(GncBudget, 1);
qof_instance_init (&budget->inst, GNC_ID_BUDGET, book);
recurrenceSet(&budget->recurrence, 1, PERIOD_MONTH, NULL);
g_date_set_time(&date, time(NULL));
g_date_subtract_days(&date, g_date_get_day(&date)-1);
recurrenceSet(&budget->recurrence, 1, PERIOD_MONTH, &date);
gnc_budget_set_name(budget, _("Unnamed Budget"));
gnc_budget_set_description(budget, "");
@@ -249,52 +251,24 @@ gnc_budget_get_account_period_value(GncBudget *budget, Account *account,
return numeric;
}
/* If 'end' is true, then get a time just before the beginning of the
next period */
static time_t
gnc_budget_get_period_time(GncBudget *budget, guint period_num, gboolean end)
{
GDate date;
recurrenceNthInstance(&(budget->recurrence),
period_num + (end ? 1 : 0), &date);
if (end) {
g_date_subtract_days(&date, 1);
return gnc_timet_get_day_end_gdate(&date);
} else {
return gnc_timet_get_day_start_gdate(&date);
}
}
Timespec
gnc_budget_get_period_start_date(GncBudget *budget, guint period_num)
{
Timespec ts;
timespecFromTime_t(
&ts, gnc_budget_get_period_time(budget, period_num, FALSE));
&ts, recurrenceGetPeriodTime(&budget->recurrence, period_num, FALSE));
return ts;
}
gnc_numeric
gnc_budget_get_account_period_actual_value(
GncBudget *budget, Account *account, guint period_num)
GncBudget *budget, Account *acc, guint period_num)
{
gnc_numeric numeric, num1, num2;
time_t t1, t2;
// FIXME: maybe zero is not best error return val.
g_return_val_if_fail(GNC_IS_BUDGET(budget) && account, gnc_numeric_zero());
t1 = gnc_budget_get_period_time(budget, period_num, FALSE);
t2 = gnc_budget_get_period_time(budget, period_num, TRUE);
num1 = xaccAccountGetBalanceAsOfDateInCurrency(
account, t1, NULL, TRUE);
num2 = xaccAccountGetBalanceAsOfDateInCurrency(
account, t2, NULL, TRUE);
numeric = gnc_numeric_sub(num2, num1, GNC_DENOM_AUTO,
GNC_HOW_DENOM_FIXED);
return numeric;
g_return_val_if_fail(GNC_IS_BUDGET(budget) && acc, gnc_numeric_zero());
return recurrenceGetAccountPeriodValue(&budget->recurrence,
acc, period_num);
}
QofBook*