| qof_book_merge: 'Query Object Framework: Design and direction.' | ||
|---|---|---|
| Prev | Chapter 5. QSF - QOF Serialization Format. | Next |
Until tools can be developed to design the map, each QSF map will have to be edited by hand. The process requires detailed knowledge of the QOF objects of both applications as well as a general understanding the source code for each program. This section contains the notes I used to create the pilot-qsf-GnuCashInvoice QSF map.
The expenses QOF object in pilot-link can be described as follows. This text is copied directly from the QofObject and QofClass parameter definitions in the source code.
struct tm date EXP_DATE, QOF_TYPE_DATE,
enum ExpenseType type EXP_TYPE, QOF_TYPE_INT32,
enum ExpensePayment payment EXP_PAYMENT, QOF_TYPE_INT32,
int currency EXP_CURRENCY, QOF_TYPE_INT32,
char *amount EXP_AMOUNT, QOF_TYPE_STRING,
char *vendor EXP_VENDOR, QOF_TYPE_STRING,
char *city EXP_CITY, QOF_TYPE_STRING,
char *attendees EXP_ATTENDEES, QOF_TYPE_STRING,
char *note EXP_NOTE, QOF_TYPE_STRING,
enum ExpenseType {
etAirfare, etBreakfast, etBus, etBusinessMeals,
etCarRental, etDinner,
etEntertainment, etFax, etGas, etGifts, etHotel,
etIncidentals,
etLaundry,
etLimo, etLodging, etLunch, etMileage, etOther, etParking,
etPostage,
etSnack, etSubway, etSupplies, etTaxi, etTelephone, etTips,
etTolls,
etTrain
};
enum ExpensePayment {
epAmEx, epCash, epCheck, epCreditCard, epMasterCard,
epPrepaid, epVISA,
epUnfiled
};
Note that although a struct tm in the code, date is considered as a standard QOF_TYPE_DATE - a Timespec. The use of an integer for currency and a string for the amount could also cause problems in GnuCash.
Date is used in the query to obtain the expenses for the days covered by the invoice. Date maps to gncInvoice::INVOICE_OPENED
Type is used to determine any mileage rate, to calculate other reimbursement parameters and to complete the description of this transaction within the invoice. Type(as string) maps to Transaction::TRANS_DESCRIPTION. Type (as an enum) is used to retrieve the rate that maps to gncEntry::ENTRY_IPRICE.
Payment indicates the method of payment. This can be incorporated into the description. In other circumstances, it would be used to set the GnuCash account to be debited but that will not be used for my test case involving invoices. Other maps can use this field as the user sees fit.
currency needs experimentation to see how it is used by pilot-link and how it can be translated into GnuCash. With gncCommodity still being a problem within QOF, this may simply be left to the GnuCash default.
Amount - interesting that it is used as a string, it will need careful conversion to a gnc_numeric. This will be used as the Amount of the expenses transaction within the invoice. Currency problems could reappear here too. Amount maps to gncEntry::ENTRY_QTY.
Vendor - this may appear optional but could be an important check that the correct expense is being allocated to the correct invoice by comparing with the gncJob or gncCustomer. Not directly mapped.
City - again, can be used to check that the correct expense has been identified by date.
Attendees - not used in this test map, may be useful to others.
Note - not used in this test map, may be useful to others.
Datebook is defined as follows (items not used in the map omitted):
int event; /* Is this a timeless event? */ DATEBOOK_EVENT, QOF_TYPE_INT32, struct tm begin; /* When does this appointment start? */ DATEBOOK_BEGIN, QOF_TYPE_DATE, struct tm end; /* When does this appointment end? */ DATEBOOK_END, QOF_TYPE_DATE, enum repeatTypes repeatType; /* How should this appointment be repeated, if at all?*/ DATEBOOK_REPEAT_TYPE, QOF_TYPE_INT32, int repeatForever; /* Do the repetitions end at some date or carry on forever? */ DATEBOOK_REPEAT_FOREVER, QOF_TYPE_INT32, (this may be changed to QOF_TYPE_BOOLEAN). struct tm repeatEnd; /* What date do they end on? */ DATEBOOK_REPEAT_END, QOF_TYPE_DATE, int repeatFrequency; /* Should I skip an interval for each repetition? */ DATEBOOK_REPEAT_FREQUENCY, QOF_TYPE_INT32, enum DayOfMonthType repeatDay; /* for repeatMonthlyByDay */ DATEBOOK_REPEAT_DAY, QOF_TYPE_INT32, int repeatWeekstart; /* What day did the user decide starts the week? */ DATEBOOK_REPEAT_WEEK_START, QOF_TYPE_INT32, int exceptions; /* How many repetitions are there to be ignored? */ DATEBOOK_EXCEPTIONS, QOF_TYPE_INT32, struct tm *exception; /* What are they? */ DATEBOOK_EXCEPTION, QOF_TYPE_DATE, char *description; /* What is the description of this appointment? */ DATEBOOK_DESCRIPTION, QOF_TYPE_STRING, char *note; /* Is there a note to go along with it? */ DATEBOOK_NOTE, QOF_TYPE_STRING,
Timeless events are anniversaries, birthdays or other marker events that are set in the PDA as 'No time'. If event is set, the datebook object needs to be ignored for the purposes of an invoice.
begin and end will be used to calculate the number of hours to charge on the invoice. end - begin maps to gncEntry::ENTRY_QTY.
Repeating events may need care to identify the actual date of the event. Check the repeatType: repeatNone, repeatDaily, repeatWeekly, repeatMonthlyByDay, repeatMonthlyByDate or repeatYearly. Check the repeatForever value and the repeatEnd Timespec. Check the repeatFrequency, repeatDay and repeatWeekStart only if appropriate. If still within the repeatEnd, check if any dates are to be ignored and find out which ones. Finally, if the event survives all checks, map to gncInvoice::INVOICE_OPENED and gncEntry::ENTRY_DATE, gncEntry::ENTRY_DATE_ENTERED. (Other maps are free to map to just one or two of those.)
Description should match with the gncJob but this is a simple check.
Some items are not read by pilot-link as of 0.11.8. There is a category setting and a Location setting. User intervention will be required to confirm that the correct event has been selected, in the absence of either of these settings, if there is any mis-match in the Description.
Finally for this map, the AddressBook object is defined as a list of all strings:
(concat(ADDR_FIRST_NAME,ADDR_LAST_NAME) <==> ADDRESS_NAME || ADDR_COMPANY, <==> ADDRESS_NAME) ADDR_PHONE_ONE, <==> ADDRESS_PHONE (if regexp matches) ADDR_PHONE_TWO, <==> ADDRESS_FAX (if regexp matches) ADDR_PHONE_THREE, <==> ADDRESS_EMAIL (if regexp matches) ADDR_PHONE_FOUR, ADDR_PHONE_FIVE, ADDR_ADDRESS, <==> ADDRESS_ONE ADDR_CITY, <==> ADDRESS_TWO ADDR_STATE, <==> ADDRESS_THREE ADDR_ZIP, <==> ADDRESS_FOUR (if regexp matches) ADDR_COUNTRY, ADDR_TITLE, ADDR_CUSTOM_ONE, ADDR_CUSTOM_TWO, ADDR_CUSTOM_THREE, ADDR_CUSTOM_FOUR, ADDR_NOTE, ADDR_CATEGORY,
Note how this map is not fixed. In the last summary, I've tried to summarise the process using familiar symbols. The map will be intelligent and will always check the incoming content against a regular expression of what the mapped field normally contains. In most cases, an address is only created once. More commonly, the details of the address will be used to check against the existing addresses to locate the correct customer. As invoices will be almost always new items, a GUID check is not practical. It will also be possible to map the custom fields on a per-user basis, perhaps to contain the rates to charge etc.