![]() |
![]() |
![]() |
![]() |
||||
|
Other FPI Links:
FPI Server Guide |
Financial Posting Interface - Client Guide© 2001 Quik Sense Software By Scott K. MaxwellThe Financial Posting Interface allows any application to post transactions to any FPI-compliant account manager. This document will tell you how to interact with an FPI-compliant account manager or budget manager.FPI was created by Quik Sense Software as a generic way to post transactions to account managers and to update those transactions if necessary. I created FPI primarily to interface my Quik Budget product to account managers. Through FPI, users can create and modify transactions in Quik Budget and the same transactions will be created and modified in the user's account manager of choice. This avoids the problem of having to enter the transaction into multiple applications. However, FPI is not for Quik Budget alone.Through FPI, any application can post transactions with no knowledge of the internal workings of the current account manager. Quik Budget is also an FPI server so with one minor change you can post to Quik Budget as well. This document is aimed at authors or any application that could benefit from the ability to post transactions to the user's default account or budget manager. Features of FPIClients can:
Getting the FPI Client SDKAll of the code necessary for implementing FPI clients is available in the FPI Client SDK at http://quiksense.com/FPI/FPIClientSDK.zip. You probably want to extract the SDK into your main project directory. You will need to add PlugInBase.cpp and FFP.cpp to your project.source code. The FPI Client SDK is a subset of the FPI Server SDK so if you have already installed the FPI Server SDK, you do not need to download the client code. Loading the Plug-InTo try to load the plug-in do something like this:
The parameters are:
In most cases you will want to use the above line as is, replacing only the first two parameters. One exception is if you are trying to connect to the default budget manager (usually Quik Budget) instead of the default account manager. In that case, you would specify 'FPBM' for both the type and rscType. Some plug-ins are built into their main application database so you may wonder how this call will find them. The answer is in a bit of glue magic. The Load method searches for the 'FPAM' database. When it finds it, first it checks to see if the database is a resource database. If so, it uses it as the plug-in. If not, it reads the first 8 bytes from record zero to discover the type/creator of the actual plug-in database. It is the account manager's responsibility to create a database of type 'FPAM' that contains its type/creator. Financial Fixed-PointFPI uses Financial Fixed-Point (FFP) to specify all amounts. Internally, FFP consists of an Int32 and a UInt16. The UInt16 specifies how many decimals of precision are needed. This will almost always be either zero or two. $20.00 is represented as an Int32 of 2000 and a UInt16 of 2. 2000 lira is represented as an Int32 of 2000 and a UInt16 of 0. This allows for a good range of values, very high precision and good performance. You can create FFP objects from either integers or doubles. To create an FFP object representing $98.47, you would do this: FFP amount(9847,2); // Constructor taking an Int32 Or: FFP amount(98.47,2); // Constructor taking a double You can query the value with 4 methods: PostingIn many cases, the only thing an application will need to do is post transactions. That is done very simply with the Post method. Here is an example:
If the post is successful, it will return a unique ID that can be used to retrieve the transaction again later. If the post fails, it will return 0. The first parameter is a link ID. This would be a unique ID for the account manager to store if it wants to directly access the matching client record. If the plug-in does not know how to handle records from the client app, this should probably be zero. In the case of Quik Budget, the link ID is always the unique ID of the QB transaction that corresponds to this post. When QB posts transactions to an account manager, you always end up with the transaction existing in both the account manager and in QB. If you post to an account that does not exist, it is up to the account manager to decide what to do. It could create the account. If UI is allowed, it could ask the user if they want to create the account. Or it could just quit and return a unique ID of zero to indicate failure. The transferToAccount is specified if the transaction is a transfer. comment is often used for payee. note can generally be pretty large and can contain anything. The transaction number or type is used to indicate a check number, transaction number, or type of transaction such as 'ATM', 'Withdrawal', 'Deposit', etc. Category capability varies greatly among account managers. Some only have a single level of categories. Others allow for a second level or even unlimited levels of nested categories. In FPI, these are always represented as a single string with the different levels separated by a colon. For instance, "Dining:Lunch" would indicate the Lunch sub-category of Dining. It is entirely up to the account manager how it will handle categories. If the category has more levels than the account manager represents, it could just chop off the extra levels, create a new category containing the whole string or simply fail and return a 0. Ideally the account manager will not fail. Some account managers support transaction classes as well as categories. This is often used to specify 'Business' and 'Personal' or to specify the name of the person who spent the money. Nearly all account managers support the concept of cleared transactions. Only a few account managers support the concept of private transactions. When specifying the amount of the transaction, be sure to always specify a negative value for money spent, charged or withdrawn and a positive value for money deposited or credited. Expense amounts are always specified in Financial Fixed-Point as detailed above. The next three parameters are completely optional. They are rate, curSymbol, and curCode. The exchange rate is always a double representing the number to multiply the amount by to get the total in the native currency. If the native currency is US$, the transaction currency is British Pounds and the amount is 10 pounds, an exchange rate of 1.6 would indicate US$16.00. You can specify both the symbol and the code of the currency as different account managers and different users prefer to use one over the other. The symbol is the common symbol used for that currency such as '$'. The code is the 3-letter code used to indicate the currency such as 'USD'. The final parameter is also optional. It is the UIFlag. Valid values are fpiShowUINever, fpiShowUIAlways, and fpiShowUIIfIncomplete. The default is fpiShowUIIfIncomplete. Some account managers will ignore this parameter and never show UI. No account manager should ever show UI, though, if you specify fpiShowUINever or if you specified false for the UIIsOkay flag in the account manager constructor. Getting a Handle on a TransactionAfter you have posted a transaction, you may want to query or modify it later. To do that you need to create a handle to the transaction. That is done like this:
The uid is the one that you received previously from the Post method. The third parameter is true for writable and false for read-only. After you instantiate the AMTransaction object, always check to see if it is still Valid. An invalid transaction could mean anything but it most often indicates that the user deleted or purged the transaction. Querying a TransactionOnce you have a valid handle, you can use the Get method to retrieve the details. Get allows you to query all of the information that you set in the Post method and has almost exactly the same prototype. The main difference is that everything is a pointer. For instance, instead of: const char *commentGet expects: const char **comment This is very similar to the way DmRecordInfo and DmDatabaseInfo work. You simply pass in valid pointers for the items you wish to retrieve and NULL for those you don't need. All of the parameters default to NULL so if you only need to retrieve the comment field, you can do this:
The string data is managed by the AMTransaction object so be sure to copy the data to a safe location if you need it after the AMTransaction object's destructor is called. Modifying a TransactionThe Change method looks almost exactly like the Post method. It works in a very similar way to DmSetRecordInfo and DmSetDatabaseInfo. You simply pass in valid pointers for the items you wish to modify and NULL for those you don't need. All of the parameters default to NULL so if you only need to change the comment field, you can do this:
Change returns UInt32. The Change method could cause the transaction to be removed or to change unique ID. For instance, in Quik Budget, changing the category to one that does not exist as a QB wallet would cause QB to remove the transaction and return a UID of 0. Also, some account managers have multiple databases depending on the class or account of the transaction so the transaction could end up moving to a completely different database with a different unique ID seed. While it is possible to change only the amount or only the exchange rate, if you are dealing in foreign currencies, it is usually safest to pass in valid values for amount, rate and at least curSymbol. The reason for this is that some account managers don't bother to store the exchange rate and currency for the transaction so passing only one of these values could cause the account manager to do something unexpected. Adding a SplitOnce you have created a transaction, you may want to add splits to it. This is done with the AddSplit method. Here is an example:
The resulting transaction would be for $10 (6.92+3.08) and contain a split with two parts. Whenever you add a split, the original transaction becomes split 1 and the first AddSplit becomes split two. Notice that the AddSplit method takes a linkID and returns a unique ID. The reason for this is that each split can be accessed independently. For example, Quik Budget does not have true split support so the QB AddSplit method simply creates another transaction. An account manager with true split support could keep a separate QB link ID for each split. An account manager with true splits could return a different unique ID for each split by ORing the 24-bit transaction uid with an 8-bit split uid. Account MethodsFPI provides methods for querying various features of the account manager. For accounts, FPI provides:
UInt16 AccountIndexOf(const char *name); const char* GetAccountName(UInt16 index); UInt16 AccountCount(); Often you will want to get an index of the account in order to use the transaction number methods or simply to set the selection value for a list of accounts. AccountIndexOf will take a name and return a list index. If the account does not exist, it will return EOF (0xffff). GetAccountName converts that index back into a name. The memory is managed by the plug-in. AccountCount does as you would expect and returns the number of valid accounts. GetAccountList returns a list of the valid accounts.
This list can be passed directly to LstSetChoices. Transaction Number/Type MethodsThe Post and Change method allow you to specify a single string for number. This string can be either a number representing the transaction or check number, or it may be a string representing an account manager specific transaction type string. To find out what kind of strings the account manager expects, you can use the following methods:
bool SupportsTransactionNumber() const; bool AllowAnythingInTransactionNumber() const; Int32 GetAccountNextCheckNumber(UInt16 acctIndex); void SetAccountLastCheckNumber(UInt16 acctIndex, Int32 last); Some account managers do not support transaction numbers/types at all. In that case, you may want to change your user interface to not allow the user to enter data that won't be preserved anyway. AllowAnythingInTransactionNumber returns true if the account manager is able to store any arbitrary string for the type. False indicates that the account managers will only take expected strings. In Quik Budget, I don't allow the user to enter random text unless the account manager supports it. GetAccountNextCheckNumber will return the next check number for the specified account. Not all account managers store this. You can also call SetAccountLastCheckNumber to update the value. TransactionNumberStringCount returns the number of transaction types for the given account. GetTransactionNumberList returns a list of transaction
type strings for the given account. This list can be passed directly to
LstSetChoices. Category MethodsFPI supports infinitely nested category structures. To accomodate this, each of the category methods takes a root string. The prototypes look like this:
bool HasCategories(const char *root=NULL); UInt16 CategoryCount(const char *root=NULL); const char** GetCategoryList(const char *root=NULL); If you pass NULL to any of these methods, they will return data based on the root categories. If you pass a root string, the return values will refer to sub-categories of that root. For instance, to query the number of sub-categories of "Dining", you would do:
WARNING: As with the Account and Transaction Number methods, the client needs to do MemPtrFree on the block of data returned by GetCategoryList when the data is no longer needed. Class MethodsClasses are similar to categories but they are not usually nested. Classes seem to be supported by about half of the account managers currently available for the Palm platform. FPI provides the following:
bool SupportsClasses() const UInt16 ClassCount(); const char** GetClassList(); WARNING: As with the Account and Transaction Number methods, the client needs to do MemPtrFree on the block of data returned by GetClassList when the data is no longer needed. Miscellaneous Account Manager MethodsBesides getting lists of the account managers accounts, categories, etc, you may want to find out a bit more about the account manager you are connecting to. FPI provides the following:
UInt32 CreatorID() const; These are all self-explanatory with the exception of GetMasterCurrency. GetMasterCurrency expects the client to pass in pointers to two 6-byte buffers. You can use this to ensure that the base currency of your app matches that of the account manager and provide a warning to the user if it does not. Copyright © 2001, Quik Sense Software |
Home | Links
| Consulting | Privacy
Statement | Email us
Copyright © 1999-2006 Quik Sense Software. All rights reserved.