1818
1919import android .database .Cursor ;
2020import android .database .sqlite .SQLiteDatabase ;
21+ import android .support .annotation .NonNull ;
2122
2223import com .crashlytics .android .Crashlytics ;
2324
25+ import org .gnucash .android .R ;
2426import org .gnucash .android .export .ExportParams ;
2527import org .gnucash .android .export .Exporter ;
2628import org .gnucash .android .model .Account ;
27- import org .gnucash .android .model .Money ;
2829import org .gnucash .android .model .Split ;
2930import org .gnucash .android .model .Transaction ;
3031import org .gnucash .android .model .TransactionType ;
3132
32- import java .io .BufferedOutputStream ;
33- import java .io .FileOutputStream ;
33+ import java .io .FileWriter ;
3434import java .io .IOException ;
35- import java .io .OutputStreamWriter ;
3635import java .text .DateFormat ;
3736import java .text .SimpleDateFormat ;
3837import java .util .ArrayList ;
39- import java .util .Collections ;
40- import java .util .Comparator ;
38+ import java .util .Arrays ;
4139import java .util .Date ;
4240import java .util .List ;
4341import java .util .Locale ;
@@ -51,20 +49,7 @@ public class CsvTransactionsExporter extends Exporter{
5149
5250 private char mCsvSeparator ;
5351
54- private DateFormat dateFormat = new SimpleDateFormat ("dd/MM/yyyy" , Locale .US );
55-
56- private Comparator <Split > splitComparator = new Comparator <Split >() {
57- @ Override
58- public int compare (Split o1 , Split o2 ) {
59- if (o1 .getType () == TransactionType .DEBIT
60- && o2 .getType () == TransactionType .CREDIT )
61- return -1 ;
62- if (o1 .getType () == TransactionType .CREDIT
63- && o2 .getType () == TransactionType .DEBIT )
64- return 1 ;
65- return 0 ;
66- }
67- };
52+ private DateFormat dateFormat = new SimpleDateFormat ("YYYY-MM-dd" , Locale .US );
6853
6954 /**
7055 * Construct a new exporter with export parameters
@@ -90,26 +75,13 @@ public CsvTransactionsExporter(ExportParams params, SQLiteDatabase db) {
9075
9176 @ Override
9277 public List <String > generateExport () throws ExporterException {
93- OutputStreamWriter writerStream = null ;
94- CsvWriter writer = null ;
9578 String outputFile = getExportCacheFilePath ();
96- try {
97- FileOutputStream fileOutputStream = new FileOutputStream (outputFile );
98- BufferedOutputStream bufferedOutputStream = new BufferedOutputStream (fileOutputStream );
99- writerStream = new OutputStreamWriter (bufferedOutputStream );
100- writer = new CsvWriter (writerStream );
101- generateExport (writer );
79+
80+ try (CsvWriter csvWriter = new CsvWriter (new FileWriter (outputFile ), "" + mCsvSeparator )){
81+ generateExport (csvWriter );
10282 } catch (IOException ex ){
10383 Crashlytics .log ("Error exporting CSV" );
10484 Crashlytics .logException (ex );
105- } finally {
106- if (writerStream != null ) {
107- try {
108- writerStream .close ();
109- } catch (IOException e ) {
110- throw new ExporterException (mExportParams , e );
111- }
112- }
11385 }
11486
11587 List <String > exportedFiles = new ArrayList <>();
@@ -118,111 +90,63 @@ public List<String> generateExport() throws ExporterException {
11890 return exportedFiles ;
11991 }
12092
121- private void write_split (final Transaction transaction , final Split split , final CsvWriter writer ) throws IOException
122- {
123- String separator = mCsvSeparator + "" ;
124- Account account = mAccountsDbAdapter .getRecord (split .getAccountUID ());
125-
126- // Date
127- Date date = new Date (transaction .getTimeMillis ());
128- writer .write (dateFormat .format (date ) + separator );
129- // Account name
130- writer .write (account .getName () + separator );
131- // TODO:Number is not defined yet?
132- writer .write ( separator );
133- // Description
134- writer .write (transaction .getDescription () + separator );
135- // Notes of transaction
136- writer .write (transaction .getNote () + separator );
137- // Memo
138- writer .write (
139- (split .getMemo ()==null ?
140- "" :split .getMemo ()) + separator );
141- // TODO:Category is not defined yet?
142- writer .write (separator );
143- // Type
144- writer .write (split .getType ().name () + separator );
145- // TODO:Action is not defined yet?
146- writer .write (separator );
147- // Reconcile
148- writer .write (split .getReconcileState () + separator );
149-
150- // Changes
151- Money change = split .getFormattedQuantity ().withCurrency (transaction .getCommodity ());
152- Money zero = Money .getZeroInstance ().withCurrency (transaction .getCommodity ());
153- // To currency; From currency; To; From
154- if (change .isNegative ()) {
155- writer .write (zero .toPlainString () + separator );
156- writer .write (change .abs ().toPlainString () + separator );
157- writer .write (Money .getZeroInstance ().toPlainString () + separator );
158- writer .write (split .getFormattedQuantity ().abs ().toPlainString () + separator );
159- }
160- else {
161- writer .write (change .abs ().toPlainString () + separator );
162- writer .write (zero .toPlainString () + separator );
163- writer .write (split .getFormattedQuantity ().abs ().toPlainString () + separator );
164- writer .write (Money .getZeroInstance ().toPlainString () + separator );
93+ /**
94+ * Write splits to CSV format
95+ * @param splits Splits to be written
96+ */
97+ private void writeSplitsToCsv (@ NonNull List <Split > splits , @ NonNull CsvWriter writer ) throws IOException {
98+ int index = 0 ;
99+ for (Split split : splits ) {
100+ if (index ++ > 0 ){ // the first split is on the same line as the transactions. But after that, we
101+ writer .write ("" + mCsvSeparator + mCsvSeparator + mCsvSeparator + mCsvSeparator
102+ + mCsvSeparator + mCsvSeparator + mCsvSeparator + mCsvSeparator );
103+ }
104+ writer .writeToken (split .getMemo ());
105+ Account account = mAccountsDbAdapter .getRecord (split .getAccountUID ());
106+ writer .writeToken (account .getFullName ());
107+ writer .writeToken (account .getName ());
108+
109+ String sign = split .getType () == TransactionType .CREDIT ? "-" : "" ;
110+ writer .writeToken (sign + split .getQuantity ().formattedString ());
111+ writer .writeToken (sign + split .getQuantity ().toLocaleString ());
112+ writer .writeToken ("" + split .getReconcileState ());
113+ if (split .getReconcileState () == Split .FLAG_RECONCILED ) {
114+ String recDateString = dateFormat .format (new Date (split .getReconcileDate ().getTime ()));
115+ writer .writeToken (recDateString );
116+ } else {
117+ writer .writeToken (null );
118+ }
119+ writer .writeEndToken (split .getQuantity ().divide (split .getValue ()).toLocaleString ());
165120 }
166-
167- // TODO: What is price?
168- writer .write (separator );
169- writer .write (separator );
170121 }
171122
172- public void generateExport (final CsvWriter writer ) throws ExporterException {
123+ private void generateExport (final CsvWriter csvWriter ) throws ExporterException {
173124 try {
174- String separator = mCsvSeparator + "" ;
175- List <String > names = new ArrayList <String >();
176- names .add ("Date" );
177- names .add ("Account name" );
178- names .add ("Number" );
179- names .add ("Description" );
180- names .add ("Notes" );
181- names .add ("Memo" );
182- names .add ("Category" );
183- names .add ("Type" );
184- names .add ("Action" );
185- names .add ("Reconcile" );
186- names .add ("To With Sym" );
187- names .add ("From With Sym" );
188- names .add ("To Num." );
189- names .add ("From Num." );
190- names .add ("To Rate/Price" );
191- names .add ("From Rate/Price" );
192-
193- List <Transaction > transactions = mTransactionsDbAdapter .getAllTransactions ();
194-
125+ List <String > names = Arrays .asList (mContext .getResources ().getStringArray (R .array .csv_transaction_headers ));
195126 for (int i = 0 ; i < names .size (); i ++) {
196- writer . write (names .get (i ) + separator );
127+ csvWriter . writeToken (names .get (i ));
197128 }
198- writer . write ( " \n " );
129+ csvWriter . newLine ( );
199130
200131
201132 Cursor cursor = mTransactionsDbAdapter .fetchAllRecords ();
202- while (cursor .moveToNext ())
203- {
133+ while (cursor .moveToNext ()){
204134 Transaction transaction = mTransactionsDbAdapter .buildModelInstance (cursor );
205- List <Split > splits = transaction .getSplits ();
206- Collections .sort (splits ,splitComparator );
207- for (int j = 0 ; j < splits .size ()/2 ; j ++) {
208- Split split = splits .get (j );
209- Split pair = null ;
210- for (int k = 0 ; k < splits .size (); k ++) {
211- if (split .isPairOf (splits .get (k ))) {
212- pair = splits .get (k );
213- }
214- }
215-
216- write_split (transaction , split , writer );
217- writer .write ("\n " );
218- if (pair != null ) {
219- write_split (transaction , pair , writer );
220- writer .write ("\n " );
221- }
222- }
135+ Date date = new Date (transaction .getTimeMillis ());
136+ csvWriter .writeToken (dateFormat .format (date ));
137+ csvWriter .writeToken (transaction .getUID ());
138+ csvWriter .writeToken (null ); //Transaction number
139+
140+ csvWriter .writeToken (transaction .getDescription ());
141+ csvWriter .writeToken (transaction .getNote ());
142+
143+ csvWriter .writeToken ("CURRENCY::" + transaction .getCurrencyCode ());
144+ csvWriter .writeToken (null ); // Void Reason
145+ csvWriter .writeToken (null ); // Action
146+ writeSplitsToCsv (transaction .getSplits (), csvWriter );
223147 }
224148
225- } catch (Exception e ) {
149+ } catch (IOException e ) {
226150 Crashlytics .logException (e );
227151 throw new ExporterException (mExportParams , e );
228152 }
0 commit comments