# Copyright © 2007 Chris Guidry # # This file is part of OFX for Ruby. # # OFX for Ruby is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # OFX for Ruby is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . require File.dirname(__FILE__) + '/document' require File.dirname(__FILE__) + '/header' require File.dirname(__FILE__) + '/message_set' require File.dirname(__FILE__) + '/status' require File.dirname(__FILE__) + '/statements' require File.dirname(__FILE__) + '/signon_message_set' require File.dirname(__FILE__) + '/signup_message_set' require File.dirname(__FILE__) + '/banking_message_set' require File.dirname(__FILE__) + '/credit_card_statement_message_set' require File.dirname(__FILE__) + '/investment_statement_message_set' require File.dirname(__FILE__) + '/interbank_funds_transfer_message_set' require File.dirname(__FILE__) + '/wire_funds_transfer_message_set' require File.dirname(__FILE__) + '/payment_message_set' require File.dirname(__FILE__) + '/email_message_set' require File.dirname(__FILE__) + '/investment_security_list_message_set' require File.dirname(__FILE__) + '/financial_institution_profile_message_set' require File.dirname(__FILE__) + '/parser' require 'date' require 'time' module OFX module OFX102 class Serializer def to_http_post_body(document) body = "" body += document.header.to_ofx_102_s body += "\n" body += "\n" document.message_sets.each do |message_set| body += message_set.to_ofx_102_s end body += "\n" # puts body body end def from_http_response_body(body) # puts "Raw response:\n#{body}" #header_pattern = /(\w+\:.*\n)+\n/ header_pattern = /(\w+\:.*\r*\n)+\r*\n/ header_match = header_pattern.match(body) if header_match.nil? raise NotImplementedError, "OFX server returned unmatched ASCII" return body end body = header_match.post_match header = Header.from_ofx_102_s(header_match[0].strip) parser = OFX::OFX102::Parser.new parser.scan_str body if parser.documents.length > 1 raise NotImplementedError, "Multiple response documents" end # require 'pp' # pp parser.ofx_hashes[0] document = parser.documents[0] document.header = header document end end end end class Date def to_ofx_102_s strftime('%Y%m%d') end end class DateTime def to_time Time.parse(self.to_s) end def to_ofx_102_s_defunct strftime('%Y%m%d%H%M%S.') + (sec_fraction * 86400000000).to_i.to_s + '[' + offset.numerator.to_s + ':' + strftime('%Z') + ']' end def to_ofx_102_s(extended=true) s = strftime('%Y%m%d%H%M%S') if extended # some servers need exactly 3 decimal places for sec_fraction s = s + '.000' # use Time class to return TZ in correct format for OFX # ie. ("EDT" vs. "-07:00") tz = to_time.zone s = s + '[0:' + tz + ']' if tz end return s end end class String def to_date Date.parse(self) end def to_datetime DateTime.parse(self) end def to_time ('-47120101' + self).to_datetime end end class TrueClass def to_ofx_102_s 'Y' end end class FalseClass def to_ofx_102_s 'Y' end end