00001 /** Code to access the database containing the Transaction information 00002 00003 $Revision: 1.38 $ 00004 Last updated: $Date: 2002/12/17 22:52:00 $ 00005 00006 Copyright (C) 2000-2002 Vlad Mereuta <dizzy@users.sourceforge.net> 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 2 of the License, or 00011 any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program; if not, write to the Free Software 00020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00021 00022 #ifndef __TRANSACTIONS_DB__ 00023 #define __TRANSACTIONS_DB__ 00024 00025 #include "Database.h" 00026 #include "CoinsPref.h" 00027 00028 /// type of the Transaction database 00029 #define TRANSACTIONSDB_TYPE 'DATA' 00030 /// db name 00031 #define TRANSACTIONSDB_NAME "FreeCoins-Transactions" 00032 00033 /// intervals at which scheduled transactions can be repeated 00034 typedef enum { rep_day, rep_week, rep_month, rep_year } Repeat_interval; 00035 00036 00037 ///unpacked structure of an scheduled scheduled 00038 typedef struct { 00039 ///interval at which the transaction will repeat (day,week,etc.) 00040 Repeat_interval repeat_interval; 00041 /// day of the week/month on which transaction will repeat 00042 UInt16 repeat_on; 00043 ///frequency of the repetition (i.e. every n days) 00044 UInt16 frequency; 00045 ///number of times the transaction will be repeated (-1 - forever) 00046 Int16 repeat_times; 00047 ///the last date at which the transaction can be repeated (start date is stored in the transaction itself) 00048 DateType end_date; 00049 /// if true, the transaction is going to be recorded as cleared 00050 Boolean to_be_cleared; 00051 ///if true, end_date defines the end of this repeat transaction; otherwise repeat_times defines it. 00052 Boolean end_by_date; 00053 /** if true, recording of the transaction is paused (i.e. the actual date is still updated as usual, but no 00054 new transactions are created */ 00055 Boolean paused; 00056 } scheduledStructure; 00057 00058 /// data specific to scheduled transactions 00059 typedef struct { 00060 /// day of the week/month on which transaction will repeat 00061 UInt16 repeat_on; 00062 ///frequency of the repetition (i.e. every n days) 00063 UInt16 frequency; 00064 ///number of times the transaction will be repeated (-1 - forever) 00065 Int16 repeat_times; 00066 ///the last date at which the transaction can be repeated (start date is stored in the transaction itself) 00067 DateType end_date; 00068 ///true if newly created transactions are cleared 00069 unsigned to_be_cleared :1; 00070 ///if true, end_date defines the end of this repeat transaction; otherwise repeat_times defines it. 00071 unsigned end_by_date :1; 00072 /** if true, recording of the transaction is paused (i.e. the actual date is still updated as usual, but no 00073 new transactions are created */ 00074 unsigned paused :1; 00075 /// saved for future fields to keep binary compatibility 00076 unsigned reserved :13; 00077 ///interval at which the transaction will repeat (day,week,etc.) 00078 Repeat_interval repeat_interval; 00079 } packedScheduleStructure; 00080 00081 ///the packed structure of a transaction - see the unpacked struct for explanations 00082 typedef struct { 00083 ///date on which the transaction was made 00084 DateType date; 00085 /// number of splits assigned to this transaction 00086 UInt8 num_splits; 00087 ///the method of payment 00088 UInt8 method; 00089 ///per-transaction exchange rate (if another currency is involved). The rate relates 1st split to second split (order matters) 00090 double exchange_rate; 00091 /// indicates if the transaction is scheduled 00092 unsigned is_scheduled :1; 00093 /// saved for future fields to keep binary compatibility 00094 unsigned reserved :15; 00095 } packedTransactionStructure; 00096 00097 /** unpacked structure of an Transaction 00098 \note the fields related to scheduling should only be considered if the transaction itself is marked as 00099 schduled (i.e. is in the scheduled category) */ 00100 typedef struct { 00101 ///date on which the transaction was made 00102 DateType date; 00103 ///the method of payment 00104 Payment_method method; 00105 ///per-transaction exchange rate (if another currency is involved). The rate relates 1st split to second split (order matters) 00106 double exchange_rate; 00107 /// indicates if the transaction is scheduled 00108 Boolean is_scheduled; 00109 /// number of splits assigned to this transaction 00110 UInt8 num_splits; 00111 ///contains scheduling information 00112 scheduledStructure sched; 00113 /// person/company 00114 Char* payee; 00115 ///optional number to id this transaction (cheque number, order number, etc.) 00116 Char* num; 00117 /// note on the transaction 00118 Char* note; 00119 } transactionStructure; 00120 00121 /** class to manipulate the transactions database. 00122 \note Transactions can belong to one of the three categories: 00123 -# cleared 00124 -# uncleared 00125 -# scheduled 00126 Cleared/uncleared transaction should be treated (\em mostly) the same. The scheduled transactions 00127 contain the information for the transaction <b> to be scheduled </b>in the transaction body, and information 00128 about how this is to be done in the scheduled structure */ 00129 00130 class TransactionsDB : public Database <transactionStructure, packedTransactionStructure> 00131 { 00132 public: 00133 /// unpacks an Transaction record 00134 void unpackRecord (transactionStructure* trans, packedTransactionStructure* packed_trans) DB_SECTION2; 00135 00136 /** packs an Transaction record 00137 \todo we should be able to pack the scheduled structure to 0 or 1 bytes. I am not sure how 00138 viable this is (as we do not always know whether the transaction is scheduled or not when packing it ) but if it 00139 can be done it would save about 14 bytes for each transaction */ 00140 void packRecord (transactionStructure* trans, MemHandle db_entry) DB_SECTION2; 00141 00142 /** get the date of the transaction 00143 @param id record index 00144 @param pDate pointer to allocated date structure that will receive the date */ 00145 void getDate(UInt16 id, DateType * pDate) DB_SECTION2; 00146 00147 /** @return the value of the Cleared category */ 00148 UInt16 getClearedCategory() DB_SECTION2; 00149 00150 /** @return the value of the Cl/Uncl category */ 00151 UInt16 getClUnclCategory() DB_SECTION2; 00152 00153 /** @return the value of the Uncleared category */ 00154 UInt16 getUnclearedCategory() DB_SECTION2; 00155 00156 /** @return the value of the Scheduled category */ 00157 UInt16 getScheduledCategory() DB_SECTION2; 00158 00159 /** determine if the transaction is balanced 00160 @param trans_uid UID of the transaction 00161 @return true if the transaction is balanced, false otherwise */ 00162 Boolean isBalanced(UInt32 trans_uid) DB_SECTION2; 00163 00164 /** get the amount by which the transaction affects the given account 00165 @param trans_uid UID of the transaction 00166 @param acc_uid UID of the account 00167 @return signed amount */ 00168 Int32 getAmount(UInt32 trans_uid, UInt32 acc_uid) DB_SECTION2; 00169 00170 /** get the peer account in the given transaction from the point of view 00171 of the given account. Only makes sense for transactions that are 00172 split two ways, i.e. simple transfers. 00173 @param trans_uid UID of the transaction 00174 @param acc_uid UID of the account 00175 @return UID of the peer account */ 00176 UInt32 getPeerAcc(UInt32 trans_uid, UInt32 acc_uid) DB_SECTION2; 00177 00178 /** checks whether a record is cleared or not 00179 @param id id of the record to be checked 00180 @return true if the record is cleared, false otherwise */ 00181 Boolean isCleared(UInt16 id) DB_SECTION2; 00182 00183 /** checks whether a record is to be cleared or not 00184 @param id id of the record to be checked 00185 @return true if the record is set to be cleared in the future, false otherwise */ 00186 Boolean willBeCleared(UInt16 id) DB_SECTION2; 00187 00188 /** checks whether a transaction is scheduled or not by checking the record category 00189 @param id the id of the transaction to be checked 00190 @return true if it is scheduled, false othewise */ 00191 Boolean isScheduled(UInt16 id) DB_SECTION2; 00192 00193 /** set a record category to cleared 00194 @param id id of the record to be set */ 00195 void clearRecord(UInt16 id) DB_SECTION2; 00196 00197 /** set a record category to uncleared 00198 @param id id of the record to be set */ 00199 void unclearRecord(UInt16 id) DB_SECTION2; 00200 00201 /// initialize the database 00202 TransactionsDB() DB_SECTION2; 00203 00204 ///init the Transactions DB with some default records 00205 void initializeTransactions() DB_SECTION2; 00206 00207 /** creates a new record and update the balances of the two involved accounts 00208 @param s pointer to the structure containing the transaction data 00209 @param cleared boolean which indicates the status of the record. The function will place the record in the right category 00210 @param scheduled (which defaults to false if no value is given) indicates whether the transaction is scheduled or not. the 00211 cateogry will be set to the right one 00212 @return id of the newly created record */ 00213 UInt16 newRecord(transactionStructure* s, Boolean cleared, Boolean scheduled = false) DB_SECTION2; 00214 00215 /** deletes a record, given its id 00216 @param id the id of the record to be deleted 00217 @param keep_balance if true then the balances of the accounts involved in the transaction will *not* be changed */ 00218 bool deleteRecord(UInt16 id, Boolean keep_balance = false) DB_SECTION2; 00219 00220 /** Compares two packed transaction structures. 00221 For parameters see the PalmOS reference */ 00222 static Int16 compareRecords(packedTransactionStructure* rec1,packedTransactionStructure* rec2,Int16 other,SortRecordInfoPtr sr1,SortRecordInfoPtr sr2,MemHandle app_info) DB_SECTION2; 00223 00224 /** This function deletes all the transactions earlier than the given date. 00225 This should not change the existing balances for the accounts involved. Both cleared and uncleared transactions are removed, but 00226 the scheduled ones are kept 00227 \todo message informing the operation is being performed while this function runs 00228 \warning should probably set the archived bit on deletion rather than removing the records. this is true for all the destructive operations, but 00229 there is really no point in doing so before the conduit reaches a working state 00230 \note scheduled transaction are not deleted on purging 00231 @param last_date the last date up to which the transactions are to be deleted */ 00232 void purgeTransactions(DateType last_date) DB_SECTION2; 00233 00234 /** records the next date in the associated transaction (in relation to the date already recorded) 00235 if we have repeated the record enought times, the record is deleted 00236 @param id id of the record for which to find the next date 00237 @return true if the record has been deleted, false otherwise */ 00238 Boolean calculateNextDate(UInt16 id) DB_SECTION2; 00239 00240 /** scans through all the scheduled transactions, and if there are any due they are recorded and their next occurance date 00241 is updated 00242 @param force if true then the current date is ignored the update is perfomed anyway 00243 @return true if updates were made, false otherwise */ 00244 Boolean schedule(Boolean force=false) DB_SECTION2; 00245 00246 /** schedule the first scheduled record that is due */ 00247 Boolean scheduleNextRecord() DB_SECTION2; 00248 00249 /** returns the total for the scheduled transactions in a given account 00250 @param account_uid uid of the account to be checked 00251 @return the sum of the amounts of all scheduled transaction for that account */ 00252 Int32 getScheduledTotal(UInt32 account_uid) DB_SECTION2; 00253 00254 /** creates a new (unscheduled) record from a scheduled one, leaving the original scheduled transaction unaltered 00255 @param record_uid uid of the scheduled transaction to be recorded 00256 @param mod_date if true, the date of the new record is going to be set to today. Otherwise the date is left 00257 unaltered 00258 @return uid of the new record that has been created */ 00259 UInt32 recordScheduledRecord(UInt32 record_uid, bool mod_date) DB_SECTION2; 00260 00261 /** Returns the first transaction with an id equal or higher than the given one which has a payee string which starts the same (case insensitive) as the given string and 00262 has as source account the account which is currently used 00263 @param p start of the payee string which is to be mached by an existing transaction 00264 @param start_id id from where to start looking for matching transactions; it defaults to 0. Note that the given ID is checked aswell! 00265 @return the UInt16 id of the first matched transaction or -1 if no such transaction was found */ 00266 Int32 getTransactionByPayeeAndAcc(Char* p, UInt16 start_id) DB_SECTION2; 00267 00268 /** Returns the first transaction with an id equal or higher than the given one which has a payee string which starts the same (case insensitive) as the given string 00269 @param p start of the payee string which is to be mached by an existing transaction 00270 @param start_id id from where to start looking for matching transactions; it defaults to 0. Note that the given ID is checked aswell! 00271 @return the UInt16 id of the first matched transaction or -1 if no such transaction was found 00272 @param want_cur_acc if true, the function will attempt to return a transaction with the same source account as the current account. If it fails to find such a transaction it 00273 returns the first transaction from any acount which matches the given payee */ 00274 Int32 getTransactionByPayee(Char* p, UInt16 start_id = 0, Boolean want_cur_acc = false) DB_SECTION2; 00275 }; 00276 00277 extern TransactionsDB* transactions_db; 00278 00279 #endif