Ejemplo n.º 1
0
  /** @param args */
  public static void main(String[] args) {

    File inputFile = null;
    FileInputStream fis = null;
    String inputFileName = null;
    String outputFileName = null;
    OptionParser optionParser = new OptionParser("nf:ho:b");
    OptionSet options = optionParser.parse(args);
    if (options.has("h")) {
      System.out.println(
          "Usage: MBankCSVToOFX -f inputFilename -o outputFilename -n (append note to name) -h (help) -b (append account number to memo)");
      System.exit(0);
    }
    boolean appendNoteToName = options.has("n");
    boolean appendAccountToNote = options.has("b");
    inputFileName = (String) options.valueOf("f");
    outputFileName = (String) options.valueOf("o");

    initMap();
    try {
      final Logger log = Logger.getLogger(MBankCSVToOFX.class.getCanonicalName());
      if (inputFileName == null) {
        final JFileChooser chooser = new JFileChooser();
        chooser.setDialogTitle("Please chooose mBank CSV file");
        final int returnVal = chooser.showOpenDialog(null);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
          inputFile = chooser.getSelectedFile();
          if (inputFile != null)
            log.info("You chose to open this file: " + chooser.getSelectedFile().getName());
          else {
            log.warning("You have not chosen a file to open, exiting");
            System.exit(0);
          }
        } else {
          log.warning("You have not chosen a file to open, exiting");
          System.exit(0);
        }

      } else inputFile = new File(inputFileName);
      log.setLevel(Level.ALL);
      fis = new FileInputStream(inputFile);

      final Hashtable<String, String> global = new Hashtable<String, String>();

      final MessageDigest sha = MessageDigest.getInstance("SHA-1");

      log.info("Opening file:" + inputFile.getName());

      fis = new FileInputStream(inputFile);
      final CsvReader reader = new CsvReader(fis, Charset.forName(INPUT_FILES_CHARSET));
      final AggregateMarshaller marshaller = new AggregateMarshaller();
      log.info("Reading records");

      final List<String[]> transactions = readRecords(global, reader);
      if (transactions.size() == 0) {
        log.warning("No transactions, possible bad file format");
        System.exit(1);

      } else {
        log.info("Processing " + transactions.size() + " transactions");
      }
      if (outputFileName == null) outputFileName = inputFile.getAbsolutePath() + ".ofx";
      log.info("Opening output file:" + outputFileName);

      final OFXWriter ofxWriter = new OFXV2Writer(new FileWriter(outputFileName));
      ((OFXV2Writer) ofxWriter).setWriteAttributesOnNewLine(true);
      log.info("Generating ofx structures");

      final SortedSet<ResponseMessageSet> responseMsgs = new TreeSet<ResponseMessageSet>();
      final SignonResponseMessageSet srms = new SignonResponseMessageSet();
      final SignonResponse signonResponse = new SignonResponse();
      signonResponse.setLanguage("Polish");
      final Status statusOk = new Status();
      statusOk.setCode(KnownCode.SUCCESS);
      signonResponse.setStatus(statusOk);
      signonResponse.setTimestamp(new Date());
      srms.setSignonResponse(signonResponse);
      responseMsgs.add(srms);

      final List<Transaction> tList = new ArrayList<Transaction>();
      DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd H:m");
      formatter.setTimeZone(TimeZone.getTimeZone("CET"));
      for (final String[] i : transactions) {
        final String block_date = i[0];
        final String accounting_date = i[1];
        String operationDescription = i[2];
        String payeeData = i[3];
        String payeeAccount = i[4];
        String operationNote = i[5];
        Double charge = trimMoneyValue(i[6], global.get("currency"));

        final Transaction transaction = new Transaction();
        transaction.setAmount(charge);
        transaction.setDateInitiated(formatter.parse(block_date + TOD_OFFSET));
        transaction.setDatePosted(formatter.parse(block_date + TOD_OFFSET));
        transaction.setDateAvailable(formatter.parse(accounting_date + TOD_OFFSET));

        payeeAccount = payeeAccount.replaceAll("'", "");
        operationNote = operationNote.replaceAll("\"", "");

        operationDescription = removeOgonki(operationDescription);
        payeeData = removeOgonki(payeeData);
        operationNote = removeOgonki(operationNote);
        int operNo = 0;
        boolean operationTypeFound = false;
        for (final String oper : transactionTypes.keySet()) {
          if (operationDescription.startsWith(oper)) {
            transaction.setTransactionType(transactionTypes.get(oper));
            // description = description.substring(oper.length());
            operationTypeFound = true;
            transaction.setName(operationDescription);
            break;
          }
          operNo++;
        }
        Payee payee = payeeFromString(payeeData);
        if (payee != null) transaction.setPayee(payee);
        else transaction.setPayeeId(payeeAccount);

        if (payeeAccount.length() > 10) {
          final BankAccountDetails bankAccountTo = new BankAccountDetails();
          bankAccountTo.setAccountNumber(payeeAccount);
          if (payeeAccount.length() == 26) bankAccountTo.setBankId(payeeAccount.substring(2, 10));
          else bankAccountTo.setBankId(payeeAccount.substring(0, 8));

          bankAccountTo.setAccountType(AccountType.CHECKING);
          transaction.setBankAccountTo(bankAccountTo);
        }
        if (!operationTypeFound) {
          transaction.setTransactionType(TransactionType.DEBIT);
          log.info("Unknown operation type:" + operationDescription + ", using defaults");
          transaction.setName(operationDescription);
        }
        if (appendNoteToName) {
          transaction.setName(transaction.getName() + ":" + operationNote.trim());
        }

        transaction.setMemo(removeMultipleSpaces(operationNote.trim()));
        if (appendAccountToNote && transaction.getBankAccountTo() != null)
          transaction.setMemo(
              transaction.getMemo() + " " + transaction.getBankAccountTo().getAccountNumber());
        final String toSign = i[0] + i[1] + i[2] + i[3] + i[4] + i[5] + i[6];
        transaction.setId(hexEncode(sha.digest(toSign.getBytes())));
        tList.add(transaction);
      }

      final TransactionList transactionList = new TransactionList();
      formatter = new SimpleDateFormat("dd.MM.yy");
      if (global.get("start_date") != null)
        transactionList.setStart(formatter.parse(global.get("start_date")));
      if (global.get("end_date") != null)
        transactionList.setEnd(formatter.parse(global.get("end_date")));
      transactionList.setTransactions(tList);
      final BankAccountDetails bac = new BankAccountDetails();
      bac.setAccountNumber(global.get("account_number").replaceAll(" ", ""));
      bac.setAccountType(AccountType.CHECKING);
      bac.setBankId("BREXPLPWMBK");

      final BankStatementResponse statementResponse = new BankStatementResponse();
      statementResponse.setAccount(bac);
      statementResponse.setCurrencyCode(global.get("currency"));
      statementResponse.setTransactionList(transactionList);

      final BankStatementResponseTransaction bsrt = new BankStatementResponseTransaction();
      bsrt.setMessage(statementResponse);
      bsrt.setStatus(statusOk);
      bsrt.setUID(UUID.randomUUID().toString());

      final BankingResponseMessageSet brms = new BankingResponseMessageSet();

      brms.setStatementResponse(bsrt);
      responseMsgs.add(brms);

      final ResponseEnvelope response = new ResponseEnvelope();
      response.setMessageSets(responseMsgs);
      log.info("Writing ofx file");

      marshaller.marshal(response, ofxWriter);
      ofxWriter.close();

    } catch (final FileNotFoundException e) {
      log.log(Level.SEVERE, "Error while converting", e);
    } catch (final IOException e) {
      log.log(Level.SEVERE, "Error while converting", e);
    } catch (final ParseException e) {
      log.log(Level.SEVERE, "Error while converting", e);
    } catch (final NoSuchAlgorithmException e) {
      log.log(Level.SEVERE, "Error while converting", e);
    }
  }