1 package com.leonarduk.clearcheckbook;
2
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.InputStreamReader;
6 import java.util.Iterator;
7 import java.util.List;
8 import java.util.Map;
9
10 import org.apache.log4j.Logger;
11
12 import com.leonarduk.clearcheckbook.dto.AccountDataType;
13 import com.leonarduk.clearcheckbook.dto.TransactionDataType;
14 import com.leonarduk.clearcheckbook.file.AMEXFilePreprocessor;
15 import com.leonarduk.clearcheckbook.file.FilePreProcessor;
16 import com.leonarduk.clearcheckbook.file.NationwideFilePreprocessor;
17 import com.leonarduk.clearcheckbook.file.TransactionFilePreprocessor;
18 import com.leonarduk.utils.Config;
19
20 /***
21 * A simple Command line Interface to use the API.
22 *
23 * @author Stephen Leonard
24 * @since 6 Feb 2014
25 *
26 * @version $Author:: $: Author of last commit
27 * @version $Rev:: $: Revision of last commit
28 * @version $Date:: $: Date of last commit
29 *
30 */
31 public class ClearCheckBookCLI {
32
33 private static final String ALL_TRANSACTIONS_CSV = "all_transactions.csv";
34
35 private static final String ACCOUNTS_CSV = "accounts.csv";
36
37 private static final Logger _logger = Logger
38 .getLogger(ClearCheckBookCLI.class);
39
40 /***
41 *
42 * @param args
43 * @throws ClearcheckbookException
44 */
45 public static void main(String[] args) throws ClearcheckbookException {
46 Config config = new Config();
47
48 String userName = config
49 .getMandatoryPropertyValue("clearcheckbook.user");
50 String password = config
51 .getMandatoryPropertyValue("clearcheckbook.password");
52
53 String command = config
54 .getOptionalPropertyValue("clearcheckbook.command");
55
56 ClearCheckBookCLI cli = new ClearCheckBookCLI(userName, password);
57 if (null == command) {
58
59 while (true) {
60 cli.getMenu();
61 }
62 }
63
64 }
65
66 private ClearCheckBookHelper helper;
67
68 private Map<Long, AccountDataType> accountsMap = null;
69
70 public ClearCheckBookCLI(String userName, String password) {
71 helper = new ClearCheckBookHelper(userName, password);
72 System.out.println("Clearcheckbook Tools - connecting as " + userName);
73 }
74
75 private AccountDataType chooseAccount(String zeroOption)
76 throws ClearcheckbookException {
77 List<AccountDataType> accounts = fetchAccounts();
78 AccountDataType account = null;
79 for (int i = 0; i < accounts.size(); i++) {
80 AccountDataType accountDataType = accounts.get(i);
81 System.out.println((i + 1) + " " + accountDataType.getId() + " "
82 + accountDataType.getName() + " "
83 + accountDataType.getCurrentBalance());
84 }
85 int option = getIntegerInput(
86 "Choose number of account or select 0 for " + zeroOption + ":",
87 accounts.size());
88 if (option > 0) {
89 account = accounts.get(option - 1);
90 }
91 return account;
92 }
93
94 private FilePreProcessor chooseFileProcessor(Long id)
95 throws ClearcheckbookException {
96 String[] processors = new String[] { "Default",
97 AMEXFilePreprocessor.class.getName(),
98 NationwideFilePreprocessor.class.getName() };
99 for (int i = 0; i < processors.length; i++) {
100 System.out.println((i) + " " + processors[i]);
101 }
102 int option = getIntegerInput("Choose fileProcessor :",
103 processors.length);
104 switch (option) {
105 case 1:
106 return new AMEXFilePreprocessor(id);
107 case 2:
108 return new NationwideFilePreprocessor(id);
109 default:
110 return new TransactionFilePreprocessor(id);
111 }
112 }
113
114 private void exportAccounts() throws ClearcheckbookException {
115 List<AccountDataType> accounts = fetchAccounts();
116 String fileName = getFilename(ACCOUNTS_CSV);
117 helper.exportAccounts(fileName, accounts);
118 System.out.println("Saved " + accounts.size() + " accounts to "
119 + fileName);
120 }
121
122 private void exportTransactions() throws ClearcheckbookException {
123 List<TransactionDataType> transactions;
124 AccountDataType account = chooseAccount("all transactions");
125
126 if (null == account) {
127 System.out.println("Fetching all transactions...");
128 transactions = this.helper.getTransactions();
129 } else {
130 System.out.println("Fetching transactions for " + account.getName()
131 + "...");
132 transactions = this.helper.getTransactions(account);
133 }
134 System.out.println("Fetched " + transactions.size() + " transactions");
135 if (transactions.size() > 0) {
136 String fileName = getFilename(getDefaultFileName(account));
137 System.out.println("Exporting " + transactions.size()
138 + " transactions to file : " + fileName + "...");
139 this.helper.exportTransactions(fileName, transactions);
140 System.out.println("...done.");
141 } else {
142 System.out.println("Nothing to save.");
143 }
144 }
145
146 private List<AccountDataType> fetchAccounts()
147 throws ClearcheckbookException {
148 System.out.println("Fetching account list...");
149 List<AccountDataType> accounts = helper.getAccounts();
150 return accounts;
151 }
152
153 private void getAccountsMenu() throws ClearcheckbookException {
154 String[] options = new String[] { "List", "Export", "Import" };
155 for (int i = 0; i < options.length; i++) {
156 System.out.println(i + " " + options[i]);
157 }
158
159 int option = getIntegerInput("Choose option:", options.length - 1);
160 switch (option) {
161 case 0:
162 listAccounts();
163 break;
164 case 1:
165 exportAccounts();
166 break;
167 case 2:
168 importAccounts();
169 break;
170 default:
171 throw new ClearcheckbookException("Invalid option: " + option);
172 }
173 }
174
175 private String getDefaultFileName(AccountDataType account) {
176 String defaultFilename;
177 if (null == account) {
178 defaultFilename = ALL_TRANSACTIONS_CSV;
179 } else {
180 defaultFilename = "account_" + account.getId() + ".csv";
181 }
182 return defaultFilename;
183 }
184
185 private String getFilename(String defaultFilename)
186 throws ClearcheckbookException {
187 String fileName = getStringInput("Enter file name [enter for "
188 + defaultFilename + "]:");
189 if (fileName.trim().equals("")) {
190 fileName = defaultFilename;
191 }
192 return fileName;
193 }
194
195 private int getIntegerInput(String question, int maxNumber)
196 throws ClearcheckbookException {
197 System.out.print(question);
198
199 try {
200 BufferedReader br = new BufferedReader(new InputStreamReader(
201 System.in));
202 int i = Integer.parseInt(br.readLine());
203 if (i > maxNumber || i < 0) {
204 System.err.println("Choose number between 0 and " + maxNumber);
205 return getIntegerInput(question, maxNumber);
206 }
207 return i;
208 } catch (NumberFormatException nfe) {
209 System.err.println("Invalid Format!");
210 return getIntegerInput(question, maxNumber);
211 } catch (IOException e) {
212 throw new ClearcheckbookException("Failed to get option", e);
213 }
214 }
215
216 private void getMenu() throws ClearcheckbookException {
217 String[] options = new String[] { "Accounts", "Transaction", "Quit" };
218 System.out.println("MAIN MENU");
219 for (int i = 0; i < options.length; i++) {
220 System.out.println(i + " " + options[i]);
221 }
222
223 int option = getIntegerInput("Choose option:", options.length - 1);
224 switch (option) {
225 case 0:
226 getAccountsMenu();
227 break;
228 case 1:
229 getTransactionsMenu();
230 break;
231 default:
232 System.out.println("Exiting");
233 System.exit(0);
234 }
235 }
236
237 private String getStringInput(String question)
238 throws ClearcheckbookException {
239 System.out.print(question);
240 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
241 try {
242 return br.readLine();
243 } catch (IOException e) {
244 throw new ClearcheckbookException("Failed to get input", e);
245 }
246
247 }
248
249 private void getTransactionsMenu() throws ClearcheckbookException {
250 String[] options = new String[] { "List", "Export", "Import" };
251 for (int i = 0; i < options.length; i++) {
252 System.out.println(i + " " + options[i]);
253 }
254
255 int option = getIntegerInput("Choose option:", options.length - 1);
256 switch (option) {
257 case 0:
258 listTransactions();
259 break;
260 case 1:
261 exportTransactions();
262 break;
263 case 2:
264 importTransactions();
265 break;
266 default:
267 throw new ClearcheckbookException("Invalid option: " + option);
268 }
269 }
270
271 private void importAccounts() throws ClearcheckbookException {
272 String fileName = getFilename(ACCOUNTS_CSV);
273 List<AccountDataType> accounts = helper.importAccounts(fileName);
274 this.helper.processAccounts(accounts);
275 System.out.println("Imported " + accounts.size() + " accounts");
276 }
277
278 private void importTransactions() throws ClearcheckbookException {
279 System.out.println("Choose which account to import to");
280 AccountDataType account = chooseAccount("no account specified");
281 Long id = 0L;
282 if (null != account) {
283 id = account.getId();
284 }
285 String fileName = getFilename(getDefaultFileName(account));
286
287 FilePreProcessor preprocessor = chooseFileProcessor(id);
288
289 List<TransactionDataType> transactions = helper.importTransactions(
290 fileName, preprocessor);
291 this.helper.processTransactions(transactions);
292 System.out.println("Imported " + transactions.size() + " transactions");
293 }
294
295 private void listAccounts() throws ClearcheckbookException {
296 List<AccountDataType> accounts = fetchAccounts();
297 for (Iterator<AccountDataType> iterator = accounts.iterator(); iterator
298 .hasNext();) {
299 AccountDataType accountDataType = iterator.next();
300 System.out.println(accountDataType.getId() + " : "
301 + accountDataType.getName() + " "
302 + accountDataType.getCurrentBalance());
303 }
304 }
305
306 private void listTransactions() throws ClearcheckbookException {
307 List<TransactionDataType> transactions;
308 AccountDataType account = chooseAccount("all transactions");
309
310 if (null == account) {
311 System.out.println("Fetching all transactions...");
312 transactions = this.helper.getTransactions();
313 } else {
314 System.out.println("Fetching transactions for " + account.getName()
315 + "...");
316 transactions = this.helper.getTransactions(account);
317 }
318 System.out.println("Fetched " + transactions.size() + " transactions");
319 for (Iterator<TransactionDataType> iterator = transactions.iterator(); iterator
320 .hasNext();) {
321 TransactionDataType transactionDataType = iterator.next();
322 System.out.println(transactionDataType.getDate() + " "
323 + transactionDataType.getAmount() + " "
324 + transactionDataType.getPayee() + " "
325 + transactionDataType.getMemo());
326 }
327
328 }
329
330 }