private void init(@Nullable SQLiteDatabase db) { if (db == null) { mAccountsDbAdapter = AccountsDbAdapter.getInstance(); mTransactionsDbAdapter = TransactionsDbAdapter.getInstance(); mScheduledActionsDbAdapter = ScheduledActionDbAdapter.getInstance(); mCommoditiesDbAdapter = CommoditiesDbAdapter.getInstance(); mPricesDbAdapter = PricesDbAdapter.getInstance(); } else { mTransactionsDbAdapter = new TransactionsDbAdapter(db, new SplitsDbAdapter(db)); mAccountsDbAdapter = new AccountsDbAdapter(db, mTransactionsDbAdapter); mScheduledActionsDbAdapter = new ScheduledActionDbAdapter(db); mCommoditiesDbAdapter = new CommoditiesDbAdapter(db); mPricesDbAdapter = new PricesDbAdapter(db); } mContent = new StringBuilder(); mAccountList = new ArrayList<>(); mAccountMap = new HashMap<>(); mTransactionList = new ArrayList<>(); mScheduledActionsList = new ArrayList<>(); mTemplatAccountList = new ArrayList<>(); mTemplateTransactions = new ArrayList<>(); mTemplateAccountToTransactionMap = new HashMap<>(); mAutoBalanceSplits = new ArrayList<>(); mPriceList = new ArrayList<>(); }
/** Extracts arguments passed to the view and initializes necessary adapters and cursors */ private void initArgs() { mAccountsDbAdapter = AccountsDbAdapter.getInstance(); Bundle args = getArguments(); mAccountUID = ((FormActivity) getActivity()).getCurrentAccountUID(); mBaseAmount = new BigDecimal(args.getString(UxArgument.AMOUNT_STRING)); String conditions = "(" + DatabaseSchema.AccountEntry.COLUMN_HIDDEN + " = 0 AND " + DatabaseSchema.AccountEntry.COLUMN_PLACEHOLDER + " = 0" + ")"; mCursor = mAccountsDbAdapter.fetchAccountsOrderedByFullName(conditions, null); mCommodity = CommoditiesDbAdapter.getInstance() .getCommodity(mAccountsDbAdapter.getCurrencyCode(mAccountUID)); }
/** * Opening an XML file should set the default currency to that used by the most accounts in the * file */ @Test public void importingXml_shouldSetDefaultCurrency() { GnuCashApplication.setDefaultCurrencyCode("JPY"); assertThat(GnuCashApplication.getDefaultCurrencyCode()).isEqualTo("JPY"); assertThat(Commodity.DEFAULT_COMMODITY).isEqualTo(Commodity.JPY); mAccountsDbAdapter.deleteAllRecords(); loadDefaultAccounts(); assertThat(GnuCashApplication.getDefaultCurrencyCode()).isNotEqualTo("JPY"); Currency currency = Currency.getInstance(GnuCashApplication.getDefaultLocale()); String expectedCode = currency.getCurrencyCode(); Commodity expectedDefaultCommodity = CommoditiesDbAdapter.getInstance().getCommodity(expectedCode); assertThat(GnuCashApplication.getDefaultCurrencyCode()).isEqualTo(expectedCode); assertThat(Commodity.DEFAULT_COMMODITY).isEqualTo(expectedDefaultCommodity); System.out.println("Default currency is now: " + expectedCode); }
@Override public void endElement(String uri, String localName, String qualifiedName) throws SAXException { String characterString = mContent.toString().trim(); if (mIgnoreElement != null) { // Ignore everything inside if (qualifiedName.equals(mIgnoreElement)) { mIgnoreElement = null; } mContent.setLength(0); return; } switch (qualifiedName) { case GncXmlHelper.TAG_NAME: mAccount.setName(characterString); mAccount.setFullName(characterString); break; case GncXmlHelper.TAG_ACCT_ID: mAccount.setUID(characterString); break; case GncXmlHelper.TAG_TYPE: AccountType accountType = AccountType.valueOf(characterString); mAccount.setAccountType(accountType); mAccount.setHidden(accountType == AccountType.ROOT); // flag root account as hidden break; case GncXmlHelper.TAG_COMMODITY_SPACE: if (characterString.equals("ISO4217")) { mISO4217Currency = true; } else { // price of non-ISO4217 commodities cannot be handled mPrice = null; } break; case GncXmlHelper.TAG_COMMODITY_ID: String currencyCode = mISO4217Currency ? characterString : NO_CURRENCY_CODE; if (mAccount != null) { mAccount.setCurrency(Currency.getInstance(currencyCode)); } if (mTransaction != null) { mTransaction.setCurrencyCode(currencyCode); } if (mPrice != null) { if (mPriceCommodity) { mPrice.setCommodityUID(mCommoditiesDbAdapter.getCommodityUID(currencyCode)); mPriceCommodity = false; } if (mPriceCurrency) { mPrice.setCurrencyUID(mCommoditiesDbAdapter.getCommodityUID(currencyCode)); mPriceCurrency = false; } } break; case GncXmlHelper.TAG_ACCT_DESCRIPTION: mAccount.setDescription(characterString); break; case GncXmlHelper.TAG_PARENT_UID: mAccount.setParentUID(characterString); break; case GncXmlHelper.TAG_ACCOUNT: if (!mInTemplates) { // we ignore template accounts, we have no use for them mAccountList.add(mAccount); mAccountMap.put(mAccount.getUID(), mAccount); // check ROOT account if (mAccount.getAccountType() == AccountType.ROOT) { if (mRootAccount == null) { mRootAccount = mAccount; } else { throw new SAXException("Multiple ROOT accounts exist in book"); } } // prepare for next input mAccount = null; // reset ISO 4217 flag for next account mISO4217Currency = false; } break; case GncXmlHelper.TAG_SLOT_KEY: switch (characterString) { case GncXmlHelper.KEY_PLACEHOLDER: mInPlaceHolderSlot = true; break; case GncXmlHelper.KEY_COLOR: mInColorSlot = true; break; case GncXmlHelper.KEY_FAVORITE: mInFavoriteSlot = true; break; case GncXmlHelper.KEY_NOTES: mIsNote = true; break; case GncXmlHelper.KEY_DEFAULT_TRANSFER_ACCOUNT: mInDefaultTransferAccount = true; break; case GncXmlHelper.KEY_EXPORTED: mInExported = true; break; case GncXmlHelper.KEY_SPLIT_ACCOUNT_SLOT: mInSplitAccountSlot = true; break; case GncXmlHelper.KEY_CREDIT_NUMERIC: mInCreditNumericSlot = true; break; case GncXmlHelper.KEY_DEBIT_NUMERIC: mInDebitNumericSlot = true; break; } break; case GncXmlHelper.TAG_SLOT_VALUE: if (mInPlaceHolderSlot) { // Log.v(LOG_TAG, "Setting account placeholder flag"); mAccount.setPlaceHolderFlag(Boolean.parseBoolean(characterString)); mInPlaceHolderSlot = false; } else if (mInColorSlot) { // Log.d(LOG_TAG, "Parsing color code: " + characterString); String color = characterString.trim(); // Gnucash exports the account color in format #rrrgggbbb, but we need only #rrggbb. // so we trim the last digit in each block, doesn't affect the color much if (!color.equals("Not Set")) { // avoid known exception, printStackTrace is very time consuming if (!Pattern.matches(Account.COLOR_HEX_REGEX, color)) color = "#" + color.replaceAll(".(.)?", "$1").replace("null", ""); try { if (mAccount != null) mAccount.setColorCode(color); } catch (IllegalArgumentException ex) { // sometimes the color entry in the account file is "Not set" instead of just blank. // So catch! Log.e( LOG_TAG, "Invalid color code '" + color + "' for account " + mAccount.getName()); Crashlytics.logException(ex); } } mInColorSlot = false; } else if (mInFavoriteSlot) { mAccount.setFavorite(Boolean.parseBoolean(characterString)); mInFavoriteSlot = false; } else if (mIsNote) { if (mTransaction != null) { mTransaction.setNote(characterString); mIsNote = false; } } else if (mInDefaultTransferAccount) { mAccount.setDefaultTransferAccountUID(characterString); mInDefaultTransferAccount = false; } else if (mInExported) { if (mTransaction != null) { mTransaction.setExported(Boolean.parseBoolean(characterString)); mInExported = false; } } else if (mInTemplates && mInSplitAccountSlot) { mSplit.setAccountUID(characterString); mInSplitAccountSlot = false; } else if (mInTemplates && mInCreditNumericSlot) { handleEndOfTemplateNumericSlot(characterString, TransactionType.CREDIT); } else if (mInTemplates && mInDebitNumericSlot) { handleEndOfTemplateNumericSlot(characterString, TransactionType.DEBIT); } break; // ================ PROCESSING OF TRANSACTION TAGS ===================================== case GncXmlHelper.TAG_TRX_ID: mTransaction.setUID(characterString); break; case GncXmlHelper.TAG_TRN_DESCRIPTION: mTransaction.setDescription(characterString); break; case GncXmlHelper.TAG_TS_DATE: try { if (mIsDatePosted && mTransaction != null) { mTransaction.setTime(GncXmlHelper.parseDate(characterString)); mIsDatePosted = false; } if (mIsDateEntered && mTransaction != null) { Timestamp timestamp = new Timestamp(GncXmlHelper.parseDate(characterString)); mTransaction.setCreatedTimestamp(timestamp); mIsDateEntered = false; } if (mPrice != null) { mPrice.setDate(new Timestamp(GncXmlHelper.parseDate(characterString))); } } catch (ParseException e) { Crashlytics.logException(e); String message = "Unable to parse transaction time - " + characterString; Log.e(LOG_TAG, message + "\n" + e.getMessage()); Crashlytics.log(message); throw new SAXException(message, e); } break; case GncXmlHelper.TAG_RECURRENCE_PERIOD: // for parsing of old backup files mRecurrencePeriod = Long.parseLong(characterString); mTransaction.setTemplate(mRecurrencePeriod > 0); break; case GncXmlHelper.TAG_SPLIT_ID: mSplit.setUID(characterString); break; case GncXmlHelper.TAG_SPLIT_MEMO: mSplit.setMemo(characterString); break; case GncXmlHelper.TAG_SPLIT_VALUE: try { // The value and quantity can have different sign for custom currency(stock). // Use the sign of value for split, as it would not be custom currency String q = characterString; if (q.charAt(0) == '-') { mNegativeQuantity = true; q = q.substring(1); } else { mNegativeQuantity = false; } mValue = GncXmlHelper.parseSplitAmount(characterString).abs(); // use sign from quantity } catch (ParseException e) { String msg = "Error parsing split quantity - " + characterString; Crashlytics.log(msg); Crashlytics.logException(e); throw new SAXException(msg, e); } break; case GncXmlHelper.TAG_SPLIT_QUANTITY: // delay the assignment of currency when the split account is seen try { mQuantity = GncXmlHelper.parseSplitAmount(characterString).abs(); } catch (ParseException e) { String msg = "Error parsing split quantity - " + characterString; Crashlytics.log(msg); Crashlytics.logException(e); throw new SAXException(msg, e); } break; case GncXmlHelper.TAG_SPLIT_ACCOUNT: if (!mInTemplates) { // this is intentional: GnuCash XML formats split amounts, credits are negative, debits // are positive. mSplit.setType(mNegativeQuantity ? TransactionType.CREDIT : TransactionType.DEBIT); // the split amount uses the account currency mSplit.setQuantity(new Money(mQuantity, getCurrencyForAccount(characterString))); // the split value uses the transaction currency mSplit.setValue(new Money(mValue, mTransaction.getCurrency())); mSplit.setAccountUID(characterString); } else { if (!mIgnoreTemplateTransaction) mTemplateAccountToTransactionMap.put(characterString, mTransaction.getUID()); } break; case GncXmlHelper.TAG_TRN_SPLIT: mTransaction.addSplit(mSplit); break; case GncXmlHelper.TAG_TRANSACTION: mTransaction.setTemplate(mInTemplates); Split imbSplit = mTransaction.getAutoBalanceSplit(); if (imbSplit != null) { mAutoBalanceSplits.add(imbSplit); } if (mInTemplates) { if (!mIgnoreTemplateTransaction) mTemplateTransactions.add(mTransaction); } else { mTransactionList.add(mTransaction); } if (mRecurrencePeriod > 0) { // if we find an old format recurrence period, parse it mTransaction.setTemplate(true); ScheduledAction scheduledAction = ScheduledAction.parseScheduledAction(mTransaction, mRecurrencePeriod); mScheduledActionsList.add(scheduledAction); } mRecurrencePeriod = 0; mIgnoreTemplateTransaction = true; mTransaction = null; break; case GncXmlHelper.TAG_TEMPLATE_TRANSACTIONS: mInTemplates = false; break; // ========================= PROCESSING SCHEDULED ACTIONS ================================== case GncXmlHelper.TAG_SX_ID: mScheduledAction.setUID(characterString); break; case GncXmlHelper.TAG_SX_NAME: if (characterString.equals(ScheduledAction.ActionType.BACKUP.name())) mScheduledAction.setActionType(ScheduledAction.ActionType.BACKUP); else mScheduledAction.setActionType(ScheduledAction.ActionType.TRANSACTION); break; case GncXmlHelper.TAG_SX_ENABLED: mScheduledAction.setEnabled(characterString.equals("y")); break; case GncXmlHelper.TAG_SX_AUTO_CREATE: mScheduledAction.setAutoCreate(characterString.equals("y")); break; case GncXmlHelper.TAG_SX_NUM_OCCUR: mScheduledAction.setTotalFrequency(Integer.parseInt(characterString)); break; case GncXmlHelper.TAG_RX_MULT: mRecurrenceMultiplier = Integer.parseInt(characterString); break; case GncXmlHelper.TAG_RX_PERIOD_TYPE: try { PeriodType periodType = PeriodType.valueOf(characterString.toUpperCase()); periodType.setMultiplier(mRecurrenceMultiplier); if (mScheduledAction != null) // there might be recurrence tags for bugdets and other stuff mScheduledAction.setPeriod(periodType); } catch (IllegalArgumentException ex) { // the period type constant is not supported String msg = "Unsupported period constant: " + characterString; Log.e(LOG_TAG, msg); Crashlytics.logException(ex); mIgnoreScheduledAction = true; } break; case GncXmlHelper.TAG_GDATE: try { long date = GncXmlHelper.DATE_FORMATTER.parse(characterString).getTime(); if (mIsScheduledStart && mScheduledAction != null) { mScheduledAction.setCreatedTimestamp(new Timestamp(date)); mIsScheduledStart = false; } if (mIsScheduledEnd && mScheduledAction != null) { mScheduledAction.setEndTime(date); mIsScheduledEnd = false; } if (mIsLastRun && mScheduledAction != null) { mScheduledAction.setLastRun(date); mIsLastRun = false; } if (mIsRecurrenceStart && mScheduledAction != null) { mScheduledAction.setStartTime(date); mIsRecurrenceStart = false; } } catch (ParseException e) { String msg = "Error parsing scheduled action date " + characterString; Log.e(LOG_TAG, msg + e.getMessage()); Crashlytics.log(msg); Crashlytics.logException(e); throw new SAXException(msg, e); } break; case GncXmlHelper.TAG_SX_TEMPL_ACCOUNT: if (mScheduledAction.getActionType() == ScheduledAction.ActionType.TRANSACTION) { mScheduledAction.setActionUID(mTemplateAccountToTransactionMap.get(characterString)); } else { mScheduledAction.setActionUID(UUID.randomUUID().toString().replaceAll("-", "")); } break; case GncXmlHelper.TAG_SCHEDULED_ACTION: if (mScheduledAction.getActionUID() != null && !mIgnoreScheduledAction) { mScheduledActionsList.add(mScheduledAction); int count = generateMissedScheduledTransactions(mScheduledAction); Log.i(LOG_TAG, String.format("Generated %d transactions from scheduled action", count)); } mRecurrenceMultiplier = 1; // reset it, even though it will be parsed from XML each time mIgnoreScheduledAction = false; break; // price table case GncXmlHelper.TAG_PRICE_ID: mPrice.setUID(characterString); break; case GncXmlHelper.TAG_PRICE_SOURCE: if (mPrice != null) { mPrice.setSource(characterString); } break; case GncXmlHelper.TAG_PRICE_VALUE: if (mPrice != null) { String[] parts = characterString.split("/"); if (parts.length != 2) { String message = "Illegal price - " + characterString; Log.e(LOG_TAG, message); Crashlytics.log(message); throw new SAXException(message); } else { mPrice.setValueNum(Long.valueOf(parts[0])); mPrice.setValueDenom(Long.valueOf(parts[1])); Log.d( getClass().getName(), "price " + characterString + " .. " + mPrice.getValueNum() + "/" + mPrice.getValueDenom()); } } break; case GncXmlHelper.TAG_PRICE_TYPE: if (mPrice != null) { mPrice.setType(characterString); } break; case GncXmlHelper.TAG_PRICE: if (mPrice != null) { mPriceList.add(mPrice); mPrice = null; } break; } // reset the accumulated characters mContent.setLength(0); }
/** * Serializes transactions from the database to XML * * @param xmlSerializer XML serializer * @param exportTemplates Flag whether to export templates or normal transactions * @throws IOException if the XML serializer cannot be written to */ private void exportTransactions(XmlSerializer xmlSerializer, boolean exportTemplates) throws IOException { String where = TransactionEntry.TABLE_NAME + "." + TransactionEntry.COLUMN_TEMPLATE + "=0"; if (exportTemplates) { where = TransactionEntry.TABLE_NAME + "." + TransactionEntry.COLUMN_TEMPLATE + "=1"; } Cursor cursor = mTransactionsDbAdapter.fetchTransactionsWithSplits( new String[] { TransactionEntry.TABLE_NAME + "." + TransactionEntry.COLUMN_UID + " AS trans_uid", TransactionEntry.TABLE_NAME + "." + TransactionEntry.COLUMN_DESCRIPTION + " AS trans_desc", TransactionEntry.TABLE_NAME + "." + TransactionEntry.COLUMN_NOTES + " AS trans_notes", TransactionEntry.TABLE_NAME + "." + TransactionEntry.COLUMN_TIMESTAMP + " AS trans_time", TransactionEntry.TABLE_NAME + "." + TransactionEntry.COLUMN_EXPORTED + " AS trans_exported", TransactionEntry.TABLE_NAME + "." + TransactionEntry.COLUMN_CURRENCY + " AS trans_currency", TransactionEntry.TABLE_NAME + "." + TransactionEntry.COLUMN_CREATED_AT + " AS trans_date_posted", TransactionEntry.TABLE_NAME + "." + TransactionEntry.COLUMN_SCHEDX_ACTION_UID + " AS trans_from_sched_action", SplitEntry.TABLE_NAME + "." + SplitEntry.COLUMN_UID + " AS split_uid", SplitEntry.TABLE_NAME + "." + SplitEntry.COLUMN_MEMO + " AS split_memo", SplitEntry.TABLE_NAME + "." + SplitEntry.COLUMN_TYPE + " AS split_type", SplitEntry.TABLE_NAME + "." + SplitEntry.COLUMN_VALUE_NUM + " AS split_value_num", SplitEntry.TABLE_NAME + "." + SplitEntry.COLUMN_VALUE_DENOM + " AS split_value_denom", SplitEntry.TABLE_NAME + "." + SplitEntry.COLUMN_QUANTITY_NUM + " AS split_quantity_num", SplitEntry.TABLE_NAME + "." + SplitEntry.COLUMN_QUANTITY_DENOM + " AS split_quantity_denom", SplitEntry.TABLE_NAME + "." + SplitEntry.COLUMN_ACCOUNT_UID + " AS split_acct_uid" }, where, null, TransactionEntry.TABLE_NAME + "." + TransactionEntry.COLUMN_TIMESTAMP + " ASC , " + TransactionEntry.TABLE_NAME + "." + TransactionEntry.COLUMN_UID + " ASC "); String lastTrxUID = ""; Commodity trnCommodity = null; String denomString = "100"; if (exportTemplates) { mRootTemplateAccount = new Account("Template Root"); mRootTemplateAccount.setAccountType(AccountType.ROOT); mTransactionToTemplateAccountMap.put(" ", mRootTemplateAccount); while (cursor.moveToNext()) { Account account = new Account(BaseModel.generateUID()); account.setAccountType(AccountType.BANK); String trnUID = cursor.getString(cursor.getColumnIndexOrThrow("trans_uid")); mTransactionToTemplateAccountMap.put(trnUID, account); } exportTemplateAccounts(xmlSerializer, mTransactionToTemplateAccountMap.values()); // push cursor back to before the beginning cursor.moveToFirst(); cursor.moveToPrevious(); } while (cursor.moveToNext()) { String curTrxUID = cursor.getString(cursor.getColumnIndexOrThrow("trans_uid")); if (!lastTrxUID.equals(curTrxUID)) { // new transaction starts if (!lastTrxUID.equals("")) { // there's an old transaction, close it xmlSerializer.endTag(null, GncXmlHelper.TAG_TRN_SPLITS); xmlSerializer.endTag(null, GncXmlHelper.TAG_TRANSACTION); } // new transaction xmlSerializer.startTag(null, GncXmlHelper.TAG_TRANSACTION); xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_VERSION, GncXmlHelper.BOOK_VERSION); // transaction id xmlSerializer.startTag(null, GncXmlHelper.TAG_TRX_ID); xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_TYPE, GncXmlHelper.ATTR_VALUE_GUID); xmlSerializer.text(curTrxUID); xmlSerializer.endTag(null, GncXmlHelper.TAG_TRX_ID); // currency String currencyCode = cursor.getString(cursor.getColumnIndexOrThrow("trans_currency")); trnCommodity = CommoditiesDbAdapter.getInstance() .getCommodity(currencyCode); // Currency.getInstance(currencyCode); xmlSerializer.startTag(null, GncXmlHelper.TAG_TRX_CURRENCY); xmlSerializer.startTag(null, GncXmlHelper.TAG_COMMODITY_SPACE); xmlSerializer.text("ISO4217"); xmlSerializer.endTag(null, GncXmlHelper.TAG_COMMODITY_SPACE); xmlSerializer.startTag(null, GncXmlHelper.TAG_COMMODITY_ID); xmlSerializer.text(currencyCode); xmlSerializer.endTag(null, GncXmlHelper.TAG_COMMODITY_ID); xmlSerializer.endTag(null, GncXmlHelper.TAG_TRX_CURRENCY); // date posted, time which user put on the transaction String strDate = GncXmlHelper.formatDate(cursor.getLong(cursor.getColumnIndexOrThrow("trans_time"))); xmlSerializer.startTag(null, GncXmlHelper.TAG_DATE_POSTED); xmlSerializer.startTag(null, GncXmlHelper.TAG_TS_DATE); xmlSerializer.text(strDate); xmlSerializer.endTag(null, GncXmlHelper.TAG_TS_DATE); xmlSerializer.endTag(null, GncXmlHelper.TAG_DATE_POSTED); // date entered, time when the transaction was actually created Timestamp timeEntered = Timestamp.valueOf(cursor.getString(cursor.getColumnIndexOrThrow("trans_date_posted"))); String dateEntered = GncXmlHelper.formatDate(timeEntered.getTime()); xmlSerializer.startTag(null, GncXmlHelper.TAG_DATE_ENTERED); xmlSerializer.startTag(null, GncXmlHelper.TAG_TS_DATE); xmlSerializer.text(dateEntered); xmlSerializer.endTag(null, GncXmlHelper.TAG_TS_DATE); xmlSerializer.endTag(null, GncXmlHelper.TAG_DATE_ENTERED); // description xmlSerializer.startTag(null, GncXmlHelper.TAG_TRN_DESCRIPTION); xmlSerializer.text(cursor.getString(cursor.getColumnIndexOrThrow("trans_desc"))); xmlSerializer.endTag(null, GncXmlHelper.TAG_TRN_DESCRIPTION); lastTrxUID = curTrxUID; // slots ArrayList<String> slotKey = new ArrayList<>(); ArrayList<String> slotType = new ArrayList<>(); ArrayList<String> slotValue = new ArrayList<>(); String notes = cursor.getString(cursor.getColumnIndexOrThrow("trans_notes")); boolean exported = cursor.getInt(cursor.getColumnIndexOrThrow("trans_exported")) == 1; if (notes != null && notes.length() > 0) { slotKey.add(GncXmlHelper.KEY_NOTES); slotType.add(GncXmlHelper.ATTR_VALUE_STRING); slotValue.add(notes); } if (!exported) { slotKey.add(GncXmlHelper.KEY_EXPORTED); slotType.add(GncXmlHelper.ATTR_VALUE_STRING); slotValue.add("false"); } String scheduledActionUID = cursor.getString(cursor.getColumnIndexOrThrow("trans_from_sched_action")); if (scheduledActionUID != null && !scheduledActionUID.isEmpty()) { slotKey.add(GncXmlHelper.KEY_FROM_SCHED_ACTION); slotType.add(GncXmlHelper.ATTR_VALUE_GUID); slotValue.add(scheduledActionUID); } xmlSerializer.startTag(null, GncXmlHelper.TAG_TRN_SLOTS); exportSlots(xmlSerializer, slotKey, slotType, slotValue); xmlSerializer.endTag(null, GncXmlHelper.TAG_TRN_SLOTS); // splits start xmlSerializer.startTag(null, GncXmlHelper.TAG_TRN_SPLITS); } xmlSerializer.startTag(null, GncXmlHelper.TAG_TRN_SPLIT); // split id xmlSerializer.startTag(null, GncXmlHelper.TAG_SPLIT_ID); xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_TYPE, GncXmlHelper.ATTR_VALUE_GUID); xmlSerializer.text(cursor.getString(cursor.getColumnIndexOrThrow("split_uid"))); xmlSerializer.endTag(null, GncXmlHelper.TAG_SPLIT_ID); // memo String memo = cursor.getString(cursor.getColumnIndexOrThrow("split_memo")); if (memo != null && memo.length() > 0) { xmlSerializer.startTag(null, GncXmlHelper.TAG_SPLIT_MEMO); xmlSerializer.text(memo); xmlSerializer.endTag(null, GncXmlHelper.TAG_SPLIT_MEMO); } // reconciled xmlSerializer.startTag(null, GncXmlHelper.TAG_RECONCILED_STATE); xmlSerializer.text("n"); xmlSerializer.endTag(null, GncXmlHelper.TAG_RECONCILED_STATE); // value, in the transaction's currency String trxType = cursor.getString(cursor.getColumnIndexOrThrow("split_type")); int splitValueNum = cursor.getInt(cursor.getColumnIndexOrThrow("split_value_num")); int splitValueDenom = cursor.getInt(cursor.getColumnIndexOrThrow("split_value_denom")); BigDecimal splitAmount = Money.getBigDecimal(splitValueNum, splitValueDenom); String strValue = "0/" + denomString; if (!exportTemplates) { // when doing normal transaction export strValue = (trxType.equals("CREDIT") ? "-" : "") + splitValueNum + "/" + splitValueDenom; } xmlSerializer.startTag(null, GncXmlHelper.TAG_SPLIT_VALUE); xmlSerializer.text(strValue); xmlSerializer.endTag(null, GncXmlHelper.TAG_SPLIT_VALUE); // quantity, in the split account's currency String splitQuantityNum = cursor.getString(cursor.getColumnIndexOrThrow("split_quantity_num")); String splitQuantityDenom = cursor.getString(cursor.getColumnIndexOrThrow("split_quantity_denom")); if (!exportTemplates) { strValue = (trxType.equals("CREDIT") ? "-" : "") + splitQuantityNum + "/" + splitQuantityDenom; } xmlSerializer.startTag(null, GncXmlHelper.TAG_SPLIT_QUANTITY); xmlSerializer.text(strValue); xmlSerializer.endTag(null, GncXmlHelper.TAG_SPLIT_QUANTITY); // account guid xmlSerializer.startTag(null, GncXmlHelper.TAG_SPLIT_ACCOUNT); xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_TYPE, GncXmlHelper.ATTR_VALUE_GUID); String splitAccountUID = null; if (exportTemplates) { // get the UID of the template account splitAccountUID = mTransactionToTemplateAccountMap.get(curTrxUID).getUID(); } else { splitAccountUID = cursor.getString(cursor.getColumnIndexOrThrow("split_acct_uid")); } xmlSerializer.text(splitAccountUID); xmlSerializer.endTag(null, GncXmlHelper.TAG_SPLIT_ACCOUNT); // if we are exporting a template transaction, then we need to add some extra slots if (exportTemplates) { xmlSerializer.startTag(null, GncXmlHelper.TAG_SPLIT_SLOTS); xmlSerializer.startTag(null, GncXmlHelper.TAG_SLOT); xmlSerializer.startTag(null, GncXmlHelper.TAG_SLOT_KEY); xmlSerializer.text( GncXmlHelper.KEY_SCHEDX_ACTION); // FIXME: not all templates may be scheduled actions xmlSerializer.endTag(null, GncXmlHelper.TAG_SLOT_KEY); xmlSerializer.startTag(null, GncXmlHelper.TAG_SLOT_VALUE); xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_TYPE, "frame"); List<String> slotKeys = new ArrayList<>(); List<String> slotTypes = new ArrayList<>(); List<String> slotValues = new ArrayList<>(); slotKeys.add(GncXmlHelper.KEY_SPLIT_ACCOUNT_SLOT); slotTypes.add(GncXmlHelper.ATTR_VALUE_GUID); slotValues.add(cursor.getString(cursor.getColumnIndexOrThrow("split_acct_uid"))); TransactionType type = TransactionType.valueOf(trxType); if (type == TransactionType.CREDIT) { slotKeys.add(GncXmlHelper.KEY_CREDIT_FORMULA); slotTypes.add(GncXmlHelper.ATTR_VALUE_STRING); slotValues.add(GncXmlHelper.formatTemplateSplitAmount(splitAmount)); slotKeys.add(GncXmlHelper.KEY_CREDIT_NUMERIC); slotTypes.add(GncXmlHelper.ATTR_VALUE_NUMERIC); slotValues.add(GncXmlHelper.formatSplitAmount(splitAmount, trnCommodity)); } else { slotKeys.add(GncXmlHelper.KEY_DEBIT_FORMULA); slotTypes.add(GncXmlHelper.ATTR_VALUE_STRING); slotValues.add(GncXmlHelper.formatTemplateSplitAmount(splitAmount)); slotKeys.add(GncXmlHelper.KEY_DEBIT_NUMERIC); slotTypes.add(GncXmlHelper.ATTR_VALUE_NUMERIC); slotValues.add(GncXmlHelper.formatSplitAmount(splitAmount, trnCommodity)); } exportSlots(xmlSerializer, slotKeys, slotTypes, slotValues); xmlSerializer.endTag(null, GncXmlHelper.TAG_SLOT_VALUE); xmlSerializer.endTag(null, GncXmlHelper.TAG_SLOT); xmlSerializer.endTag(null, GncXmlHelper.TAG_SPLIT_SLOTS); } xmlSerializer.endTag(null, GncXmlHelper.TAG_TRN_SPLIT); } if (!lastTrxUID.equals("")) { // there's an unfinished transaction, close it xmlSerializer.endTag(null, GncXmlHelper.TAG_TRN_SPLITS); xmlSerializer.endTag(null, GncXmlHelper.TAG_TRANSACTION); } cursor.close(); }
private void exportAccounts(XmlSerializer xmlSerializer) throws IOException { // gnucash desktop requires that parent account appears before its descendants. // sort by full-name to fulfill the request Cursor cursor = mAccountsDbAdapter.fetchAccounts( null, null, DatabaseSchema.AccountEntry.COLUMN_FULL_NAME + " ASC"); while (cursor.moveToNext()) { // write account xmlSerializer.startTag(null, GncXmlHelper.TAG_ACCOUNT); xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_VERSION, GncXmlHelper.BOOK_VERSION); // account name xmlSerializer.startTag(null, GncXmlHelper.TAG_NAME); xmlSerializer.text( cursor.getString(cursor.getColumnIndexOrThrow(DatabaseSchema.AccountEntry.COLUMN_NAME))); xmlSerializer.endTag(null, GncXmlHelper.TAG_NAME); // account guid xmlSerializer.startTag(null, GncXmlHelper.TAG_ACCT_ID); xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_TYPE, GncXmlHelper.ATTR_VALUE_GUID); xmlSerializer.text( cursor.getString(cursor.getColumnIndexOrThrow(DatabaseSchema.AccountEntry.COLUMN_UID))); xmlSerializer.endTag(null, GncXmlHelper.TAG_ACCT_ID); // account type xmlSerializer.startTag(null, GncXmlHelper.TAG_TYPE); String acct_type = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseSchema.AccountEntry.COLUMN_TYPE)); xmlSerializer.text(acct_type); xmlSerializer.endTag(null, GncXmlHelper.TAG_TYPE); // commodity xmlSerializer.startTag(null, GncXmlHelper.TAG_ACCOUNT_COMMODITY); xmlSerializer.startTag(null, GncXmlHelper.TAG_COMMODITY_SPACE); xmlSerializer.text("ISO4217"); xmlSerializer.endTag(null, GncXmlHelper.TAG_COMMODITY_SPACE); xmlSerializer.startTag(null, GncXmlHelper.TAG_COMMODITY_ID); String acctCurrencyCode = cursor.getString( cursor.getColumnIndexOrThrow(DatabaseSchema.AccountEntry.COLUMN_CURRENCY)); xmlSerializer.text(acctCurrencyCode); xmlSerializer.endTag(null, GncXmlHelper.TAG_COMMODITY_ID); xmlSerializer.endTag(null, GncXmlHelper.TAG_ACCOUNT_COMMODITY); // commodity scu Commodity commodity = CommoditiesDbAdapter.getInstance().getCommodity(acctCurrencyCode); xmlSerializer.startTag(null, GncXmlHelper.TAG_COMMODITY_SCU); xmlSerializer.text(Integer.toString(commodity.getSmallestFraction())); xmlSerializer.endTag(null, GncXmlHelper.TAG_COMMODITY_SCU); // account description String description = cursor.getString( cursor.getColumnIndexOrThrow(DatabaseSchema.AccountEntry.COLUMN_DESCRIPTION)); if (description != null && !description.equals("")) { xmlSerializer.startTag(null, GncXmlHelper.TAG_ACCT_DESCRIPTION); xmlSerializer.text(description); xmlSerializer.endTag(null, GncXmlHelper.TAG_ACCT_DESCRIPTION); } // account slots, color, placeholder, default transfer account, favorite ArrayList<String> slotKey = new ArrayList<>(); ArrayList<String> slotType = new ArrayList<>(); ArrayList<String> slotValue = new ArrayList<>(); slotKey.add(GncXmlHelper.KEY_PLACEHOLDER); slotType.add(GncXmlHelper.ATTR_VALUE_STRING); slotValue.add( Boolean.toString( cursor.getInt( cursor.getColumnIndexOrThrow(DatabaseSchema.AccountEntry.COLUMN_PLACEHOLDER)) != 0)); String color = cursor.getString( cursor.getColumnIndexOrThrow(DatabaseSchema.AccountEntry.COLUMN_COLOR_CODE)); if (color != null && color.length() > 0) { slotKey.add(GncXmlHelper.KEY_COLOR); slotType.add(GncXmlHelper.ATTR_VALUE_STRING); slotValue.add(color); } String defaultTransferAcctUID = cursor.getString( cursor.getColumnIndexOrThrow( DatabaseSchema.AccountEntry.COLUMN_DEFAULT_TRANSFER_ACCOUNT_UID)); if (defaultTransferAcctUID != null && defaultTransferAcctUID.length() > 0) { slotKey.add(GncXmlHelper.KEY_DEFAULT_TRANSFER_ACCOUNT); slotType.add(GncXmlHelper.ATTR_VALUE_STRING); slotValue.add(defaultTransferAcctUID); } slotKey.add(GncXmlHelper.KEY_FAVORITE); slotType.add(GncXmlHelper.ATTR_VALUE_STRING); slotValue.add( Boolean.toString( cursor.getInt( cursor.getColumnIndexOrThrow(DatabaseSchema.AccountEntry.COLUMN_FAVORITE)) != 0)); xmlSerializer.startTag(null, GncXmlHelper.TAG_ACT_SLOTS); exportSlots(xmlSerializer, slotKey, slotType, slotValue); xmlSerializer.endTag(null, GncXmlHelper.TAG_ACT_SLOTS); // parent uid String parentUID = cursor.getString( cursor.getColumnIndexOrThrow(DatabaseSchema.AccountEntry.COLUMN_PARENT_ACCOUNT_UID)); if (!acct_type.equals("ROOT") && parentUID != null && parentUID.length() > 0) { xmlSerializer.startTag(null, GncXmlHelper.TAG_PARENT_UID); xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_TYPE, GncXmlHelper.ATTR_VALUE_GUID); xmlSerializer.text(parentUID); xmlSerializer.endTag(null, GncXmlHelper.TAG_PARENT_UID); } else { Log.d( "export", "root account : " + cursor.getString( cursor.getColumnIndexOrThrow(DatabaseSchema.AccountEntry.COLUMN_UID))); } xmlSerializer.endTag(null, GncXmlHelper.TAG_ACCOUNT); } cursor.close(); }