1 /********************************************************************\
2  * SplitP.h -- private header for splits                            *
3  * Copyright (C) 1997 Robin D. Clark                                *
4  * Copyright (C) 1997-2000 Linas Vepstas <linas@linas.org>          *
5  * Copyright (C) 2000 Bill Gribble                                  *
6  *                                                                  *
7  * This program is free software; you can redistribute it and/or    *
8  * modify it under the terms of the GNU 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  * This program 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    *
15  * GNU 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 
26 /*
27  * FILE:
28  * SplitP.h
29  *
30  * FUNCTION:
31  * The is the *private* split header file.  Code outside of
32  * engine should *not* include this file.  This is because code
33  * outside of the engine should *never* access any of the structure
34  * members directly.
35  *
36  * Note that this header file also defines prototypes for various
37  * routines that perform sub-atomic updates of the accounting
38  * structures.  If these routines are not used properly, they
39  * can result in inconsistent, unbalanced accounting structures.
40  * In other words, their use is dangerous, and their use outside
41  * of the scope of the engine is forbidden.
42  *
43  */
44 
45 #ifndef XACC_SPLIT_P_H
46 #define XACC_SPLIT_P_H
47 
48 #include <time.h>
49 #include <glib.h>
50 
51 #include "gnc-engine.h"   /* for typedefs */
52 #include "qof.h"
53 
54 
55 /** STRUCTS *********************************************************/
56 /* A "split" is more commonly referred to as an "entry" in a "transaction".
57  */
58 
59 /* Flags for handling cap-gains status */
60 #define GAINS_STATUS_UNKNOWN        0xff
61 #define GAINS_STATUS_CLEAN           0x0
62 #define GAINS_STATUS_GAINS           0x3
63 #define GAINS_STATUS_DATE_DIRTY     0x10
64 #define GAINS_STATUS_AMNT_DIRTY     0x20
65 #define GAINS_STATUS_VALU_DIRTY     0x40
66 #define GAINS_STATUS_LOT_DIRTY      0x80
67 #define GAINS_STATUS_ADIRTY    (GAINS_STATUS_AMNT_DIRTY|GAINS_STATUS_LOT_DIRTY)
68 #define GAINS_STATUS_VDIRTY    (GAINS_STATUS_VALU_DIRTY)
69 #define GAINS_STATUS_A_VDIRTY  (GAINS_STATUS_AMNT_DIRTY|GAINS_STATUS_VALU_DIRTY|GAINS_STATUS_LOT_DIRTY)
70 
71 struct split_s
72 {
73     QofInstance inst;
74 
75     Account *acc;              /* back-pointer to debited/credited account  */
76     Account *orig_acc;
77     GNCLot *lot;               /* back-pointer to debited/credited lot */
78 
79     Transaction *parent;       /* parent of split                           */
80     Transaction *orig_parent;
81 
82     /* The memo field is an arbitrary user-assiged value.
83      * It is intended to hold a short (zero to forty character) string
84      * that is displayed by the GUI along with this split.
85      */
86     const char  *memo;
87 
88     /* The action field is an arbitrary user-assigned value.
89      * It is meant to be a very short (one to ten character) string that
90      * signifies the "type" of this split, such as e.g. Buy, Sell, Div,
91      * Withdraw, Deposit, ATM, Check, etc. The idea is that this field
92      * can be used to create custom reports or graphs of data.
93      */
94     const char  *action;       /* Buy, Sell, Div, etc.                      */
95 
96     time64 date_reconciled;    /* date split was reconciled                 */
97     char   reconciled;         /* The reconciled field                      */
98 
99     /* gains is a flag used to track the relationship between
100      * capital-gains splits. Depending on its value, this flag indicates
101      * if this split is the source of gains, if this split is a record
102      * of the gains, and if values are 'dirty' and need to be recomputed.
103      */
104     unsigned char  gains;
105 
106     /* 'gains_split' is a convenience pointer used to track down the
107      * other end of a cap-gains transaction pair.  NULL if this split
108      * doesn't involve cap gains.
109      */
110     Split *gains_split;
111 
112     /* 'value' is the quantity of the transaction balancing commodity
113      * (i.e. currency) involved, 'amount' is the amount of the account's
114      * commodity involved. */
115     gnc_numeric  value;
116     gnc_numeric  amount;
117 
118     const gchar * split_type;
119 
120     /* -------------------------------------------------------------- */
121     /* Below follow some 'temporary' fields */
122 
123     /* The various "balances" are the sum of all of the values of
124      * all the splits in the account, up to and including this split.
125      * These balances apply to a sorting order by date posted
126      * (not by date entered). */
127     gnc_numeric  balance;
128     gnc_numeric  noclosing_balance;
129     gnc_numeric  cleared_balance;
130     gnc_numeric  reconciled_balance;
131 };
132 
133 struct _SplitClass
134 {
135     QofInstanceClass parent_class;
136 };
137 
138 
139 /* Set the split's GncGUID. This should only be done when reading
140  * a split from a datafile, or some other external source. Never
141  * call this on an existing split! */
142 #define xaccSplitSetGUID(s,g) qof_instance_set_guid(QOF_INSTANCE(s),g)
143 
144 /* The xaccFreeSplit() method simply frees all memory associated
145  * with the split.  It does not verify that the split isn't
146  * referenced in some account.  If the split is referenced by an
147  * account, then calling this method will leave the system in an
148  * inconsistent state.  This *will* lead to crashes and hangs.
149  */
150 void  xaccFreeSplit (Split *split);    /* frees memory */
151 
152 Split *xaccSplitCloneNoKvp (const Split *s);
153 void xaccSplitCopyKvp (const Split *from, Split *to);
154 
155 Split *xaccDupeSplit (const Split *s);
156 void mark_split (Split *s);
157 
158 void xaccSplitVoid(Split *split);
159 void xaccSplitUnvoid(Split *split);
160 void xaccSplitCommitEdit(Split *s);
161 void xaccSplitRollbackEdit(Split *s);
162 
163 /* Compute the value of a list of splits in the given currency,
164  * excluding the skip_me split. */
165 gnc_numeric xaccSplitsComputeValue (GList *splits, const Split * skip_me,
166                                     const gnc_commodity * base_currency);
167 
168 /* Code to register Split type with the engine */
169 gboolean xaccSplitRegister (void);
170 
171 /* The xaccSplitDetermineGainStatus() routine will analyze the
172  *   the split, and try to set the internal status flags
173  *   appropriately for the split.  These flags indicate if the split
174  *   represents cap gains, and if the gains value/amount needs to be
175  *   recomputed.
176  */
177 void xaccSplitDetermineGainStatus (Split *split);
178 
179 /* ---------------------------------------------------------------- */
180 /* Deprecated routines */
181 void         DxaccSplitSetSharePriceAndAmount (Split *split,
182         double price,
183         double amount);
184 void         DxaccSplitSetShareAmount (Split *split, double amount);
185 
186 /********************************************************************\
187  * sorting comparison function
188  *
189  * returns a negative value if transaction a is dated earlier than b,
190  * returns a positive value if transaction a is dated later than b,
191  *
192  * This function tries very hard to uniquely order all transactions.
193  * If two transactions occur on the same date, then their "num" fields
194  * are compared.  If the num fields are identical, then the description
195  * fields are compared.  If these are identical, then the memo fields
196  * are compared.  Hopefully, there will not be any transactions that
197  * occur on the same day that have all three of these values identical.
198  *
199  * Note that being able to establish this kind of absolute order is
200  * important for some of the ledger display functions.
201  *
202  * Yes, this kind of code dependency is ugly, but the alternatives seem
203  * ugly too.
204  *
205 \********************************************************************/
206 
207 
208 #define CHECK_GAINS_STATUS(s)  \
209    if (GAINS_STATUS_UNKNOWN == s->gains) xaccSplitDetermineGainStatus(s);
210 
211 #define SET_GAINS_DIRTY(s,flg) do {                                     \
212    if (FALSE == (GAINS_STATUS_GAINS & s->gains)) {                      \
213       s->gains |= flg;                                                  \
214    } else {                                                             \
215       if (s->gains_split) s->gains_split->gains |= flg;                 \
216    }                                                                    \
217 } while (0)
218 
219 #define SET_GAINS_ADIRTY(s)  SET_GAINS_DIRTY(s,GAINS_STATUS_ADIRTY);
220 #define SET_GAINS_A_VDIRTY(s) SET_GAINS_DIRTY(s,GAINS_STATUS_A_VDIRTY);
221 #define SET_GAINS_VDIRTY(s)  SET_GAINS_DIRTY(s,GAINS_STATUS_VDIRTY);
222 
223 /* Structure for accessing static functions for testing */
224 typedef struct
225 {
226     gboolean (*xaccSplitEqualCheckBal) (const char *tag, gnc_numeric a,
227 					gnc_numeric b);
228     int (*get_currency_denom) (const Split *s);
229     int (*get_commodity_denom) (const Split *s);
230     gboolean (*get_corr_account_split) (const Split *sa, const Split **retval);
231 } SplitTestFunctions;
232 
233 SplitTestFunctions* _utest_split_fill_functions (void);
234 
235 
236 /*@}*/
237 
238 
239 #endif /* XACC_SPLIT_P_H */
240