private void setListeners(Split split) { splitAmountEditText.bindListeners(mCalculatorKeyboard); removeSplitButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { mRemovedSplitUIDs.add(splitUidTextView.getText().toString()); mSplitsLinearLayout.removeView(splitView); mSplitItemViewList.remove(splitView); mImbalanceWatcher.afterTextChanged(null); } }); updateTransferAccountsList(accountsSpinner); splitCurrencyTextView.setText(mCommodity.getSymbol()); splitTypeSwitch.setAmountFormattingListener(splitAmountEditText, splitCurrencyTextView); splitTypeSwitch.setChecked(mBaseAmount.signum() > 0); splitUidTextView.setText(BaseModel.generateUID()); if (split != null) { splitAmountEditText.setCommodity(split.getValue().getCommodity()); splitAmountEditText.setValue(split.getFormattedValue().asBigDecimal()); splitCurrencyTextView.setText(split.getValue().getCurrency().getSymbol()); splitMemoEditText.setText(split.getMemo()); splitUidTextView.setText(split.getUID()); String splitAccountUID = split.getAccountUID(); setSelectedTransferAccount(mAccountsDbAdapter.getID(splitAccountUID), accountsSpinner); splitTypeSwitch.setAccountType(mAccountsDbAdapter.getAccountType(splitAccountUID)); splitTypeSwitch.setChecked(split.getType()); } accountsSpinner.setOnItemSelectedListener(new SplitAccountListener(splitTypeSwitch, this)); splitTypeSwitch.addOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mImbalanceWatcher.afterTextChanged(null); } }); splitAmountEditText.addTextChangedListener(mImbalanceWatcher); }
@Override public void generateExport(Writer writer) throws ExporterException { try { String[] namespaces = new String[] { "gnc", "act", "book", "cd", "cmdty", "price", "slot", "split", "trn", "ts", "sx", "recurrence" }; XmlSerializer xmlSerializer = XmlPullParserFactory.newInstance().newSerializer(); xmlSerializer.setOutput(writer); xmlSerializer.startDocument("utf-8", true); // root tag xmlSerializer.startTag(null, GncXmlHelper.TAG_ROOT); for (String ns : namespaces) { xmlSerializer.attribute(null, "xmlns:" + ns, "http://www.gnucash.org/XML/" + ns); } // book count xmlSerializer.startTag(null, GncXmlHelper.TAG_COUNT_DATA); xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_CD_TYPE, GncXmlHelper.ATTR_VALUE_BOOK); xmlSerializer.text("1"); xmlSerializer.endTag(null, GncXmlHelper.TAG_COUNT_DATA); // book xmlSerializer.startTag(null, GncXmlHelper.TAG_BOOK); xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_VERSION, GncXmlHelper.BOOK_VERSION); // book_id xmlSerializer.startTag(null, GncXmlHelper.TAG_BOOK_ID); xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_TYPE, GncXmlHelper.ATTR_VALUE_GUID); xmlSerializer.text(BaseModel.generateUID()); xmlSerializer.endTag(null, GncXmlHelper.TAG_BOOK_ID); // commodity count List<Currency> currencies = mAccountsDbAdapter.getCurrenciesInUse(); for (int i = 0; i < currencies.size(); i++) { if (currencies.get(i).getCurrencyCode().equals("XXX")) { currencies.remove(i); } } xmlSerializer.startTag(null, GncXmlHelper.TAG_COUNT_DATA); xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_CD_TYPE, "commodity"); xmlSerializer.text(currencies.size() + ""); xmlSerializer.endTag(null, GncXmlHelper.TAG_COUNT_DATA); // account count xmlSerializer.startTag(null, GncXmlHelper.TAG_COUNT_DATA); xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_CD_TYPE, "account"); xmlSerializer.text(mAccountsDbAdapter.getRecordsCount() + ""); xmlSerializer.endTag(null, GncXmlHelper.TAG_COUNT_DATA); // transaction count xmlSerializer.startTag(null, GncXmlHelper.TAG_COUNT_DATA); xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_CD_TYPE, "transaction"); xmlSerializer.text(mTransactionsDbAdapter.getRecordsCount() + ""); xmlSerializer.endTag(null, GncXmlHelper.TAG_COUNT_DATA); // price count long priceCount = mPricesDbAdpater.getRecordsCount(); if (priceCount > 0) { xmlSerializer.startTag(null, GncXmlHelper.TAG_COUNT_DATA); xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_CD_TYPE, "price"); xmlSerializer.text(priceCount + ""); xmlSerializer.endTag(null, GncXmlHelper.TAG_COUNT_DATA); } // export the commodities used in the DB exportCommodity(xmlSerializer, currencies); // prices if (priceCount > 0) { exportPrices(xmlSerializer); } // accounts. exportAccounts(xmlSerializer); // transactions. exportTransactions(xmlSerializer, false); // transaction templates if (mTransactionsDbAdapter.getTemplateTransactionsCount() > 0) { xmlSerializer.startTag(null, GncXmlHelper.TAG_TEMPLATE_TRANSACTIONS); exportTransactions(xmlSerializer, true); xmlSerializer.endTag(null, GncXmlHelper.TAG_TEMPLATE_TRANSACTIONS); } // scheduled actions exportScheduledTransactions(xmlSerializer); xmlSerializer.endTag(null, GncXmlHelper.TAG_BOOK); xmlSerializer.endTag(null, GncXmlHelper.TAG_ROOT); xmlSerializer.endDocument(); } catch (Exception e) { Crashlytics.logException(e); throw new ExporterException(mParameters, e); } }
/** * 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(); }