Lots are required to correctly implement invoices, inventory, depreciation and stock market investment gains. See the file src/doc/lots.txt for a detailed implementation overview.
A lot is "closed" when the number of items in the lot has gone to zero. It is very easy to compute the gains/losses for a closed lot: it is the sum-total of the values of the items put into/taken out of the lot. (Realized) Gains on still-open lots can be computed by pro-rating the purchase prices.
Lots are nothing more than a collection or grouping of splits in an account. All of the splits in a lot must belong to the same account; there's no mix-n-match. Thus, in this sense, a lot belongs to an accunt as well.
Lots have an implicit "opening date": the date of the earliest split in the lot. The "close date" is the date of the split that brought the lot item balance down to zero.
Files | |
| file | gnc-lot.h |
Defines | |
| #define | gnc_lot_get_guid(X) qof_entity_get_guid(QOF_ENTITY(X)) |
| #define | LOT_IS_CLOSED "is-closed?" |
| #define | LOT_BALANCE "balance" |
| #define | LOT_TITLE "lot-title" |
| #define | LOT_NOTES "notes" |
Functions | |
| GNCLot * | gnc_lot_new (QofBook *) |
| void | gnc_lot_destroy (GNCLot *) |
| GNCLot * | gnc_lot_lookup (const GUID *guid, QofBook *book) |
| QofBook * | gnc_lot_get_book (GNCLot *) |
| void | gnc_lot_add_split (GNCLot *, Split *) |
| void | gnc_lot_remove_split (GNCLot *, Split *) |
| SplitList * | gnc_lot_get_split_list (GNCLot *) |
| gint | gnc_lot_count_splits (GNCLot *) |
| Account * | gnc_lot_get_account (GNCLot *) |
| gnc_numeric | gnc_lot_get_balance (GNCLot *) |
| gboolean | gnc_lot_is_closed (GNCLot *) |
| Split * | gnc_lot_get_earliest_split (GNCLot *lot) |
| Split * | gnc_lot_get_latest_split (GNCLot *lot) |
| const char * | gnc_lot_get_title (GNCLot *) |
| const char * | gnc_lot_get_notes (GNCLot *) |
| void | gnc_lot_set_title (GNCLot *, const char *) |
| void | gnc_lot_set_notes (GNCLot *, const char *) |
| KvpFrame * | gnc_lot_get_slots (GNCLot *) |
|
||||||||||||
|
The gnc_lot_add_split() routine adds a split to this lot. Note that *all* splits in a lot must also be in the same account. Note that this routine adds the split unconditionally, with no regard for the accounting policy. To enforce a particular accounting polciy, use the xaccSplitAssignToLot() routine instead. Definition at line 243 of file gnc-lot.c. 00244 { 00245 Account * acc; 00246 if (!lot || !split) return; 00247 00248 ENTER ("(lot=%p, split=%p) %s amt=%s val=%s", lot, split, 00249 gnc_lot_get_title (lot), 00250 gnc_num_dbg_to_string (split->amount), 00251 gnc_num_dbg_to_string (split->value)); 00252 acc = xaccSplitGetAccount (split); 00253 if (NULL == lot->account) 00254 { 00255 xaccAccountInsertLot (acc, lot); 00256 } 00257 else if (lot->account != acc) 00258 { 00259 PERR ("splits from different accounts cannot " 00260 "be added to this lot!\n" 00261 "\tlot account=\'%s\', split account=\'%s\'\n", 00262 xaccAccountGetName(lot->account), xaccAccountGetName (acc)); 00263 return; 00264 } 00265 00266 if (lot == split->lot) return; /* handle not-uncommon no-op */ 00267 if (split->lot) 00268 { 00269 gnc_lot_remove_split (split->lot, split); 00270 } 00271 split->lot = lot; 00272 00273 lot->splits = g_list_append (lot->splits, split); 00274 00275 /* for recomputation of is-closed */ 00276 lot->is_closed = -1; 00277 00278 gnc_engine_gen_event (&lot->entity, GNC_EVENT_MODIFY); 00279 }
|
|
|
The gnc_lot_get_account() routine returns the account with which this lot is associated. Definition at line 144 of file gnc-lot.c.
|
|
|
The gnc_lot_get_balance() routine returns the balance of the lot. The commodity in which this balance is expressed is the commodity of the account. Definition at line 204 of file gnc-lot.c. 00205 { 00206 GList *node; 00207 gnc_numeric zero = gnc_numeric_zero(); 00208 gnc_numeric baln = zero; 00209 if (!lot) return zero; 00210 00211 if (!lot->splits) 00212 { 00213 lot->is_closed = FALSE; 00214 return zero; 00215 } 00216 00217 /* Sum over splits; because they all belong to same account 00218 * they will have same denominator. 00219 */ 00220 for (node=lot->splits; node; node=node->next) 00221 { 00222 Split *s = node->data; 00223 gnc_numeric amt = xaccSplitGetAmount (s); 00224 baln = gnc_numeric_add_fixed (baln, amt); 00225 } 00226 00227 /* cache a zero balance as a closed lot */ 00228 if (gnc_numeric_equal (baln, zero)) 00229 { 00230 lot->is_closed = TRUE; 00231 } 00232 else 00233 { 00234 lot->is_closed = FALSE; 00235 } 00236 00237 return baln; 00238 }
|
|
|
The gnc_lot_get_earliest_split() routine is a convenience routine that helps identify the date this lot was opened. It simply loops over all of the splits in the lot, and returns the split with the earliest split->transaction->date_posted. Definition at line 303 of file gnc-lot.c. 00304 { 00305 SplitList *node; 00306 Timespec ts; 00307 Split *earliest = NULL; 00308 00309 ts.tv_sec = ((long long) LONG_MAX); 00310 ts.tv_nsec = 0; 00311 if (!lot) return NULL; 00312 00313 for (node=lot->splits; node; node=node->next) 00314 { 00315 Split *s = node->data; 00316 Transaction *trans = s->parent; 00317 if (!trans) continue; 00318 if ((ts.tv_sec > trans->date_posted.tv_sec) || 00319 ((ts.tv_sec == trans->date_posted.tv_sec) && 00320 (ts.tv_nsec > trans->date_posted.tv_nsec))) 00321 00322 { 00323 ts = trans->date_posted; 00324 earliest = s; 00325 } 00326 } 00327 00328 return earliest; 00329 }
|
|
|
The gnc_lot_get_latest_split() routine is a convenience routine that helps identify the date this lot was closed. It simply loops over all of the splits in the lot, and returns the split with the latest split->transaction->date_posted. Definition at line 332 of file gnc-lot.c. 00333 { 00334 SplitList *node; 00335 Timespec ts; 00336 Split *latest = NULL; 00337 00338 ts.tv_sec = -((long long) LONG_MAX); 00339 ts.tv_nsec = 0; 00340 if (!lot) return NULL; 00341 00342 for (node=lot->splits; node; node=node->next) 00343 { 00344 Split *s = node->data; 00345 Transaction *trans = s->parent; 00346 if (!trans) continue; 00347 if ((ts.tv_sec < trans->date_posted.tv_sec) || 00348 ((ts.tv_sec == trans->date_posted.tv_sec) && 00349 (ts.tv_nsec < trans->date_posted.tv_nsec))) 00350 00351 { 00352 ts = trans->date_posted; 00353 latest = s; 00354 } 00355 } 00356 00357 return latest; 00358 }
|
|
|
Every lot has a place to hang kvp data. This routine returns that place. Definition at line 151 of file gnc-lot.c.
|
|
|
The gnc_lot_get_split_list() routine returns a GList of all the splits in this lot. Do *not* not free this list when done; it is a pointer straight into the lots intenal list. Do *not* add to or remove from this list directly. Calling either gnc_lot_add_split() or gnc_lot_remove_split() will invalidate the returned pointer. Definition at line 158 of file gnc-lot.c.
|
|
|
Get and set the account title, or the account notes. Definition at line 174 of file gnc-lot.c. 00175 { 00176 if (!lot) return NULL; 00177 return kvp_frame_get_string (lot->kvp_data, "/title"); 00178 }
|
|
|
The gnc_lot_is_closed() routine returns a boolean flag: is this lot closed? A lot is closed if its balance is zero. This routine is faster than using gnc_lot_get_balance() because once the balance goes to zero, this fact is cached. Definition at line 136 of file gnc-lot.c. 00137 { 00138 if (!lot) return TRUE; 00139 if (0 > lot->is_closed) gnc_lot_get_balance (lot); 00140 return lot->is_closed; 00141 }
|
1.4.3-20050530