Line data Source code
1 : /*
2 : * gnc-accounting-period.c --
3 : *
4 : * Copyright (c) 2005 David Hampton <hampton@employees.org>
5 : * All rights reserved.
6 : *
7 : * GnuCash is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU Library General Public License as
9 : * published by the Free Software Foundation; either version 2 of
10 : * the License, or (at your option) any later version.
11 : *
12 : * Gnucash is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : * Library General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License
18 : * along with this program; if not, contact:
19 : *
20 : * Free Software Foundation Voice: +1-617-542-5942
21 : * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
22 : * Boston, MA 02110-1301, USA gnu@gnu.org
23 : */
24 :
25 : /** @addtogroup GUI
26 : @{ */
27 : /** @file gnc-accounting-period.c
28 : @brief General utilities for dealing with accounting periods.
29 : @author David Hampton <hampton@employees.org>
30 :
31 : These are general utility functions for specifying an accounting
32 : period and converting it to a value usable by the gnucash engine.
33 : The choice of src/app-utils is arbitrary as these utilities don't
34 : fit well anywhere else. They are at a higher level than a GDate,
35 : so they don't fit in src/core-utils/gnc-gdate-utils.c. They don't
36 : operate on engine data structures, so they don't belong in
37 : src/engine/Period.c. Putting them into src/engine/gnc-date.c
38 : would be the best place for them, but then that creates a new
39 : dependency from the src/engine directory to the src/core-utils
40 : directory that doesn't currently exist. Since that might be a
41 : problem for CashUtils, the app-file directory was chosen.
42 : */
43 :
44 : #include <config.h>
45 : #include <string.h>
46 : #include "gnc-accounting-period.h"
47 : #include "gnc-date.h"
48 : #include "gnc-prefs.h"
49 : #include "qof.h"
50 : #include "gnc-session.h"
51 :
52 : static const QofLogModule log_module = G_LOG_DOMAIN;
53 : static time64 gnc_accounting_period_start_time64 (GncAccountingPeriod which,
54 : const GDate *fy_end,
55 : const GDate *contains);
56 : static time64 gnc_accounting_period_end_time64 (GncAccountingPeriod which,
57 : const GDate *fy_end,
58 : const GDate *contains);
59 :
60 : static time64
61 226 : lookup_start_date_option (GDate *fy_end)
62 : {
63 : time64 time;
64 : int which;
65 :
66 226 : if (gnc_prefs_get_bool (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_START_CHOICE_ABS))
67 24 : time = gnc_time64_get_day_start (gnc_prefs_get_int64
68 : (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_START_DATE));
69 : else
70 : {
71 202 : which = gnc_prefs_get_int (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_START_PERIOD);
72 202 : time = gnc_accounting_period_start_time64 (which, fy_end, NULL);
73 : }
74 : /* we will need the balance of the last transaction before the start
75 : date, so subtract 1 from start date */
76 : /* CAS: we don't actually do what this comment says. I think that's
77 : because a bug in the engine has been fixed. */
78 226 : return time;
79 : }
80 :
81 : static time64
82 41 : lookup_end_date_option (GDate *fy_end)
83 : {
84 : time64 time;
85 : int which;
86 :
87 41 : if (gnc_prefs_get_bool (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_END_CHOICE_ABS))
88 0 : time = gnc_time64_get_day_end (gnc_prefs_get_int64
89 : (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_END_DATE));
90 : else
91 : {
92 41 : which = gnc_prefs_get_int (GNC_PREFS_GROUP_ACCT_SUMMARY, GNC_PREF_END_PERIOD);
93 41 : time = gnc_accounting_period_end_time64 (which, fy_end, NULL);
94 : }
95 41 : if (time == 0)
96 0 : time = -1;
97 41 : return time;
98 : }
99 :
100 : static GDate *
101 267 : get_fy_end (void)
102 : {
103 : QofBook *book;
104 267 : GDate *date = NULL;
105 :
106 267 : book = qof_session_get_book(gnc_get_current_session());
107 267 : qof_instance_get (QOF_INSTANCE (book), "fy-end", &date, NULL);
108 267 : return date;
109 : }
110 :
111 : time64
112 226 : gnc_accounting_period_fiscal_start (void)
113 : {
114 : time64 t;
115 226 : GDate *fy_end = get_fy_end();
116 226 : t = lookup_start_date_option (fy_end);
117 226 : if (fy_end)
118 0 : g_date_free (fy_end);
119 226 : return t;
120 : }
121 :
122 : time64
123 41 : gnc_accounting_period_fiscal_end (void)
124 : {
125 : time64 t;
126 41 : GDate *fy_end = get_fy_end();
127 :
128 41 : t = lookup_end_date_option (fy_end);
129 41 : if (fy_end)
130 0 : g_date_free (fy_end);
131 41 : return t;
132 : }
133 :
134 : GDate *
135 202 : gnc_accounting_period_start_gdate (GncAccountingPeriod which,
136 : const GDate *fy_end,
137 : const GDate *contains)
138 : {
139 : GDate *date;
140 :
141 202 : if (contains)
142 : {
143 0 : date = g_date_new_dmy (g_date_get_day (contains),
144 : g_date_get_month (contains),
145 0 : g_date_get_year (contains));
146 : }
147 : else
148 : {
149 202 : date = g_date_new ();
150 202 : gnc_gdate_set_today (date);
151 : }
152 :
153 202 : switch (which)
154 : {
155 0 : default:
156 0 : PINFO ("Undefined relative time constant %d", which);
157 0 : g_date_free (date);
158 0 : return NULL;
159 :
160 178 : case GNC_ACCOUNTING_PERIOD_TODAY:
161 : /* Already have today's date */
162 178 : break;
163 :
164 0 : case GNC_ACCOUNTING_PERIOD_MONTH:
165 0 : gnc_gdate_set_month_start (date);
166 0 : break;
167 :
168 0 : case GNC_ACCOUNTING_PERIOD_MONTH_PREV:
169 0 : gnc_gdate_set_prev_month_start (date);
170 0 : break;
171 :
172 0 : case GNC_ACCOUNTING_PERIOD_QUARTER:
173 0 : gnc_gdate_set_quarter_start (date);
174 0 : break;
175 :
176 0 : case GNC_ACCOUNTING_PERIOD_QUARTER_PREV:
177 0 : gnc_gdate_set_prev_quarter_start (date);
178 0 : break;
179 :
180 24 : case GNC_ACCOUNTING_PERIOD_CYEAR:
181 24 : gnc_gdate_set_year_start (date);
182 24 : break;
183 :
184 0 : case GNC_ACCOUNTING_PERIOD_CYEAR_PREV:
185 0 : gnc_gdate_set_prev_year_start (date);
186 0 : break;
187 :
188 0 : case GNC_ACCOUNTING_PERIOD_FYEAR:
189 0 : if (fy_end == NULL)
190 : {
191 0 : PINFO ("Request for fiscal year value but no fiscal year end value provided.");
192 0 : g_date_free (date);
193 0 : return NULL;
194 : }
195 0 : gnc_gdate_set_fiscal_year_start (date, fy_end);
196 0 : break;
197 :
198 0 : case GNC_ACCOUNTING_PERIOD_FYEAR_PREV:
199 0 : if (fy_end == NULL)
200 : {
201 0 : PINFO ("Request for fiscal year value but no fiscal year end value provided.");
202 0 : g_date_free (date);
203 0 : return NULL;
204 : }
205 0 : gnc_gdate_set_prev_fiscal_year_start (date, fy_end);
206 0 : break;
207 : }
208 202 : return date;
209 : }
210 :
211 : static time64
212 202 : gnc_accounting_period_start_time64 (GncAccountingPeriod which,
213 : const GDate *fy_end,
214 : const GDate *contains)
215 : {
216 : GDate *date;
217 : time64 secs;
218 :
219 202 : date = gnc_accounting_period_start_gdate (which, fy_end, contains);
220 202 : if (!date)
221 0 : return 0;
222 :
223 202 : secs = gnc_time64_get_day_start_gdate (date);
224 202 : g_date_free (date);
225 202 : return secs;
226 : }
227 :
228 : GDate *
229 41 : gnc_accounting_period_end_gdate (GncAccountingPeriod which,
230 : const GDate *fy_end,
231 : const GDate *contains)
232 : {
233 : GDate *date;
234 :
235 41 : if (contains)
236 : {
237 0 : date = g_date_new_dmy (g_date_get_day (contains),
238 : g_date_get_month (contains),
239 0 : g_date_get_year (contains));
240 : }
241 : else
242 : {
243 41 : date = g_date_new ();
244 41 : gnc_gdate_set_today (date);
245 : }
246 :
247 41 : switch (which)
248 : {
249 0 : default:
250 0 : PINFO ("Undefined relative time constant %d", which);
251 0 : g_date_free (date);
252 0 : return 0;
253 :
254 41 : case GNC_ACCOUNTING_PERIOD_TODAY:
255 : /* Already have today's date */
256 41 : break;
257 :
258 0 : case GNC_ACCOUNTING_PERIOD_MONTH:
259 0 : gnc_gdate_set_month_end (date);
260 0 : break;
261 :
262 0 : case GNC_ACCOUNTING_PERIOD_MONTH_PREV:
263 0 : gnc_gdate_set_prev_month_end (date);
264 0 : break;
265 :
266 0 : case GNC_ACCOUNTING_PERIOD_QUARTER:
267 0 : gnc_gdate_set_quarter_end (date);
268 0 : break;
269 :
270 0 : case GNC_ACCOUNTING_PERIOD_QUARTER_PREV:
271 0 : gnc_gdate_set_prev_quarter_end (date);
272 0 : break;
273 :
274 0 : case GNC_ACCOUNTING_PERIOD_CYEAR:
275 0 : gnc_gdate_set_year_end (date);
276 0 : break;
277 :
278 0 : case GNC_ACCOUNTING_PERIOD_CYEAR_PREV:
279 0 : gnc_gdate_set_prev_year_end (date);
280 0 : break;
281 :
282 0 : case GNC_ACCOUNTING_PERIOD_FYEAR:
283 0 : if (fy_end == NULL)
284 : {
285 0 : PINFO ("Request for fisal year value but no fiscal year end value provided.");
286 0 : g_date_free (date);
287 0 : return 0;
288 : }
289 0 : gnc_gdate_set_fiscal_year_end (date, fy_end);
290 0 : break;
291 :
292 0 : case GNC_ACCOUNTING_PERIOD_FYEAR_PREV:
293 0 : if (fy_end == NULL)
294 : {
295 0 : PINFO ("Request for fisal year value but no fiscal year end value provided.");
296 0 : g_date_free (date);
297 0 : return 0;
298 : }
299 0 : gnc_gdate_set_prev_fiscal_year_end (date, fy_end);
300 0 : break;
301 : }
302 :
303 41 : return date;
304 : }
305 :
306 : static time64
307 41 : gnc_accounting_period_end_time64 (GncAccountingPeriod which,
308 : const GDate *fy_end,
309 : const GDate *contains)
310 : {
311 : GDate *date;
312 : time64 secs;
313 :
314 41 : date = gnc_accounting_period_end_gdate (which, fy_end, contains);
315 41 : if (!date)
316 0 : return 0;
317 :
318 41 : secs = gnc_time64_get_day_end_gdate (date);
319 41 : g_date_free (date);
320 41 : return secs ;
321 : }
322 :
323 : /** @} */
|