model.rb
4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
class Kalibro::Model
attr_accessor :errors
def initialize(attributes={})
attributes.each { |field, value| send("#{field}=", value) if self.class.is_valid?(field) }
@errors = []
end
def to_hash(options={})
hash = Hash.new
excepts = options[:except].nil? ? [] : options[:except]
excepts << :errors
fields.each do |field|
if(!excepts.include?(field))
field_value = send(field)
if !field_value.nil?
hash[field] = convert_to_hash(field_value)
if field_value.is_a?(Kalibro::Model)
hash = {:attributes! => {}}.merge(hash)
hash[:attributes!][field.to_sym] = {
'xmlns:xsi'=> 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:type' => 'kalibro:' + xml_instance_class_name(field_value) }
end
end
end
end
hash
end
def self.request(action, request_body = nil)
response = client(endpoint).request(:kalibro, action) { soap.body = request_body }
response.to_hash["#{action}_response".to_sym] # response is a Savon::SOAP::Response, and to_hash is a Savon::SOAP::Response method
end
def self.to_objects_array value
array = value.kind_of?(Array) ? value : [value]
array.each.collect { |element| to_object(element) }
end
def self.to_object value
value.kind_of?(Hash) ? new(value) : value
end
def self.create(attributes={})
new_model = new attributes
new_model.save
new_model
end
def self.find(id)
if(exists?(id))
new request(find_action, id_params(id))["#{class_name.underscore}".to_sym]
else
raise Kalibro::Errors::RecordNotFound
end
end
def save
begin
self.id = self.class.request(save_action, save_params)["#{instance_class_name.underscore}_id".to_sym]
true
rescue Exception => exception
add_error exception
false
end
end
def destroy
begin
self.class.request(destroy_action, destroy_params)
rescue Exception => exception
add_error exception
end
end
def self.exists?(id)
request(exists_action, id_params(id))[:exists]
end
protected
def fields
instance_variable_names.each.collect { |variable| variable.to_s.sub(/@/, '').to_sym }
end
def convert_to_hash(value)
return value if value.nil?
return value.collect { |element| convert_to_hash(element) } if value.is_a?(Array)
return value.to_hash if value.is_a?(Kalibro::Model)
return self.class.date_with_milliseconds(value) if value.is_a?(DateTime)
return 'INF' if value.is_a?(Float) and value.infinite? == 1
return '-INF' if value.is_a?(Float) and value.infinite? == -1
value.to_s
end
def xml_instance_class_name(object)
xml_name = object.class.name
xml_name["Kalibro::"] = ""
xml_name[0..0] = xml_name[0..0].downcase
xml_name + "Xml"
end
def self.client(endpoint)
service_address = YAML.load_file("#{RAILS_ROOT}/plugins/mezuro/service.yml")
Savon::Client.new("#{service_address}#{endpoint}Endpoint/?wsdl")
end
def self.is_valid?(field)
field.to_s[0] != '@' and field != :attributes! and (field.to_s =~ /xsi/).nil?
end
def self.date_with_milliseconds(date)
milliseconds = "." + (date.sec_fraction * 60 * 60 * 24 * 1000).to_s
date.to_s[0..18] + milliseconds + date.to_s[19..-1]
end
def instance_class_name
self.class.name.gsub(/Kalibro::/,"")
end
def self.endpoint
class_name
end
def save_action
"save_#{instance_class_name.underscore}".to_sym
end
def save_params
{instance_class_name.underscore.to_sym => self.to_hash}
end
def destroy_action
"delete_#{instance_class_name.underscore}".to_sym
end
def destroy_params
{"#{instance_class_name.underscore}_id".to_sym => self.id}
end
def self.class_name
self.name.gsub(/Kalibro::/,"")
end
def self.exists_action
"#{class_name.underscore}_exists".to_sym
end
def self.id_params(id)
{"#{class_name.underscore}_id".to_sym => id}
end
def self.find_action
"get_#{class_name.underscore}".to_sym
end
def add_error(exception)
@errors << exception
end
end