1 /******************************************************************** 2 * gnc-pricedb.h -- a simple price database for gnucash. * 3 * * 4 * This program is free software; you can redistribute it and/or * 5 * modify it under the terms of the GNU General Public License as * 6 * published by the Free Software Foundation; either version 2 of * 7 * the License, or (at your option) any later version. * 8 * * 9 * This program is distributed in the hope that it will be useful, * 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 * GNU General Public License for more details. * 13 * * 14 * You should have received a copy of the GNU General Public License* 15 * along with this program; if not, contact: * 16 * * 17 * Free Software Foundation Voice: +1-617-542-5942 * 18 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * 19 * Boston, MA 02110-1301, USA gnu@gnu.org * 20 * * 21 *******************************************************************/ 22 23 #ifndef GNC_PRICEDB_H 24 #define GNC_PRICEDB_H 25 26 typedef struct _GncPriceClass GNCPriceClass; 27 typedef struct _GncPriceDBClass GNCPriceDBClass; 28 29 #include <stdio.h> 30 #include "qof.h" 31 #include "gnc-commodity.h" 32 #include "gnc-engine.h" 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 /* --- type macros --- */ 39 #define GNC_TYPE_PRICE (gnc_price_get_type ()) 40 #define GNC_PRICE(o) \ 41 (G_TYPE_CHECK_INSTANCE_CAST ((o), GNC_TYPE_PRICE, GNCPrice)) 42 #define GNC_PRICE_CLASS(k) \ 43 (G_TYPE_CHECK_CLASS_CAST((k), GNC_TYPE_PRICE, GNCPriceClass)) 44 #define GNC_IS_PRICE(o) \ 45 (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNC_TYPE_PRICE)) 46 #define GNC_IS_PRICE_CLASS(k) \ 47 (G_TYPE_CHECK_CLASS_TYPE ((k), GNC_TYPE_PRICE)) 48 #define GNC_PRICE_GET_CLASS(o) \ 49 (G_TYPE_INSTANCE_GET_CLASS ((o), GNC_TYPE_PRICE, GNCPriceClass)) 50 GType gnc_price_get_type(void); 51 52 /* --- type macros --- */ 53 #define GNC_TYPE_PRICEDB (gnc_pricedb_get_type ()) 54 #define GNC_PRICEDB(o) \ 55 (G_TYPE_CHECK_INSTANCE_CAST ((o), GNC_TYPE_PRICEDB, GNCPriceDB)) 56 #define GNC_PRICEDB_CLASS(k) \ 57 (G_TYPE_CHECK_CLASS_CAST((k), GNC_TYPE_PRICEDB, GNCPriceDBClass)) 58 #define GNC_IS_PRICEDB(o) \ 59 (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNC_TYPE_PRICEDB)) 60 #define GNC_IS_PRICEDB_CLASS(k) \ 61 (G_TYPE_CHECK_CLASS_TYPE ((k), GNC_TYPE_PRICEDB)) 62 #define GNC_PRICEDB_GET_CLASS(o) \ 63 (G_TYPE_INSTANCE_GET_CLASS ((o), GNC_TYPE_PRICEDB, GNCPriceDBClass)) 64 GType gnc_pricedb_get_type(void); 65 66 67 /** @addtogroup PriceDB 68 @{ */ 69 /** @file gnc-pricedb.h 70 @author Copyright (C) 2001 Rob Browning 71 @author Copyright (C) 2001,2003 Linas Vepstas <linas@linas.org> 72 @brief a simple price database for gnucash 73 */ 74 /** @} */ 75 76 77 /** @addtogroup Engine 78 @{ */ 79 /** @addtogroup PriceDB Price Database 80 @ingroup Engine 81 The PriceDB is intended to be a database of price quotes, or more 82 specifically, a database of GNCPrices. For the time being, it is 83 still a fairly simple database supporting only fairly simple 84 queries. It is expected that new queries will be added as needed, 85 and that there is some advantage to delaying complex queries for 86 now in the hope that we get a real DB implementation before 87 they're really needed. 88 89 Every QofBook contains a GNCPriceDB, accessible via 90 gnc_pricedb_get_db. 91 92 \warning The PriceDB does not currently use the object 93 system used elsewhere in the GnuCash Engine, i.e. it does 94 not use GUISD's, Entities and Collections. It should. 95 In particular, this means that currently prices cannot 96 be queried with the same mechanism as everything else. 97 */ 98 99 /** @addtogroup Price Prices 100 @ingroup Engine 101 Each price in the database represents an "instantaneous" quote for 102 a given commodity with respect to another commodity. For example, 103 a given price might represent the value of LNUX in USD on 104 2001-02-03. 105 106 \par Fields: 107 108 - commodity: the item being priced. 109 - currency: the denomination of the value of the item being priced. 110 - value: the value of the item being priced. 111 - time: the time the price was valid. 112 - source: a string describing the source of the quote. These 113 strings will be something like this: "Finance::Quote", 114 "user:misc", "user:foo", etc. If the quote came from a user, 115 as a matter of policy, you *must* prefix the string you give 116 with "user:". For now, the only other reserved values are 117 "Finance::Quote" and "old-file-import". Any string used must 118 be added to the source_list array in dialog-price-edit-db.c so 119 that it can be properly translated. (There are unfortunately 120 many strings in users' databases, so this string must be 121 translated on output instead of always being used in untranslated 122 form). 123 - type: the type of quote - types possible right now are bid, ask, last, 124 nav, transaction, and unknown. 'Transaction' is set when the price is 125 created from an amount and value in a Split and is not available for users 126 to set via the GUI. 127 128 \par Implementation Details: 129 130 \note 131 For source and type, NULL and the empty string are 132 considered the same, so if one of these is "", then after a file 133 save/restore, it might be NULL. Behave accordingly. 134 135 GNCPrices are reference counted. When you gnc_price_create one 136 or clone it, the new price's count is set to 1. When you are 137 finished with a price, call gnc_price_unref. If you hand the 138 price pointer to some other code that needs to keep it, make 139 sure it calls gnc_price_ref to indicate its interest in that 140 price, and calls gnc_price_unref when it's finished with the 141 price. For those unfamiliar with reference counting, basically 142 each price stores an integer count which starts at 1 and is 143 incremented every time someone calls gnc_price_ref. Conversely, 144 the count is decremented every time someone calls 145 gnc_price_unref. If the count ever reaches 0, the price is 146 destroyed. 147 148 All of the getters return data that's internal to the GNCPrice, 149 not copies, so don't free these values. 150 151 All of the setters store copies of the data given, with the 152 exception of the commodity field which just stores the pointer 153 given. It is assumed that commodities are a global resource and 154 are pointer unique. 155 */ 156 /* ================================================================ */ 157 158 /** @addtogroup Price 159 @{ */ 160 161 /** */ 162 typedef GList PriceList; 163 164 /** Price source enum. Be sure to keep in sync with the source_name array in 165 * gnc-pricedb.c. These are in preference order, so for example a quote with 166 * PRICE_SOURCE_EDIT_DLG will overwrite one with PRICE_SOURCE_FQ but not the 167 * other way around. 168 */ 169 typedef enum 170 { 171 PRICE_SOURCE_EDIT_DLG, // "user:price-editor" 172 PRICE_SOURCE_FQ, // "Finance::Quote" 173 PRICE_SOURCE_USER_PRICE, // "user:price" 174 PRICE_SOURCE_XFER_DLG_VAL, // "user:xfer-dialog" 175 PRICE_SOURCE_SPLIT_REG, // "user:split-register" 176 PRICE_SOURCE_SPLIT_IMPORT, // "user:split-import" 177 PRICE_SOURCE_STOCK_SPLIT, // "user:stock-split" 178 PRICE_SOURCE_INVOICE, // "user:invoice-post" 179 PRICE_SOURCE_TEMP, // "temporary" 180 PRICE_SOURCE_INVALID, // "invalid" 181 } PriceSource; 182 183 #define PRICE_TYPE_LAST "last" 184 #define PRICE_TYPE_UNK "unknown" 185 #define PRICE_TYPE_TRN "transaction" 186 /* ------------------ */ 187 /** @name Constructors 188 @{ */ 189 190 /** gnc_price_create - returns a newly allocated and initialized price 191 with a reference count of 1. */ 192 /*@ dependent @*/ 193 GNCPrice *gnc_price_create(QofBook *book); 194 195 /** gnc_price_clone - returns a newly allocated price that's a 196 content-wise duplicate of the given price, p. The returned clone 197 will have a reference count of 1. */ 198 GNCPrice *gnc_price_clone(GNCPrice* p, QofBook *book); 199 200 /** Return a newly-allocated price that's the inverse of the given price, p. 201 * 202 * Inverse means that the commodity and currency are swapped and the value is 203 * the numeric inverse of the original's. The source is set to PRICE_SOURCE_TEMP 204 * to prevent it being saved in the pricedb. 205 * @param p The price to invert 206 * @return a new price, with a ref-count of 1. Don't forget to unref it! 207 */ 208 GNCPrice *gnc_price_invert(GNCPrice *p); 209 210 /** @} */ 211 212 /* ------------------ */ 213 /** @name Memory Management 214 @{ */ 215 216 /** gnc_price_ref - indicate your need for a given price to stick 217 around (i.e. increase its reference count by 1). */ 218 void gnc_price_ref(GNCPrice *p); 219 220 /** gnc_price_unref - indicate you're finished with a price 221 (i.e. decrease its reference count by 1). */ 222 void gnc_price_unref(GNCPrice *p); 223 /** @} */ 224 225 /* ------------------ */ 226 /** @name Setters 227 * All of the setters store copies of the data 228 * given, with the exception of the commodity field which just stores 229 * the pointer given. It is assumed that commodities are a global 230 * resource and are pointer unique. 231 * 232 * Invocations of the setters should be wrapped with calls to 233 * gnc_price_begin_edit() and commit_edit(). The begin/commit 234 * calls help ensure that the local price db is synchronized with 235 * the backend. 236 @{ */ 237 void gnc_price_begin_edit (GNCPrice *p); 238 void gnc_price_commit_edit (GNCPrice *p); 239 240 void gnc_price_set_commodity(GNCPrice *p, gnc_commodity *c); 241 void gnc_price_set_currency(GNCPrice *p, gnc_commodity *c); 242 void gnc_price_set_time64(GNCPrice *p, time64 t); 243 void gnc_price_set_source(GNCPrice *p, PriceSource source); 244 void gnc_price_set_source_string(GNCPrice *p, const char* s); 245 void gnc_price_set_typestr(GNCPrice *p, const char* type); 246 void gnc_price_set_value(GNCPrice *p, gnc_numeric value); 247 /** @} */ 248 249 /* ------------------ */ 250 /** @name Getters 251 All of the getters return data that's internal 252 to the GNCPrice, not copies, so don't free these values. 253 @{ */ 254 255 GNCPrice * gnc_price_lookup (const GncGUID *guid, QofBook *book); 256 /*@ dependent @*/ 257 gnc_commodity * gnc_price_get_commodity(const GNCPrice *p); 258 /*@ dependent @*/ 259 gnc_commodity * gnc_price_get_currency(const GNCPrice *p); 260 time64 gnc_price_get_time64(const GNCPrice *p); 261 PriceSource gnc_price_get_source(const GNCPrice *p); 262 const char * gnc_price_get_source_string(const GNCPrice *p); 263 const char * gnc_price_get_typestr(const GNCPrice *p); 264 gnc_numeric gnc_price_get_value(const GNCPrice *p); 265 gboolean gnc_price_equal(const GNCPrice *p1, const GNCPrice *p2); 266 267 #define gnc_price_get_guid(X) qof_entity_get_guid(QOF_INSTANCE(X)) 268 #define gnc_price_return_guid(X) (*(qof_entity_get_guid(QOF_INSTANCE(X)))) 269 #define gnc_price_get_book(X) qof_instance_get_book(QOF_INSTANCE(X)) 270 /** @} */ 271 272 /** @name Internal/Debugging 273 @{ */ 274 /** This simple function can be useful for debugging the price code */ 275 void gnc_price_print(GNCPrice *db, FILE *f, int indent); 276 /** @} */ 277 /** @name Denominator Constants Price policy: In order to avoid rounding 278 * problems, currency prices (often called exchange rates) are saved in terms of 279 * the smaller currency, so that price > 1, with a fixed denominator of 280 * 1/1000. Commodity prices in currency are always expressed as value per unit 281 * of the commodity with a fixed denominator of the pricing currency's 282 * SCU * 10000. 283 */ 284 #define CURRENCY_DENOM 10000 285 #define COMMODITY_DENOM_MULT 10000 286 287 /* ================================================================ */ 288 /** @name GNCPrice lists 289 The database communicates multiple prices in and out via gnc price 290 lists. These are just time sorted GLists of GNCPrice pointers. 291 Functions for manipulating these lists are provided. These 292 functions are helpful in that they handle maintaining proper 293 reference counts on behalf of the price list for every price being 294 held in a given list. I.e. insert "refs" the prices being 295 inserted, remove and destroy "unref" the prices that will no 296 longer be referred to by the list. 297 @{ 298 */ 299 300 /** gnc_price_list_insert - insert a price into the given list, calling 301 gnc_price_ref on it during the process. */ 302 gboolean gnc_price_list_insert(PriceList **prices, GNCPrice *p, 303 gboolean check_dupl); 304 305 /** gnc_price_list_remove - remove the price, p, from the given list, 306 calling gnc_price_unref on it during the process. */ 307 gboolean gnc_price_list_remove(PriceList **prices, GNCPrice *p); 308 309 /** gnc_price_list_destroy - destroy the given price list, calling 310 gnc_price_unref on all the prices included in the list. */ 311 void gnc_price_list_destroy(PriceList *prices); 312 313 gboolean gnc_price_list_equal(PriceList *prices1, PriceList *prices2); 314 /** @} */ 315 /** @} end of the Price doxygen group */ 316 317 /* ================================================================ */ 318 /** @addtogroup PriceDB 319 Whenever a you store a price in the pricedb, the pricedb adds its 320 own reference to the price, so you can safely unref that price after 321 inserting it into the DB if you're finished with it otherwise. 322 323 Similarly, when the pricedb returns a price to you, either singly, 324 or in a price list, the price will have had a ref added for you, so 325 you only need to unref the price(s) when you're finished with 326 it/them. 327 @{ 328 */ 329 /** Data type */ 330 typedef struct gnc_price_db_s GNCPriceDB; 331 332 /** @brief Return the pricedb associated with the book 333 * @param book The QofBook holding the pricedb 334 * @return The GNCPriceDB associated with the book. 335 */ 336 GNCPriceDB * gnc_pricedb_get_db(QofBook *book); 337 /** @brief Return the pricedb via the Book's collection. 338 * @param col The QofCollection holding the pricedb 339 * @return The GNCPriceDB in the QofCollection 340 */ 341 GNCPriceDB * gnc_collection_get_pricedb(QofCollection *col); 342 343 /** @brief Destroy the given pricedb and unref all of the prices it contains. 344 * 345 * This may not deallocate all of those prices. Other code may still be holding 346 * references to them. 347 * @param db The pricedb to destroy. 348 */ 349 void gnc_pricedb_destroy(GNCPriceDB *db); 350 351 /** @brief Begin an edit. */ 352 void gnc_pricedb_begin_edit (GNCPriceDB *); 353 /** @brief Commit an edit. */ 354 void gnc_pricedb_commit_edit (GNCPriceDB *); 355 356 /** @brief Set flag to indicate whether duplication checks should be performed. 357 * 358 * Normally used at load time to speed up loading the pricedb. 359 * @param db The pricedb 360 * @param bulk_update TRUE to disable duplication checks, FALSE to enable them. 361 */ 362 void gnc_pricedb_set_bulk_update(GNCPriceDB *db, gboolean bulk_update); 363 364 /** @brief Add a price to the pricedb. 365 * 366 * You may drop your reference to the price (i.e. call unref) after this 367 * succeeds, whenever you're finished with the price. 368 * @param db The pricedb 369 * @param p The GNCPrice to add. 370 * @return TRUE if the price was added, FALSE otherwise. 371 */ 372 gboolean gnc_pricedb_add_price(GNCPriceDB *db, GNCPrice *p); 373 374 /** @brief Remove a price from the pricedb and unref the price. 375 * @param db The Pricedb 376 * @param p The price to remove. 377 */ 378 gboolean gnc_pricedb_remove_price(GNCPriceDB *db, GNCPrice *p); 379 380 typedef enum 381 { 382 PRICE_REMOVE_SOURCE_FQ = 1, // this flag is set when added by F:Q checked 383 PRICE_REMOVE_SOURCE_USER = 2, // this flag is set when added by the user checked 384 PRICE_REMOVE_SOURCE_APP = 4, // this flag is set when added by the app checked 385 PRICE_REMOVE_SOURCE_COMM = 8, // this flag is set when we have commodities selected 386 } PriceRemoveSourceFlags; 387 388 typedef enum 389 { 390 PRICE_REMOVE_KEEP_NONE, // keep none 391 PRICE_REMOVE_KEEP_LAST_WEEKLY, // leave last one of every week 392 PRICE_REMOVE_KEEP_LAST_MONTHLY, // leave last one of every month 393 PRICE_REMOVE_KEEP_LAST_QUARTERLY, // leave last one of every quarter 394 PRICE_REMOVE_KEEP_LAST_PERIOD, // leave last one of every annual period 395 PRICE_REMOVE_KEEP_SCALED, // leave one every week then one a month 396 } PriceRemoveKeepOptions; 397 398 /** @brief Remove and unref prices older than a certain time. 399 * @param db The pricedb 400 * @param comm_list A list of commodities 401 * @param fiscal_end_date the end date of the current accounting period 402 * @param cutoff The time before which prices should be deleted. 403 * @param source Whether Finance::Quote, user or all prices should be deleted. 404 * @param keep Whether scaled, monthly, weekly or no prices should be left. 405 * @return True if there were prices to process, False if not. 406 */ 407 gboolean gnc_pricedb_remove_old_prices(GNCPriceDB *db, GList *comm_list, 408 GDate *fiscal_end_date, time64 cutoff, 409 PriceRemoveSourceFlags source, 410 PriceRemoveKeepOptions keep); 411 412 /** @brief Find the most recent price between the two commodities. 413 * 414 * The returned GNCPrice may be in either direction so check to ensure that its 415 * value is correctly applied. 416 * @param db The pricedb 417 * @param commodity The first commodity 418 * @param currency The second commodity 419 * @return A GNCPrice or NULL if no price exists. 420 */ 421 GNCPrice * gnc_pricedb_lookup_latest(GNCPriceDB *db, 422 const gnc_commodity *commodity, 423 const gnc_commodity *currency); 424 425 /** @brief Find the most recent price between a commodity and all other 426 * commodities 427 * 428 * The returned GNCPrices may be in either direction so check to ensure that 429 * their values are correctly applied. 430 * @param db The pricedb 431 * @param commodity The commodity for which to obtain prices 432 * @return A PriceList of prices found, or NULL if none found. 433 */ 434 PriceList * gnc_pricedb_lookup_latest_any_currency(GNCPriceDB *db, 435 const gnc_commodity *commodity); 436 437 /** @brief Report whether the pricedb contains prices for one commodity in 438 * another. 439 * 440 * Does *not* check the reverse direction. 441 * @param db The pricedb to check 442 * @param commodity The commodity to check for the existence of prices 443 * @param currency The commodity in which prices are sought. If NULL reports all 444 * commodities. 445 * @return TRUE if matching prices are found, FALSE otherwise. 446 */ 447 gboolean gnc_pricedb_has_prices(GNCPriceDB *db, 448 const gnc_commodity *commodity, 449 const gnc_commodity *currency); 450 451 /** @brief Return all the prices for a given commodity in another. 452 * 453 * Does *not* retrieve reverse prices, i.e. prices of the second commodity in 454 * the first. 455 * @param db The pricedb from which to retrieve prices. 456 * @param commodity The commodity for which prices should be retrieved. 457 * @param currency The commodity in which prices should be quoted. If NULL, all 458 * prices in any commodity are included. 459 * @return A PriceList of matching prices or NULL if none were found. 460 */ 461 PriceList * gnc_pricedb_get_prices(GNCPriceDB *db, 462 const gnc_commodity *commodity, 463 const gnc_commodity *currency); 464 465 /** @brief Find the price between two commodities at a time64. 466 * 467 * The returned GNCPrice may be in either direction so check to ensure that its 468 * value is correctly applied. 469 * @param db The pricedb 470 * @param commodity The first commodity 471 * @param currency The second commodity 472 * @param t The time64 at which to retrieve the price. 473 * @return A GNCPrice or NULL if none matches. 474 */ 475 /* NOT USED */ 476 GNCPrice * gnc_pricedb_lookup_at_time64(GNCPriceDB *db, 477 const gnc_commodity *commodity, 478 const gnc_commodity *currency, 479 time64 t); 480 481 /** @brief Return the price between the two commodities on the indicated 482 * day. Note that the notion of day might be distorted by changes in timezone. 483 * 484 * The returned GNCPrice may be in either direction so check to ensure that its 485 * value is correctly applied. 486 * @param db The pricedb 487 * @param commodity The first commodity 488 * @param currency The second commodity 489 * @param t A time. The price returned will be in the same day as this time 490 * according to the local timezone. 491 * @return A GNCPrice or NULL on failure. 492 */ 493 GNCPrice * gnc_pricedb_lookup_day_t64(GNCPriceDB *db, 494 const gnc_commodity *commodity, 495 const gnc_commodity *currency, 496 time64 t); 497 498 /** @brief Return the price between the two commoditiesz nearest to the given 499 * time. 500 * 501 * The returned GNCPrice may be in either direction so check to ensure that its 502 * value is correctly applied. 503 * @param db The pricedb 504 * @param c The first commodity 505 * @param currency The second commodity 506 * @param t The time nearest to which the returned price should be. 507 * @return A GNCPrice or NULL if no prices exist between the two commodities. 508 */ 509 GNCPrice * gnc_pricedb_lookup_nearest_in_time64(GNCPriceDB *db, 510 const gnc_commodity *c, 511 const gnc_commodity *currency, 512 time64 t); 513 514 /** @brief Return the price nearest in time to that given between the given 515 * commodity and every other. 516 * 517 * The returned GNCPrices may be in either direction so check to ensure that 518 * their values are correctly applied. 519 * 520 * @param db, The pricedb 521 * @param c, The commodity for which prices should be obtained. 522 * @param t, The time nearest to which the prices should be obtained. 523 * @return A PriceList of prices for each commodity pair found or NULL if none 524 * are. 525 */ 526 PriceList * gnc_pricedb_lookup_nearest_in_time_any_currency_t64(GNCPriceDB *db, 527 const gnc_commodity *c, 528 time64 t); 529 530 /** @brief Return the nearest price between the given commodities before the 531 * given time. 532 * 533 * The returned GNCPrice may be in either direction so check to ensure that its 534 * value is correctly applied. 535 * @param db The pricedb 536 * @param c The first commodity 537 * @param currency The second commodity 538 * @param t The time before which to find the price 539 * @return A GNCPrice or NULL if no prices are found before t. 540 */ 541 GNCPrice * gnc_pricedb_lookup_nearest_before_t64 (GNCPriceDB *db, 542 const gnc_commodity *c, 543 const gnc_commodity *currency, 544 time64 t); 545 546 /** @brief Return the nearest price between the given commodity and any other 547 * before the given time. 548 * 549 * The returned GNCPrice may be in either direction so check to ensure that its 550 * value is correctly applied. 551 * @param db The pricedb 552 * @param c The commodity 553 * @param t The time before which to find prices 554 * @return A PriceList of prices for each commodity found or NULL if none are. 555 */ 556 PriceList * gnc_pricedb_lookup_nearest_before_any_currency_t64 (GNCPriceDB *db, 557 const gnc_commodity *c, 558 time64 t); 559 560 /** @brief Retrieve the price one currency to another using the price 561 * nearest to before the given time. 562 * @param pdb The pricedb 563 * @param orig_currency The commodity in which the balance is currently 564 * expressed 565 * @param new_currency The commodity to which the balance should be converted 566 * @param t The time to be used for for comparison 567 * @return A price, or gnc_numeric_zero if no price is available. 568 */ 569 gnc_numeric gnc_pricedb_get_nearest_before_price (GNCPriceDB *pdb, 570 const gnc_commodity *orig_currency, 571 const gnc_commodity *new_currency, 572 const time64 t); 573 574 /** @brief Retrieve the price one currency to another using the price 575 * nearest to the given time 576 * @param pdb The pricedb 577 * @param orig_currency The commodity in which the balance is currently 578 * expressed 579 * @param new_currency The commodity to which the balance should be converted 580 * @param t The time in which the nearest price should be used. 581 * @return A price, or gnc_numeric_zero if no price is available. 582 */ 583 gnc_numeric gnc_pricedb_get_nearest_price (GNCPriceDB *pdb, 584 const gnc_commodity *orig_currency, 585 const gnc_commodity *new_currency, 586 const time64 t); 587 588 /** @brief Retrieve the price one currency to another using the latest price 589 * @param pdb The pricedb 590 * @param orig_currency The commodity in which the balance is currently 591 * expressed 592 * @param new_currency The commodity to which the balance should be converted 593 * @return A price, or gnc_numeric_zero if no price is available. 594 */ 595 gnc_numeric gnc_pricedb_get_latest_price (GNCPriceDB *pdb, 596 const gnc_commodity *orig_currency, 597 const gnc_commodity *new_currency); 598 599 600 /** @brief Convert a balance from one currency to another using the most recent 601 * price between the two. 602 * @param pdb The pricedb 603 * @param balance The balance to be converted 604 * @param balance_currency The commodity in which the balance is currently 605 * expressed 606 * @param new_currency The commodity to which the balance should be converted 607 * @return A new balance or gnc_numeric_zero if no price is available. 608 */ 609 gnc_numeric 610 gnc_pricedb_convert_balance_latest_price(GNCPriceDB *pdb, 611 gnc_numeric balance, 612 const gnc_commodity *balance_currency, 613 const gnc_commodity *new_currency); 614 615 /** @brief Convert a balance from one currency to another using the price 616 * nearest to the given time. 617 * @param pdb The pricedb 618 * @param balance The balance to be converted 619 * @param balance_currency The commodity in which the balance is currently 620 * expressed 621 * @param new_currency The commodity to which the balance should be converted 622 * @param t The time nearest to which price should be used. 623 * @return A new balance or gnc_numeric_zero if no price is available. 624 */ 625 gnc_numeric 626 gnc_pricedb_convert_balance_nearest_price_t64(GNCPriceDB *pdb, 627 gnc_numeric balance, 628 const gnc_commodity *balance_currency, 629 const gnc_commodity *new_currency, 630 time64 t); 631 632 /** @brief Convert a balance from one currency to another using the price 633 * nearest to before the given time. 634 * @param pdb The pricedb 635 * @param balance The balance to be converted 636 * @param balance_currency The commodity in which the balance is currently 637 * expressed 638 * @param new_currency The commodity to which the balance should be converted 639 * @param t The time in which the last price before it should be used. 640 * @return A new balance or gnc_numeric_zero if no price is available. 641 */ 642 gnc_numeric 643 gnc_pricedb_convert_balance_nearest_before_price_t64 (GNCPriceDB *pdb, 644 gnc_numeric balance, 645 const gnc_commodity *balance_currency, 646 const gnc_commodity *new_currency, 647 time64 t); 648 649 typedef gboolean (*GncPriceForeachFunc)(GNCPrice *p, gpointer user_data); 650 651 /** @brief Call a GncPriceForeachFunction once for each price in db, until the 652 * function returns FALSE. 653 * 654 * If stable_order is not FALSE, make sure the ordering of the traversal is 655 * stable (i.e. the same order every time given the same db contents -- stable 656 * traversals may be less efficient). 657 * @param db The pricedb 658 * @param f The function to call 659 * @param user_data A data to pass to each invocation of f 660 * @param stable_order Ensure that the traversal is performed in the same order 661 * each time. 662 * @return TRUE if all calls to f succeeded (unstable) or if the order of 663 * processing was the same as the previous invocation (stable), FALSE otherwise. 664 */ 665 gboolean gnc_pricedb_foreach_price(GNCPriceDB *db, 666 GncPriceForeachFunc f, 667 gpointer user_data, 668 gboolean stable_order); 669 670 /** @brief Get the number of prices, in any currency, for a given commodity. 671 * @param db The pricedb 672 * @param c The commodity 673 * @return The number of prices in the database for this commody, zero if none 674 */ 675 int 676 gnc_pricedb_num_prices(GNCPriceDB *db, 677 const gnc_commodity *c); 678 679 /** @brief Get the nth price for the given commodity in reverse date order 680 * @param db The pricedb 681 * @param c The commodity whose nth price is needed 682 * @param n Zero based index of the price wanted 683 * @return The nth price for this commodity in reverse chronological order, without 684 * regard for what currency the price is in 685 */ 686 GNCPrice * 687 gnc_pricedb_nth_price (GNCPriceDB *db, 688 const gnc_commodity *c, 689 const int n); 690 691 void gnc_pricedb_nth_price_reset_cache (GNCPriceDB *db); 692 693 /* The following two convenience functions are used to test the xml backend */ 694 /** @brief Return the number of prices in the database. 695 * 696 * For XML Backend Testing 697 */ 698 guint gnc_pricedb_get_num_prices(GNCPriceDB *db); 699 700 /** @brief Test equality of two pricedbs 701 * 702 * For XML Backend Testing */ 703 gboolean gnc_pricedb_equal (GNCPriceDB *db1, GNCPriceDB *db2); 704 705 /** @name Internal/Debugging 706 @{ */ 707 /** This simple function can be useful for debugging the pricedb code */ 708 void gnc_pricedb_print_contents(GNCPriceDB *db, FILE *f); 709 /** @} */ 710 711 /** @name Price Parameter Names 712 * For use with QofQuery 713 */ 714 /**@{*/ 715 #define PRICE_COMMODITY "price-commodity" 716 #define PRICE_CURRENCY "price-currency" 717 #define PRICE_DATE "price-date" 718 #define PRICE_SOURCE "price-source" 719 #define PRICE_TYPE "price-type" 720 #define PRICE_VALUE "price-value" 721 /**@}*/ 722 723 /** @} */ 724 725 #ifdef __cplusplus 726 } /* extern "C" */ 727 #endif 728 729 #endif /* GNC_PRICEDB_H */ 730 /** @} */ 731 /** @} */ 732