xmlconv2 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/History.txt +6 -0
  2. data/LICENCE.txt +339 -0
  3. data/Manifest.txt +107 -0
  4. data/README.txt +25 -0
  5. data/Rakefile +28 -0
  6. data/bin/admin +65 -0
  7. data/bin/xmlconvd +19 -0
  8. data/data/grammar/i2.grammar +73 -0
  9. data/src/conversion/bdd_geh.rb +281 -0
  10. data/src/conversion/bdd_i2.rb +102 -0
  11. data/src/conversion/bdd_xml.rb +242 -0
  12. data/src/conversion/geh_bdd.rb +165 -0
  13. data/src/conversion/i2_bdd.rb +271 -0
  14. data/src/conversion/xml_bdd.rb +125 -0
  15. data/src/custom/lookandfeel.rb +47 -0
  16. data/src/i2/address.rb +33 -0
  17. data/src/i2/date.rb +37 -0
  18. data/src/i2/document.rb +26 -0
  19. data/src/i2/header.rb +24 -0
  20. data/src/i2/order.rb +44 -0
  21. data/src/i2/parser.rb +25 -0
  22. data/src/i2/position.rb +37 -0
  23. data/src/i2/record.rb +11 -0
  24. data/src/model/address.rb +20 -0
  25. data/src/model/agreement.rb +10 -0
  26. data/src/model/bdd.rb +26 -0
  27. data/src/model/bsr.rb +16 -0
  28. data/src/model/delivery.rb +15 -0
  29. data/src/model/delivery_item.rb +18 -0
  30. data/src/model/freetext_container.rb +26 -0
  31. data/src/model/id_container.rb +15 -0
  32. data/src/model/invoice.rb +18 -0
  33. data/src/model/invoice_item.rb +11 -0
  34. data/src/model/item.rb +19 -0
  35. data/src/model/item_container.rb +15 -0
  36. data/src/model/name.rb +27 -0
  37. data/src/model/part_info.rb +10 -0
  38. data/src/model/part_info_container.rb +15 -0
  39. data/src/model/party.rb +23 -0
  40. data/src/model/party_container.rb +20 -0
  41. data/src/model/price.rb +10 -0
  42. data/src/model/price_container.rb +18 -0
  43. data/src/model/transaction.rb +28 -0
  44. data/src/state/global.rb +28 -0
  45. data/src/state/global_predefine.rb +11 -0
  46. data/src/state/login.rb +38 -0
  47. data/src/state/transaction.rb +13 -0
  48. data/src/state/transactions.rb +130 -0
  49. data/src/util/application.rb +143 -0
  50. data/src/util/destination.rb +130 -0
  51. data/src/util/invoicer.rb +72 -0
  52. data/src/util/known_user.rb +16 -0
  53. data/src/util/polling_manager.rb +78 -0
  54. data/src/util/session.rb +23 -0
  55. data/src/util/transaction.rb +105 -0
  56. data/src/util/validator.rb +20 -0
  57. data/src/view/foot.rb +27 -0
  58. data/src/view/head.rb +13 -0
  59. data/src/view/login.rb +36 -0
  60. data/src/view/navigation.rb +30 -0
  61. data/src/view/navigationlink.rb +21 -0
  62. data/src/view/pager.rb +73 -0
  63. data/src/view/preformatted.rb +39 -0
  64. data/src/view/template.rb +17 -0
  65. data/src/view/transaction.rb +42 -0
  66. data/src/view/transactions.rb +90 -0
  67. data/test/mock.rb +149 -0
  68. data/test/suite.rb +16 -0
  69. data/test/test_conversion/bdd_geh.rb +533 -0
  70. data/test/test_conversion/bdd_i2.rb +314 -0
  71. data/test/test_conversion/bdd_xml.rb +556 -0
  72. data/test/test_conversion/geh_bdd.rb +372 -0
  73. data/test/test_conversion/i2_bdd.rb +804 -0
  74. data/test/test_conversion/xml_bdd.rb +203 -0
  75. data/test/test_i2/address.rb +88 -0
  76. data/test/test_i2/date.rb +49 -0
  77. data/test/test_i2/document.rb +62 -0
  78. data/test/test_i2/header.rb +39 -0
  79. data/test/test_i2/order.rb +94 -0
  80. data/test/test_i2/parser.rb +309 -0
  81. data/test/test_i2/position.rb +65 -0
  82. data/test/test_integration/geh_i2.rb +312 -0
  83. data/test/test_integration/i2_geh.rb +449 -0
  84. data/test/test_integration/i2_xml.rb +162 -0
  85. data/test/test_integration/xml_i2.rb +254 -0
  86. data/test/test_model/address.rb +35 -0
  87. data/test/test_model/agreement.rb +22 -0
  88. data/test/test_model/bdd.rb +55 -0
  89. data/test/test_model/bsr.rb +38 -0
  90. data/test/test_model/delivery.rb +79 -0
  91. data/test/test_model/delivery_item.rb +52 -0
  92. data/test/test_model/freetext_container.rb +45 -0
  93. data/test/test_model/invoice.rb +65 -0
  94. data/test/test_model/invoice_item.rb +41 -0
  95. data/test/test_model/name.rb +57 -0
  96. data/test/test_model/part_info.rb +24 -0
  97. data/test/test_model/party.rb +96 -0
  98. data/test/test_model/price.rb +24 -0
  99. data/test/test_util/application.rb +168 -0
  100. data/test/test_util/destination.rb +197 -0
  101. data/test/test_util/invoicer.rb +36 -0
  102. data/test/test_util/polling_manager.rb +111 -0
  103. data/test/test_util/transaction.rb +129 -0
  104. data/user-stories/UserStories_XmlConv2.txt +381 -0
  105. data/user-stories/doku/ABB.incoming.HTTP.invoice.xml +315 -0
  106. data/user-stories/doku/ABB.received.xml +259 -0
  107. data/user-stories/doku/BO_OrderProcessing.sxw +0 -0
  108. metadata +195 -0
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env ruby
2
+ # Destination -- xmlconv2 -- 08.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'fileutils'
5
+ require 'uri'
6
+ require 'odba'
7
+ require 'net/http'
8
+
9
+ module XmlConv
10
+ module Util
11
+ class Destination
12
+ include ODBA::Persistable
13
+ attr_accessor :path
14
+ attr_reader :uri, :status
15
+ STATUS_COMPARABLE = {
16
+ :pending_pickup => 10,
17
+ :picked_up => 20,
18
+ :http_ok => 20
19
+ }
20
+ def initialize
21
+ @status = :open
22
+ end
23
+ def deliver(delivery)
24
+ raise 'Abstract Method deliver called in Destination'
25
+ end
26
+ def update_status
27
+ end
28
+ def status_comparable
29
+ self::class::STATUS_COMPARABLE[@status].to_i
30
+ end
31
+ def forget_credentials!
32
+ end
33
+ end
34
+ class DestinationDir < Destination
35
+ attr_reader :filename
36
+ def deliver(delivery)
37
+ do_deliver(delivery)
38
+ @status = :pending_pickup
39
+ odba_store
40
+ end
41
+ def do_deliver(delivery)
42
+ if(delivery.is_a?(Array))
43
+ delivery.each { |part| do_deliver(part) }
44
+ else
45
+ FileUtils.mkdir_p(@path)
46
+ @filename = if(delivery.respond_to?(:filename))
47
+ delivery.filename
48
+ else
49
+ "%.5f.txt" % Time.now.to_f
50
+ end
51
+ path = File.expand_path(@filename, @path)
52
+ File.open(path, 'w') { |fh| fh << delivery.to_s }
53
+ end
54
+ end
55
+ def update_status
56
+ if(@status == :pending_pickup \
57
+ && !File.exist?(File.expand_path(@filename.to_s, @path)))
58
+ @status = :picked_up
59
+ odba_store
60
+ end
61
+ end
62
+ def uri
63
+ URI.parse("file:#{File.expand_path(@filename.to_s, @path)}")
64
+ end
65
+ end
66
+ class DestinationHttp < Destination
67
+ HTTP_CLASS = Net::HTTP # replaceable for testing purposes
68
+ HTTP_HEADERS = {
69
+ 'content-type' => 'text/xml',
70
+ }
71
+ def initialize
72
+ super
73
+ @uri = URI.parse('http:/')
74
+ end
75
+ def deliver(delivery)
76
+ do_deliver(delivery)
77
+ ensure
78
+ forget_credentials!
79
+ end
80
+ def do_deliver(delivery)
81
+ if(delivery.is_a?(Array))
82
+ worst_status = ''
83
+ delivery.each { |part|
84
+ do_deliver(part)
85
+ ## bogostatus: assume that the more information in the string,
86
+ ## the worse the status is (ok < not found)
87
+ ## rationale: DTSTTCPW
88
+ if(@status.to_s > worst_status.to_s)
89
+ worst_status = @status
90
+ end
91
+ }
92
+ @status = worst_status
93
+ else
94
+ self.class::HTTP_CLASS.start(@uri.host, @uri.port) { |http|
95
+ request = Net::HTTP::Post.new(@uri.path, HTTP_HEADERS)
96
+ if(@uri.user || @uri.password)
97
+ request.basic_auth(@uri.user, @uri.password)
98
+ end
99
+ response = http.request(request, delivery.to_s)
100
+ status_str = response.message.downcase.gsub(/\s+/, "_")
101
+ @status = "http_#{status_str}".intern
102
+ }
103
+ end
104
+ end
105
+ def forget_credentials!
106
+ @uri = URI::HTTP.new(@uri.scheme, nil, @uri.host, @uri.port,
107
+ @uri.registry, @uri.path, @uri.opaque, @uri.query, @uri.fragment)
108
+ end
109
+ def host
110
+ @uri.host
111
+ end
112
+ def host=(str)
113
+ @uri.host = str
114
+ end
115
+ def path
116
+ @uri.path if(@uri)
117
+ end
118
+ def path=(str)
119
+ @uri.path = str if(@uri)
120
+ end
121
+ def uri=(uri)
122
+ if(uri.is_a?(String))
123
+ @uri = URI.parse(uri)
124
+ else
125
+ @uri = uri
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env ruby
2
+ # Util::Invoicer -- xmlconv2 -- 03.08.2006 -- hwyss@ywesee.com
3
+
4
+ require 'ydim/config'
5
+ require 'ydim/client'
6
+ require 'openssl'
7
+
8
+ module XmlConv
9
+ module Util
10
+ class Invoicer
11
+ class << self
12
+ def create_invoice(time_range, groups, date, currency='CHF')
13
+ time = Time.now
14
+ format = "Umsatzbeteiligung %s\nCHF %1.2f Umsatz\naus %i Rechnungs-�bermittlungen"
15
+ ydim_connect { |client|
16
+ ydim_inv = client.create_invoice(YDIM_ID)
17
+ ydim_inv.description = sprintf("Umsatzbeteiligung %s-%s",
18
+ time_range.first.strftime("%d.%m.%Y"),
19
+ (time_range.last - 1).strftime("%d.%m.%Y"))
20
+ ydim_inv.date = date
21
+ ydim_inv.currency = currency
22
+ ydim_inv.payment_period = 30
23
+ item_data = groups.sort.collect { |group, bdds|
24
+ amount = 0
25
+ invoices = 0
26
+ bdds.each { |bdd|
27
+ amount += bdd.invoiced_amount
28
+ invoices += 1 unless(bdd.invoices.empty?)
29
+ }
30
+ {
31
+ :price => (amount * 1.5) / 1000.0,
32
+ :quantity => 1,
33
+ :text => sprintf(format, group.to_s, amount, invoices),
34
+ :time => Time.local(date.year, date.month, date.day),
35
+ :unit => "0.15%",
36
+ }
37
+ }
38
+ client.add_items(ydim_inv.unique_id, item_data)
39
+ ydim_inv
40
+ }
41
+ end
42
+ def group_by_partner(transactions)
43
+ groups = {}
44
+ transactions.each { |transaction|
45
+ (groups[transaction.partner] ||= []).push(transaction.model)
46
+ }
47
+ groups
48
+ end
49
+ def run(time_range, transactions, date)
50
+ unless(transactions.empty?)
51
+ invoice = create_invoice(time_range, group_by_partner(transactions),
52
+ date)
53
+ send_invoice(invoice.unique_id)
54
+ end
55
+ end
56
+ def send_invoice(invoice_id)
57
+ ydim_connect { |client| client.send_invoice(invoice_id) }
58
+ end
59
+ def ydim_connect(&block)
60
+ config = YDIM::Client::CONFIG
61
+ server = DRbObject.new(nil, config.server_url)
62
+ client = YDIM::Client.new(config)
63
+ key = OpenSSL::PKey::DSA.new(File.read(config.private_key))
64
+ client.login(server, key)
65
+ block.call(client)
66
+ ensure
67
+ client.logout if(client)
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ # Util::KnownUser -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'sbsm/user'
5
+ require 'state/transactions'
6
+
7
+ module XmlConv
8
+ module Util
9
+ class KnownUser < SBSM::KnownUser
10
+ HOME = State::Transactions
11
+ NAVIGATION = [
12
+ :home, :logout
13
+ ]
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env ruby
2
+ # Util::PollingManager -- xmlconv2 -- 29.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'fileutils'
5
+ require 'uri'
6
+ require 'yaml'
7
+ require 'util/destination'
8
+ require 'util/transaction'
9
+
10
+ module XmlConv
11
+ module Util
12
+ class PollingMission
13
+ attr_accessor :directory, :reader, :writer, :destination,
14
+ :error_recipients, :debug_recipients, :backup_dir,
15
+ :glob_pattern, :partner
16
+ end
17
+ class PollingManager
18
+ PROJECT_ROOT = File.expand_path('../..', File.dirname(__FILE__))
19
+ CONFIG_PATH = File.expand_path('etc/polling.yaml', PROJECT_ROOT)
20
+ def initialize(system)
21
+ @system = system
22
+ end
23
+ def destination(str)
24
+ uri = URI.parse(str)
25
+ case uri
26
+ when URI::HTTP
27
+ dest = DestinationHttp.new
28
+ dest.uri = uri
29
+ dest
30
+ else
31
+ dest = DestinationDir.new
32
+ dest.path = str
33
+ dest
34
+ end
35
+ end
36
+ def load_sources(&block)
37
+ file = File.open(self::class::CONFIG_PATH)
38
+ YAML.load_documents(file) { |mission|
39
+ path = File.expand_path(mission.directory, PROJECT_ROOT)
40
+ mission.directory = path
41
+ block.call(mission)
42
+ }
43
+ ensure
44
+ file.close if(file)
45
+ end
46
+ def file_paths(dir_path, pattern=nil)
47
+ Dir.glob(File.expand_path(pattern || '*', dir_path)).collect { |entry|
48
+ File.expand_path(entry, dir_path)
49
+ }.compact
50
+ end
51
+ def poll(source)
52
+ file_paths(source.directory, source.glob_pattern).each { |path|
53
+ begin
54
+ transaction = XmlConv::Util::Transaction.new
55
+ transaction.input = File.read(path)
56
+ transaction.partner = source.partner
57
+ transaction.origin = 'file:' << path
58
+ transaction.reader = source.reader
59
+ transaction.writer = source.writer
60
+ transaction.destination = destination(source.destination)
61
+ transaction.debug_recipients = source.debug_recipients
62
+ transaction.error_recipients = source.error_recipients
63
+ @system.execute(transaction)
64
+ ensure
65
+ backup_dir = source.backup_dir
66
+ FileUtils.mkdir_p(backup_dir)
67
+ FileUtils.mv(path, backup_dir)
68
+ end
69
+ }
70
+ end
71
+ def poll_sources
72
+ load_sources { |source|
73
+ poll(source)
74
+ }
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+ # Session -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'sbsm/session'
5
+ require 'state/login'
6
+ require 'custom/lookandfeel'
7
+ require 'util/known_user'
8
+
9
+ module XmlConv
10
+ module Util
11
+ class Session < SBSM::Session
12
+ DEFAULT_LANGUAGE = 'de'
13
+ DEFAULT_STATE = State::Login
14
+ LOOKANDFEEL = Custom::Lookandfeel
15
+ def login
16
+ if((pass = user_input(:pass)) \
17
+ && (pass == "6646c9e7892ef147dbed611a00ea48e6"))
18
+ @user = Util::KnownUser.new
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env ruby
2
+ # Util::Transaction -- xmlconv2 -- 04.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'odba'
5
+ require 'conversion/bdd_geh'
6
+ require 'conversion/bdd_i2'
7
+ require 'conversion/bdd_xml'
8
+ require 'conversion/geh_bdd'
9
+ require 'conversion/i2_bdd'
10
+ require 'conversion/xml_bdd'
11
+ require 'util/destination'
12
+ require 'net/smtp'
13
+ require 'tmail'
14
+
15
+ module XmlConv
16
+ module Util
17
+ class Transaction
18
+ include ODBA::Persistable
19
+ MAIL_FROM = 'xmlconv@ywesee.com'
20
+ SMTP_HANDLER = Net::SMTP
21
+ attr_accessor :input, :reader, :writer, :destination, :origin,
22
+ :transaction_id, :partner, :error,
23
+ :error_recipients, :debug_recipients
24
+ attr_reader :output, :model, :start_time, :commit_time,
25
+ :input_model, :output_model, :status
26
+ def execute
27
+ reader_instance = Conversion.const_get(@reader)
28
+ writer_instance = Conversion.const_get(@writer)
29
+ @start_time = Time.now
30
+ input_model = reader_instance.parse(@input)
31
+ @model = reader_instance.convert(input_model)
32
+ output_model = writer_instance.convert(@model)
33
+ @output = output_model.to_s
34
+ @destination.deliver(output_model)
35
+ @commit_time = Time.now
36
+ @output
37
+ ensure
38
+ @destination.forget_credentials!
39
+ end
40
+ def notify
41
+ recipients = [@debug_recipients]
42
+ subject = 'XmlConv2 - Debug-Notification'
43
+ if(@error)
44
+ recipients.push(@error_recipients)
45
+ subject = 'XmlConv2 - Error-Notification'
46
+ end
47
+ recipients.flatten!
48
+ recipients.compact!
49
+ recipients.uniq!
50
+ return if(recipients.empty?)
51
+ mail = TMail::Mail.new
52
+ mail.set_content_type('text', 'plain', 'charset'=>'ISO-8859-1')
53
+ mail.body = <<-EOS
54
+ Date: #{@start_time.strftime("%d.%m.%Y")}
55
+ Time: #{@start_time.strftime("%H:%M:%S")}
56
+ Status: #{status}
57
+ Error: #{@error}
58
+ Link: http://janico.ywesee.com/de/transaction/transaction_id/#{@transaction_id}
59
+
60
+ Input:
61
+ # input start
62
+ #{@input}
63
+ # input end
64
+
65
+ Output:
66
+ # output start
67
+ #{@output}
68
+ # output end
69
+ EOS
70
+ mail.from = self::class::MAIL_FROM
71
+ mail.to = recipients
72
+ mail.subject = subject
73
+ mail.date = Time.now
74
+ mail['User-Agent'] = 'XmlConv::Util::Transaction'
75
+
76
+ self.class::SMTP_HANDLER.start('mail.ywesee.com') { |smtp|
77
+ smtp.sendmail(mail.encoded, self::class::MAIL_FROM, recipients)
78
+ }
79
+ end
80
+ def status
81
+ if(@error)
82
+ :error
83
+ elsif(@destination.respond_to?(:status))
84
+ @destination.status
85
+ end
86
+ end
87
+ def status_comparable
88
+ if(@destination.respond_to?(:status_comparable))
89
+ @destination.status_comparable
90
+ end
91
+ end
92
+ def update_status
93
+ if(@destination.respond_to?(:update_status))
94
+ @destination.update_status
95
+ end
96
+ end
97
+ def uri
98
+ @destination.uri if(@destination.respond_to?(:uri))
99
+ end
100
+ def uri_comparable
101
+ self.uri.to_s
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ # Util::Validator -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'sbsm/validator'
5
+
6
+ module XmlConv
7
+ module Util
8
+ class Validator < SBSM::Validator
9
+ EVENTS = [
10
+ :login, :logout, :sort, :transaction, :self, :home
11
+ ]
12
+ STRINGS = [
13
+ :sortvalue,
14
+ ]
15
+ NUMERIC = [
16
+ :transaction_id, :page
17
+ ]
18
+ end
19
+ end
20
+ end