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