collmex-ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/collmex.rb ADDED
@@ -0,0 +1,35 @@
1
+ require 'collmex/api'
2
+ require 'collmex/request'
3
+
4
+ module Collmex
5
+
6
+ class << self
7
+ attr_accessor :customer_id
8
+ attr_accessor :username
9
+ attr_accessor :password
10
+
11
+ def csv_opts
12
+ {
13
+ :col_sep => ";"
14
+ }
15
+ end
16
+
17
+
18
+ def setup_login_data
19
+ config = YAML.load_file('config/collmex_config.yml')["development"]
20
+ Collmex.username = config["username"]
21
+ Collmex.password = config["password"]
22
+ Collmex.customer_id = config["customer_id"]
23
+ end
24
+
25
+ def reset_login_data
26
+ Collmex.username = "000000"
27
+ Collmex.password = "000000"
28
+ Collmex.customer_id = "000000"
29
+ end
30
+ end
31
+ end
32
+
33
+ Collmex.reset_login_data
34
+
35
+
@@ -0,0 +1,361 @@
1
+ require "csv"
2
+
3
+ module Collmex
4
+ module Api
5
+
6
+ def self.is_a_collmex_api_line_obj? obj
7
+ obj.class.name =~ /Collmex\:\:Api/
8
+ end
9
+
10
+ def self.line_class_exists?(class_name)
11
+ klass = Collmex::Api.const_get(class_name)
12
+ return klass.is_a?(Class)
13
+ rescue NameError
14
+ return false
15
+ end
16
+
17
+ def self.parse_line(line)
18
+ if line.is_a?(Array) and line.first.is_a?(String)
19
+ identifyer = line.first.split("_").map{ |s| s.downcase.capitalize }.join
20
+ if self.line_class_exists?(identifyer)
21
+ Collmex::Api.const_get(identifyer).new(line)
22
+ else
23
+ raise "Could not find a Collmex::Api::Line class for \"#{identifyer}\""
24
+ end
25
+ elsif line.is_a?(String) && parsed_line = CSV.parse_line(line, Collmex.csv_opts)
26
+ identifyer = parsed_line.first.split("_").map{ |s| s.downcase.capitalize }.join
27
+ if self.line_class_exists?(identifyer)
28
+ Collmex::Api.const_get(identifyer).new(parsed_line)
29
+ else
30
+ raise "Could not find a Collmex::Api::Line class for \"#{identifyer}\""
31
+ end
32
+ else
33
+ raise "Could not parse a Collmex::Api Line from #{line.inspect}"
34
+ end
35
+ end
36
+
37
+ def self.parse_field(value, type, opts = nil)
38
+ case type
39
+ when :string then value.to_s
40
+ when :date then Date.parse(value.to_s) unless value.nil?
41
+ when :int then value.to_i unless value.nil?
42
+ when :integer then value.to_i unless value.nil?
43
+ when :float then value.to_s.gsub(',','.').to_f unless value.nil?
44
+ when :currency then Collmex::Api.parse_currency(value) unless value.nil?
45
+ end
46
+ end
47
+
48
+ def self.parse_currency(str)
49
+ str = str.to_s
50
+ case str
51
+ when /\A-?\d*[\,|.]\d{0,2}\z/ then (str.gsub(',','.').to_f * 100).to_i
52
+ when /\A-?\d+\z/ then str.to_i
53
+ when /\A-?((\d){1,3})*([\.]\d{3})+([,]\d{2})\z/ then (str.gsub('.','').gsub(',','.').to_f * 100).to_i
54
+ when /\A-?((\d){1,3})*([\,]\d{3})+([.]\d{2})\z/ then (str.gsub(',','').to_f * 100).to_i
55
+ when /\A-?((\d){1,3})*([\.\,]\d{3})+\z/ then str.gsub(',','').gsub('.','').to_i * 100
56
+ else str.to_i
57
+ end
58
+ end
59
+
60
+ def self.stringify(data, type)
61
+ case type
62
+ when :integer then (data.nil?)? data.to_s : data.to_i.to_s
63
+ when :string then data.to_s
64
+ when :float then sprintf("%.2f",data).gsub('.',',')
65
+ when :currency then Collmex::Api.stringify_currency(data)
66
+ when :date then data.strftime("%Y%m%d") unless data.nil?
67
+ end
68
+ end
69
+
70
+ def self.stringify_currency(data)
71
+ case
72
+ when data.is_a?(Integer) then sprintf("%.2f",(data.to_f / 100)).gsub('.',',')
73
+ when data.is_a?(Float) then sprintf("%.2f",(data.to_f)).gsub('.',',')
74
+ when data.is_a?(String)
75
+ int = self.parse_currency(data)
76
+ sprintf("%.2f",(int.to_f / 100)).gsub('.',',')
77
+ else data
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+
84
+
85
+ module Collmex
86
+ module Api
87
+ class Line
88
+
89
+ def self.specification
90
+ {}
91
+ end
92
+
93
+ def self.default_hash
94
+ hash = {}
95
+ self.specification.each_with_index do |field_spec, index|
96
+ if field_spec.has_key? :fix
97
+ hash[field_spec[:name]] = field_spec[:fix]
98
+ elsif field_spec.has_key? :default
99
+ hash[field_spec[:name]] = field_spec[:default]
100
+ else
101
+ hash[field_spec[:name]] = Collmex::Api.parse_field(nil, field_spec[:type])
102
+ end
103
+ end
104
+ hash
105
+ end
106
+
107
+ def self.hashify(data)
108
+ hash = self.default_hash
109
+ fields_spec = self.specification
110
+
111
+ if data.is_a? Array
112
+ fields_spec.each_with_index do |field_spec, index|
113
+ if !data[index].nil? && !field_spec.has_key?(:fix)
114
+ hash[field_spec[:name]] = Collmex::Api.parse_field(data[index], field_spec[:type])
115
+ end
116
+ end
117
+ elsif data.is_a? Hash
118
+ fields_spec.each_with_index do |field_spec, index|
119
+ if data.key?(field_spec[:name]) && !field_spec.has_key?(:fix)
120
+ hash[field_spec[:name]] = Collmex::Api.parse_field(data[field_spec[:name]], field_spec[:type])
121
+ end
122
+ end
123
+ elsif data.is_a?(String) && parsed = CSV.parse_line(data,Collmex.csv_opts)
124
+ fields_spec.each_with_index do |field_spec, index|
125
+ if !data[index].nil? && !field_spec.has_key?(:fix)
126
+ hash[field_spec[:name]] = Collmex::Api.parse_field(parsed[index], field_spec[:type])
127
+ end
128
+ end
129
+ end
130
+ hash
131
+ end
132
+
133
+
134
+ def initialize(arg = nil)
135
+ #puts self.class.name
136
+ @hash = self.class.default_hash
137
+ @hash = @hash.merge(self.class.hashify(arg)) if !arg.nil?
138
+ if self.class.specification.empty? && self.class.name.to_s != "Collmex::Api::Line"
139
+ raise "#{self.class.name} has no specification"
140
+ end
141
+ end
142
+
143
+
144
+ def to_a
145
+ array = []
146
+ self.class.specification.each do |spec|
147
+ array << @hash[spec[:name]]
148
+ end
149
+ array
150
+ end
151
+
152
+ def to_stringified_array
153
+ array = []
154
+ self.class.specification.each do |spec|
155
+ array << Collmex::Api.stringify(@hash[spec[:name]], spec[:type])
156
+ end
157
+ array
158
+ end
159
+
160
+
161
+ def to_csv
162
+ array = []
163
+ self.class.specification.each do |spec|
164
+ array << Collmex::Api.stringify(@hash[spec[:name]], spec[:type])
165
+ end
166
+ CSV.generate_line(array, Collmex.csv_opts)
167
+ end
168
+
169
+ def to_h
170
+ @hash
171
+ end
172
+
173
+
174
+ end
175
+ end
176
+ end
177
+
178
+
179
+
180
+
181
+
182
+
183
+
184
+ module Collmex
185
+ module Api
186
+
187
+ class Login < Line
188
+ def self.specification
189
+ [
190
+ { name: :identifyer, type: :string, fix: "LOGIN" },
191
+ { name: :username, type: :integer },
192
+ { name: :password, type: :integer }
193
+ ]
194
+ end
195
+ end
196
+
197
+ class Cmxknd < Line
198
+ def self.specification
199
+ [
200
+ { name: :identifyer , type: :string , fix: "CMXKND" },
201
+ { name: :customer_id , type: :integer },
202
+ { name: :company_id , type: :integer , default: 1 },
203
+ { name: :salutation , type: :string },
204
+ { name: :title , type: :string },
205
+ { name: :firstname , type: :string },
206
+ { name: :lastname , type: :string },
207
+ { name: :comapyn , type: :string },
208
+ { name: :department , type: :string },
209
+ { name: :street , type: :string },
210
+ { name: :zipcode , type: :string },
211
+ { name: :city , type: :string },
212
+ { name: :annotation , type: :string },
213
+ { name: :inactive , type: :integer },
214
+ { name: :country , type: :string },
215
+ { name: :phone , type: :string },
216
+ { name: :fax , type: :string },
217
+ { name: :email , type: :string },
218
+ { name: :account_id , type: :string },
219
+ { name: :blz , type: :string },
220
+ { name: :iban , type: :string },
221
+ { name: :bic , type: :string },
222
+ { name: :bank_name , type: :string },
223
+ { name: :vat_id , type: :string },
224
+ { name: :payment_condition, type: :integer },
225
+ { name: :dscout_group , type: :integer },
226
+ { name: :deliver_conditions, type: :string },
227
+ { name: :deliver_conditions_additions, type: :string },
228
+ { name: :output_media , type: :integer },
229
+ { name: :account_owner , type: :string },
230
+ { name: :address_group , type: :integer },
231
+ { name: :ebay_member , type: :string },
232
+ { name: :price_group , type: :integer },
233
+ { name: :currency , type: :string },
234
+ { name: :agent , type: :integer },
235
+ { name: :cost_unit , type: :string },
236
+ { name: :due_to , type: :date },
237
+ { name: :delivery_ban , type: :integer },
238
+ { name: :building_servant , type: :integer },
239
+ { name: :account_id_at_customer, type: :string },
240
+ { name: :output_language , type: :integer },
241
+ { name: :email_cc , type: :string },
242
+ { name: :phone_2 , type: :string },
243
+ ]
244
+ end
245
+ end
246
+
247
+ class Message < Line
248
+ def self.specification
249
+ [
250
+ { name: :identifyer , type: :string , fix: "MESSAGE" },
251
+ { name: :type , type: :string },
252
+ { name: :id , type: :integer },
253
+ { name: :text , type: :string },
254
+ { name: :line , type: :integer },
255
+ ]
256
+ end
257
+
258
+
259
+ def success?
260
+ if @hash.has_key?(:type) && !@hash[:type].empty? && @hash[:type] == "S"
261
+ true
262
+ else
263
+ false
264
+ end
265
+ end
266
+
267
+ def result
268
+ if @hash.has_key?(:type) && !@hash[:type].empty?
269
+ case @hash[:type]
270
+ when "S" then :success
271
+ when "W" then :warning
272
+ when "E" then :error
273
+ else :undefined
274
+ end
275
+ else
276
+ :undefined
277
+ end
278
+ end
279
+ end
280
+
281
+ class CustomerGet < Line
282
+ def self.specification
283
+ [
284
+ { name: :identifyer , type: :string , fix: "CUSTOMER_GET" },
285
+ { name: :id , type: :integer },
286
+ { name: :company_id , type: :integer , default: 1 },
287
+ { name: :searchtext , type: :string },
288
+ { name: :due_to_review , type: :integer },
289
+ { name: :zip_code , type: :string },
290
+ { name: :adress_group , type: :integer },
291
+ { name: :price_group , type: :integer },
292
+ { name: :discout_group , type: :integer },
293
+ { name: :agent , type: :integer },
294
+ { name: :only_changed , type: :integer },
295
+ { name: :system_name , type: :string },
296
+ { name: :inactive , type: :integer },
297
+ ]
298
+
299
+
300
+ end
301
+ end
302
+
303
+ class AccdocGet < Line
304
+ def self.specification
305
+ [
306
+ { name: :identifyer , type: :string , fix: "ACCDOC_GET" },
307
+ { name: :company_id , type: :integer , default: 1 },
308
+ { name: :business_year , type: :integer },
309
+ { name: :id , type: :integer },
310
+ { name: :account_id , type: :integer },
311
+ { name: :cost_unit , type: :integer },
312
+ { name: :customer_id , type: :integer },
313
+ { name: :provider_id , type: :integer },
314
+ { name: :asset_id , type: :integer },
315
+ { name: :invoice_id , type: :integer },
316
+ { name: :jorney_id , type: :integer },
317
+ { name: :text , type: :string },
318
+ { name: :date_start , type: :date },
319
+ { name: :date_end , type: :date },
320
+ { name: :cancellattion , type: :integer },
321
+ { name: :changed_only , type: :integer },
322
+ { name: :system_name , type: :string },
323
+ ]
324
+ end
325
+ end
326
+
327
+ class Accdoc < Line
328
+ def self.specification
329
+ [
330
+ { name: :identifyer , type: :string , fix: "ACCDOC" },
331
+ { name: :company_id , type: :integer , default: 1 },
332
+ { name: :business_year , type: :integer },
333
+ { name: :id , type: :integer },
334
+ { name: :accdoc_date , type: :date },
335
+ { name: :accounted_date , type: :date },
336
+ { name: :test , type: :string },
337
+ { name: :position_id , type: :integer },
338
+ { name: :account_id , type: :integer },
339
+ { name: :account_name , type: :string },
340
+ { name: :should_have , type: :integer },
341
+ { name: :amount , type: :currency },
342
+ { name: :customer_id , type: :integer },
343
+ { name: :customer_name , type: :string },
344
+ { name: :provider_id , type: :integer },
345
+ { name: :provider_name , type: :string },
346
+ { name: :asset_id , type: :integer },
347
+ { name: :asset_name , type: :string },
348
+ { name: :canceled_accdoc , type: :integer },
349
+ { name: :cost_unit , type: :string },
350
+ { name: :invoice_id , type: :string },
351
+ { name: :customer_order_id, type: :integer },
352
+ { name: :jorney_id , type: :integer },
353
+ { name: :belongs_to_id , type: :integer },
354
+ { name: :belongs_to_year , type: :integer },
355
+ { name: :belongs_to_pos , type: :integer },
356
+ ]
357
+ end
358
+ end
359
+
360
+ end
361
+ end
File without changes
File without changes
@@ -0,0 +1,95 @@
1
+ require "net/http"
2
+ require "uri"
3
+
4
+ module Collmex
5
+ class Request
6
+
7
+
8
+ attr_accessor :commands, :http
9
+
10
+
11
+ def self.run(&block)
12
+ Request.new.tap do |request|
13
+ request.instance_eval &block if block_given?
14
+ request.execute
15
+ end
16
+ end
17
+
18
+
19
+ def self.classify(term)
20
+ term.to_s.split("_").collect(&:capitalize).join
21
+ end
22
+
23
+
24
+ def enqueue(command, args = {})
25
+ if command.is_a? Symbol
26
+ add_command Collmex::Api::const_get(self.class.classify(command)).new(args)
27
+ elsif Collmex::Api.is_a_collmex_api_line_obj?(command)
28
+ add_command command
29
+ else
30
+ return false
31
+ end
32
+ end
33
+
34
+
35
+ def initialize
36
+ @commands = []
37
+ @raw_response = {}
38
+
39
+ add_command Collmex::Api::Login.new({username: Collmex.username, password: Collmex.password})
40
+ end
41
+
42
+
43
+ def add_command(cmd)
44
+ @commands << cmd
45
+ cmd
46
+ end
47
+
48
+
49
+ def self.uri
50
+ URI.parse "https://www.collmex.de/cgi-bin/cgi.exe\?#{Collmex.customer_id},0,data_exchange"
51
+ end
52
+
53
+
54
+ def self.header_attributes
55
+ {"Content-Type" => "text/csv"}
56
+ end
57
+
58
+ def payload
59
+ @commands.map{ |c| c.to_csv }.join
60
+ end
61
+
62
+
63
+ def parse_response
64
+ @response = @raw_response[:array].map { |l| Collmex::Api.parse_line(l) }
65
+ @response
66
+ end
67
+
68
+ def raw_response
69
+ @raw_response
70
+ end
71
+
72
+
73
+ def response
74
+ @response
75
+ end
76
+
77
+
78
+ def execute
79
+ @http = Net::HTTP.new(Collmex::Request.uri.host, Collmex::Request.uri.port)
80
+ @http.use_ssl = true
81
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
82
+
83
+ response = @http.request_post(Collmex::Request.uri.request_uri, self.payload, Collmex::Request.header_attributes)
84
+
85
+ response.body.force_encoding("ISO8859-1") if response.body.encoding.to_s == "ASCII-8BIT"
86
+
87
+ @raw_response[:string] = response.body.encode("UTF-8")
88
+ @raw_response[:array] = CSV.parse(@raw_response[:string], Collmex.csv_opts)
89
+
90
+ return parse_response
91
+ end
92
+
93
+
94
+ end
95
+ end