|
GnuCash 2.4.99
|
00001 /********************************************************************\ 00002 * SplitP.h -- private header for splits * 00003 * Copyright (C) 1997 Robin D. Clark * 00004 * Copyright (C) 1997-2000 Linas Vepstas <linas@linas.org> * 00005 * Copyright (C) 2000 Bill Gribble * 00006 * * 00007 * This program is free software; you can redistribute it and/or * 00008 * modify it under the terms of the GNU General Public License as * 00009 * published by the Free Software Foundation; either version 2 of * 00010 * the License, or (at your option) any later version. * 00011 * * 00012 * This program is distributed in the hope that it will be useful, * 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00015 * GNU General Public License for more details. * 00016 * * 00017 * You should have received a copy of the GNU General Public License* 00018 * along with this program; if not, contact: * 00019 * * 00020 * Free Software Foundation Voice: +1-617-542-5942 * 00021 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * 00022 * Boston, MA 02110-1301, USA gnu@gnu.org * 00023 * * 00024 \********************************************************************/ 00025 00026 /* 00027 * FILE: 00028 * SplitP.h 00029 * 00030 * FUNCTION: 00031 * The is the *private* split header file. Code outside of 00032 * engine should *not* include this file. This is because code 00033 * outside of the engine should *never* access any of the structure 00034 * members directly. 00035 * 00036 * Note that this header file also defines prototypes for various 00037 * routines that perform sub-atomic updates of the accounting 00038 * structures. If these routines are not used properly, they 00039 * can result in inconsistent, unbalanced accounting structures. 00040 * In other words, their use is dangerous, and their use outside 00041 * of the scope of the engine is forbidden. 00042 * 00043 */ 00044 00045 #ifndef XACC_SPLIT_P_H 00046 #define XACC_SPLIT_P_H 00047 00048 #include <time.h> 00049 #include <glib.h> 00050 00051 #include "gnc-engine.h" /* for typedefs */ 00052 #include "qof.h" 00053 00054 00056 /* A "split" is more commonly referred to as an "entry" in a "transaction". 00057 */ 00058 00059 /* Flags for handling cap-gains status */ 00060 #define GAINS_STATUS_UNKNOWN 0xff 00061 #define GAINS_STATUS_CLEAN 0x0 00062 #define GAINS_STATUS_GAINS 0x3 00063 #define GAINS_STATUS_DATE_DIRTY 0x10 00064 #define GAINS_STATUS_AMNT_DIRTY 0x20 00065 #define GAINS_STATUS_VALU_DIRTY 0x40 00066 #define GAINS_STATUS_LOT_DIRTY 0x80 00067 #define GAINS_STATUS_ADIRTY (GAINS_STATUS_AMNT_DIRTY|GAINS_STATUS_LOT_DIRTY) 00068 #define GAINS_STATUS_VDIRTY (GAINS_STATUS_VALU_DIRTY) 00069 #define GAINS_STATUS_A_VDIRTY (GAINS_STATUS_AMNT_DIRTY|GAINS_STATUS_VALU_DIRTY|GAINS_STATUS_LOT_DIRTY) 00070 00071 struct split_s 00072 { 00073 QofInstance inst; 00074 00075 Account *acc; /* back-pointer to debited/credited account */ 00076 Account *orig_acc; 00077 GNCLot *lot; /* back-pointer to debited/credited lot */ 00078 00079 Transaction *parent; /* parent of split */ 00080 Transaction *orig_parent; 00081 00082 /* The memo field is an arbitrary user-assiged value. 00083 * It is intended to hold a short (zero to forty character) string 00084 * that is displayed by the GUI along with this split. 00085 */ 00086 char * memo; 00087 00088 /* The action field is an arbitrary user-assigned value. 00089 * It is meant to be a very short (one to ten character) string that 00090 * signifies the "type" of this split, such as e.g. Buy, Sell, Div, 00091 * Withdraw, Deposit, ATM, Check, etc. The idea is that this field 00092 * can be used to create custom reports or graphs of data. 00093 */ 00094 char * action; /* Buy, Sell, Div, etc. */ 00095 00096 Timespec date_reconciled; /* date split was reconciled */ 00097 char reconciled; /* The reconciled field */ 00098 00099 /* gains is a flag used to track the relationship between 00100 * capital-gains splits. Depending on its value, this flag indicates 00101 * if this split is the source of gains, if this split is a record 00102 * of the gains, and if values are 'dirty' and need to be recomputed. 00103 */ 00104 unsigned char gains; 00105 00106 /* 'gains_split' is a convenience pointer used to track down the 00107 * other end of a cap-gains transaction pair. NULL if this split 00108 * doesn't involve cap gains. 00109 */ 00110 Split *gains_split; 00111 00112 /* 'value' is the quantity of the transaction balancing commodity 00113 * (i.e. currency) involved, 'amount' is the amount of the account's 00114 * commodity involved. */ 00115 gnc_numeric value; 00116 gnc_numeric amount; 00117 00118 /* -------------------------------------------------------------- */ 00119 /* Below follow some 'temporary' fields */ 00120 00121 /* The various "balances" are the sum of all of the values of 00122 * all the splits in the account, up to and including this split. 00123 * These balances apply to a sorting order by date posted 00124 * (not by date entered). */ 00125 gnc_numeric balance; 00126 gnc_numeric cleared_balance; 00127 gnc_numeric reconciled_balance; 00128 }; 00129 00130 struct _SplitClass 00131 { 00132 QofInstanceClass parent_class; 00133 }; 00134 00135 00136 /* Set the split's GncGUID. This should only be done when reading 00137 * a split from a datafile, or some other external source. Never 00138 * call this on an existing split! */ 00139 #define xaccSplitSetGUID(s,g) qof_instance_set_guid(QOF_INSTANCE(s),g) 00140 00141 /* The xaccFreeSplit() method simply frees all memory associated 00142 * with the split. It does not verify that the split isn't 00143 * referenced in some account. If the split is referenced by an 00144 * account, then calling this method will leave the system in an 00145 * inconsistent state. This *will* lead to crashes and hangs. 00146 */ 00147 void xaccFreeSplit (Split *split); /* frees memory */ 00148 00149 Split * xaccSplitClone (const Split *s); 00150 00151 Split *xaccDupeSplit (const Split *s); 00152 void mark_split (Split *s); 00153 00154 void xaccSplitVoid(Split *split); 00155 void xaccSplitUnvoid(Split *split); 00156 void xaccSplitCommitEdit(Split *s); 00157 void xaccSplitRollbackEdit(Split *s); 00158 00159 /* Compute the value of a list of splits in the given currency, 00160 * excluding the skip_me split. */ 00161 gnc_numeric xaccSplitsComputeValue (GList *splits, const Split * skip_me, 00162 const gnc_commodity * base_currency); 00163 00164 /* Code to register Split type with the engine */ 00165 gboolean xaccSplitRegister (void); 00166 00167 /* The xaccSplitDetermineGainStatus() routine will analyze the 00168 * the split, and try to set the internal status flags 00169 * appropriately for the split. These flags indicate if the split 00170 * represents cap gains, and if the gains value/amount needs to be 00171 * recomputed. 00172 */ 00173 void xaccSplitDetermineGainStatus (Split *split); 00174 00175 /* ---------------------------------------------------------------- */ 00176 /* Deprecated routines */ 00177 void DxaccSplitSetSharePriceAndAmount (Split *split, 00178 double price, 00179 double amount); 00180 void DxaccSplitSetShareAmount (Split *split, double amount); 00181 00182 /********************************************************************\ 00183 * sorting comparison function 00184 * 00185 * returns a negative value if transaction a is dated earlier than b, 00186 * returns a positive value if transaction a is dated later than b, 00187 * 00188 * This function tries very hard to uniquely order all transactions. 00189 * If two transactions occur on the same date, then their "num" fields 00190 * are compared. If the num fields are identical, then the description 00191 * fields are compared. If these are identical, then the memo fields 00192 * are compared. Hopefully, there will not be any transactions that 00193 * occur on the same day that have all three of these values identical. 00194 * 00195 * Note that being able to establish this kind of absolute order is 00196 * important for some of the ledger display functions. 00197 * 00198 * Yes, this kind of code dependency is ugly, but the alternatives seem 00199 * ugly too. 00200 * 00201 \********************************************************************/ 00202 00203 00204 #define DATE_CMP(aaa,bbb,field) { \ 00205 /* if dates differ, return */ \ 00206 if ( (aaa->field.tv_sec) < \ 00207 (bbb->field.tv_sec)) { \ 00208 return -1; \ 00209 } else \ 00210 if ( (aaa->field.tv_sec) > \ 00211 (bbb->field.tv_sec)) { \ 00212 return +1; \ 00213 } \ 00214 \ 00215 /* else, seconds match. check nanoseconds */ \ 00216 if ( (aaa->field.tv_nsec) < \ 00217 (bbb->field.tv_nsec)) { \ 00218 return -1; \ 00219 } else \ 00220 if ( (aaa->field.tv_nsec) > \ 00221 (bbb->field.tv_nsec)) { \ 00222 return +1; \ 00223 } \ 00224 } 00225 00226 #define CHECK_GAINS_STATUS(s) \ 00227 if (GAINS_STATUS_UNKNOWN == s->gains) xaccSplitDetermineGainStatus(s); 00228 00229 #define SET_GAINS_DIRTY(s,flg) do { \ 00230 if (FALSE == (GAINS_STATUS_GAINS & s->gains)) { \ 00231 s->gains |= flg; \ 00232 } else { \ 00233 if (s->gains_split) s->gains_split->gains |= flg; \ 00234 } \ 00235 } while (0) 00236 00237 #define SET_GAINS_ADIRTY(s) SET_GAINS_DIRTY(s,GAINS_STATUS_ADIRTY); 00238 #define SET_GAINS_A_VDIRTY(s) SET_GAINS_DIRTY(s,GAINS_STATUS_A_VDIRTY); 00239 #define SET_GAINS_VDIRTY(s) SET_GAINS_DIRTY(s,GAINS_STATUS_VDIRTY); 00240 00241 /* Structure for accessing static functions for testing */ 00242 typedef struct 00243 { 00244 gboolean (*xaccSplitEqualCheckBal) (const char *tag, gnc_numeric a, 00245 gnc_numeric b); 00246 int (*get_currency_denom) (const Split *s); 00247 int (*get_commodity_denom) (const Split *s); 00248 gboolean (*get_corr_account_split) (const Split *sa, const Split **retval); 00249 } SplitTestFunctions; 00250 00251 SplitTestFunctions* _utest_split_fill_functions (void); 00252 00253 00257 #endif /* XACC_SPLIT_P_H */
1.7.4