netsuite 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +0 -2
- data/README.md +154 -0
- data/lib/netsuite.rb +7 -0
- data/lib/netsuite/actions/add.rb +6 -21
- data/lib/netsuite/actions/delete.rb +7 -10
- data/lib/netsuite/actions/get.rb +7 -10
- data/lib/netsuite/actions/get_list.rb +77 -0
- data/lib/netsuite/actions/get_select_value.rb +71 -0
- data/lib/netsuite/actions/search.rb +151 -36
- data/lib/netsuite/actions/search_more_with_id.rb +3 -2
- data/lib/netsuite/actions/update.rb +16 -16
- data/lib/netsuite/configuration.rb +29 -15
- data/lib/netsuite/namespaces/list_support.rb +11 -0
- data/lib/netsuite/records/account.rb +1 -0
- data/lib/netsuite/records/base_ref_list.rb +33 -0
- data/lib/netsuite/records/cash_sale.rb +7 -0
- data/lib/netsuite/records/custom_field.rb +2 -1
- data/lib/netsuite/records/custom_field_list.rb +62 -12
- data/lib/netsuite/records/custom_record.rb +1 -7
- data/lib/netsuite/records/custom_record_ref.rb +7 -0
- data/lib/netsuite/records/customer.rb +4 -3
- data/lib/netsuite/records/phone_call.rb +29 -0
- data/lib/netsuite/records/record_ref.rb +1 -9
- data/lib/netsuite/records/sales_order.rb +2 -1
- data/lib/netsuite/records/support_case.rb +32 -0
- data/lib/netsuite/records/task.rb +4 -3
- data/lib/netsuite/records/transaction.rb +4 -21
- data/lib/netsuite/support/actions.rb +4 -0
- data/lib/netsuite/support/records.rb +3 -0
- data/lib/netsuite/support/search_result.rb +53 -29
- data/lib/netsuite/version.rb +1 -1
- data/netsuite.gemspec +1 -1
- data/spec/netsuite/actions/add_spec.rb +9 -13
- data/spec/netsuite/actions/delete_spec.rb +5 -8
- data/spec/netsuite/actions/get_spec.rb +39 -24
- data/spec/netsuite/actions/search_spec.rb +149 -0
- data/spec/netsuite/actions/update_spec.rb +9 -13
- data/spec/netsuite/configuration_spec.rb +3 -9
- data/spec/netsuite/records/custom_field_list_spec.rb +19 -5
- data/spec/netsuite/records/customer_spec.rb +2 -2
- data/spec/netsuite/records/phone_call_spec.rb +23 -0
- data/spec/netsuite/records/support_case_spec.rb +157 -0
- data/spec/support/fixtures/search/saved_search_customer.xml +54 -0
- data/spec/support/fixtures/search/saved_search_joined_custom_customer.xml +87 -0
- metadata +21 -4
@@ -1,4 +1,3 @@
|
|
1
|
-
# TODO: Tests
|
2
1
|
module NetSuite
|
3
2
|
module Actions
|
4
3
|
class Search
|
@@ -12,23 +11,20 @@ module NetSuite
|
|
12
11
|
private
|
13
12
|
|
14
13
|
def request
|
15
|
-
# https://system.netsuite.com/help/helpcenter/en_US/Output/Help/
|
14
|
+
# https://system.netsuite.com/help/helpcenter/en_US/Output/Help/SuiteCloudCustomizationScriptingWebServices/SuiteTalkWebServices/SettingSearchPreferences.html
|
15
|
+
# https://webservices.netsuite.com/xsd/platform/v2012_2_0/messages.xsd
|
16
|
+
|
16
17
|
preferences = NetSuite::Configuration.auth_header
|
17
|
-
preferences = preferences.merge(
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
'xmlns:listRel' => "urn:relationships_#{NetSuite::Configuration.api_version}.lists.webservices.netsuite.com",
|
28
|
-
'xmlns:tranSales' => "urn:sales_#{NetSuite::Configuration.api_version}.transactions.webservices.netsuite.com",
|
29
|
-
},
|
30
|
-
soap_header: preferences
|
31
|
-
).call :search, :message => request_body
|
18
|
+
preferences = preferences.merge(
|
19
|
+
(@options[:preferences] || {}).inject({'platformMsgs:SearchPreferences' => {}}) do |h, (k, v)|
|
20
|
+
h['platformMsgs:SearchPreferences'][k.to_s.lower_camelcase] = v
|
21
|
+
h
|
22
|
+
end
|
23
|
+
)
|
24
|
+
|
25
|
+
NetSuite::Configuration
|
26
|
+
.connection(soap_header: preferences)
|
27
|
+
.call (@options.has_key?(:search_id)? :search_more_with_id : :search), :message => request_body
|
32
28
|
end
|
33
29
|
|
34
30
|
# basic search XML
|
@@ -46,41 +42,151 @@ module NetSuite
|
|
46
42
|
# </soap:Body>
|
47
43
|
|
48
44
|
def request_body
|
45
|
+
if @options.has_key?(:search_id)
|
46
|
+
return {
|
47
|
+
'pageIndex' => @options[:page_index],
|
48
|
+
'searchId' => @options[:search_id],
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
# columns is only needed for advanced search results
|
53
|
+
columns = @options[:columns] || {}
|
49
54
|
criteria = @options[:criteria] || @options
|
50
55
|
|
51
|
-
# TODO
|
56
|
+
# TODO find cleaner solution for pulling the namespace of the record, which is a instance method
|
52
57
|
example_instance = @klass.new
|
53
58
|
namespace = example_instance.record_namespace
|
54
59
|
|
55
|
-
# extract the class name
|
60
|
+
# extract the class name
|
56
61
|
class_name = @klass.to_s.split("::").last
|
57
62
|
|
58
|
-
|
63
|
+
criteria_structure = {}
|
64
|
+
columns_structure = columns
|
65
|
+
saved_search_id = criteria.delete(:saved)
|
59
66
|
|
60
|
-
|
61
|
-
|
62
|
-
h["platformCommon:#{condition[:field]}"] = {
|
63
|
-
"platformCore:searchValue" => condition[:value]
|
64
|
-
}
|
67
|
+
# TODO this whole thing needs to be refactored so we can apply some of the same logic to the
|
68
|
+
# column creation xml
|
65
69
|
|
66
|
-
|
67
|
-
|
68
|
-
|
70
|
+
criteria.each_pair do |condition_category, conditions|
|
71
|
+
criteria_structure["#{namespace}:#{condition_category}"] = conditions.inject({}) do |h, condition|
|
72
|
+
element_name = "platformCommon:#{condition[:field]}"
|
73
|
+
|
74
|
+
case condition[:field]
|
75
|
+
when 'recType'
|
76
|
+
# TODO this seems a bit brittle, look into a way to handle this better
|
77
|
+
h[element_name] = {
|
78
|
+
:@internalId => condition[:value].internal_id
|
79
|
+
}
|
80
|
+
when 'customFieldList'
|
81
|
+
# === START CUSTOM FIELD
|
82
|
+
|
83
|
+
# there isn't a clean way to do lists of the same element
|
84
|
+
# Gyoku doesn't seem support the nice :@attribute and :content! syntax for lists of elements of the same name
|
85
|
+
# https://github.com/savonrb/gyoku/issues/18#issuecomment-17825848
|
86
|
+
|
87
|
+
# TODO with the latest version of savon we can easily improve the code here, should be rewritten with new attribute syntax
|
88
|
+
|
89
|
+
custom_field_list = condition[:value].map do |h|
|
90
|
+
if h[:value].is_a?(Array) && h[:value].first.respond_to?(:to_record)
|
91
|
+
{
|
92
|
+
"platformCore:searchValue" => h[:value].map(&:to_record),
|
93
|
+
:attributes! => {
|
94
|
+
'platformCore:searchValue' => {
|
95
|
+
'internalId' => h[:value].map(&:internal_id)
|
96
|
+
}
|
97
|
+
}
|
98
|
+
}
|
99
|
+
elsif h[:value].respond_to?(:to_record)
|
100
|
+
{
|
101
|
+
"platformCore:searchValue" => {
|
102
|
+
:content! => h[:value].to_record,
|
103
|
+
:@internalId => h[:value].internal_id
|
104
|
+
}
|
105
|
+
}
|
106
|
+
else
|
107
|
+
{ "platformCore:searchValue" => h[:value] }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
h[element_name] = {
|
112
|
+
'platformCore:customField' => custom_field_list,
|
113
|
+
:attributes! => {
|
114
|
+
'platformCore:customField' => {
|
115
|
+
'internalId' => condition[:value].map { |h| h[:field] },
|
116
|
+
'operator' => condition[:value].map { |h| h[:operator] },
|
117
|
+
'xsi:type' => condition[:value].map { |h| "platformCore:#{h[:type]}" }
|
118
|
+
}
|
119
|
+
}
|
69
120
|
}
|
70
|
-
|
121
|
+
|
122
|
+
# === END CUSTOM FIELD
|
123
|
+
else
|
124
|
+
if condition[:value].is_a?(Array) && condition[:value].first.respond_to?(:to_record)
|
125
|
+
# TODO need to update to the latest savon so we don't need to duplicate the same workaround above again
|
126
|
+
# TODO it's possible that this might break, not sure if platformCore:SearchMultiSelectField is the right type in every situation
|
127
|
+
|
128
|
+
h[element_name] = {
|
129
|
+
'@operator' => condition[:operator],
|
130
|
+
'@xsi:type' => 'platformCore:SearchMultiSelectField',
|
131
|
+
"platformCore:searchValue" => {
|
132
|
+
:content! => condition[:value].map(&:to_record),
|
133
|
+
'@internalId' => condition[:value].map(&:internal_id),
|
134
|
+
'@xsi:type' => 'platformCore:RecordRef',
|
135
|
+
'@type' => 'account'
|
136
|
+
}
|
137
|
+
}
|
138
|
+
elsif condition[:value].is_a?(Array) && condition[:type] == 'SearchDateField'
|
139
|
+
# date ranges are handled via searchValue (start range) and searchValue2 (end range)
|
140
|
+
|
141
|
+
h[element_name] = {
|
142
|
+
'@operator' => condition[:operator],
|
143
|
+
"platformCore:searchValue" => condition[:value].first.to_s,
|
144
|
+
"platformCore:searchValue2" => condition[:value].last.to_s
|
145
|
+
}
|
146
|
+
else
|
147
|
+
h[element_name] = {
|
148
|
+
:content! => { "platformCore:searchValue" => condition[:value] },
|
149
|
+
}
|
150
|
+
|
151
|
+
h[element_name][:@operator] = condition[:operator] if condition[:operator]
|
152
|
+
end
|
153
|
+
end
|
71
154
|
|
72
155
|
h
|
73
156
|
end
|
74
157
|
end
|
75
158
|
|
76
|
-
|
77
|
-
|
78
|
-
|
159
|
+
# TODO this needs to be DRYed up a bit
|
160
|
+
|
161
|
+
if saved_search_id
|
162
|
+
{
|
163
|
+
'searchRecord' => {
|
164
|
+
'@savedSearchId' => saved_search_id,
|
165
|
+
'@xsi:type' => "#{namespace}:#{class_name}SearchAdvanced",
|
166
|
+
:content! => {
|
167
|
+
"#{namespace}:criteria" => criteria_structure
|
168
|
+
# TODO need to optionally support columns here
|
169
|
+
}
|
170
|
+
}
|
171
|
+
}
|
172
|
+
elsif !columns_structure.empty?
|
173
|
+
{
|
174
|
+
'searchRecord' => {
|
175
|
+
'@xsi:type' => "#{namespace}:#{class_name}SearchAdvanced",
|
176
|
+
:content! => {
|
177
|
+
"#{namespace}:criteria" => criteria_structure,
|
178
|
+
"#{namespace}:columns" => columns_structure
|
179
|
+
}
|
180
|
+
}
|
181
|
+
}
|
182
|
+
else
|
183
|
+
{
|
79
184
|
'searchRecord' => {
|
80
|
-
|
81
|
-
|
185
|
+
:content! => criteria_structure,
|
186
|
+
'@xsi:type' => "#{namespace}:#{class_name}Search"
|
187
|
+
}
|
82
188
|
}
|
83
|
-
|
189
|
+
end
|
84
190
|
end
|
85
191
|
|
86
192
|
def response_header
|
@@ -96,13 +202,22 @@ module NetSuite
|
|
96
202
|
end
|
97
203
|
|
98
204
|
def search_result
|
99
|
-
@search_result = @response.body
|
205
|
+
@search_result = if @response.body.has_key?(:search_more_with_id_response)
|
206
|
+
@response.body[:search_more_with_id_response]
|
207
|
+
else
|
208
|
+
@response.body[:search_response]
|
209
|
+
end[:search_result]
|
100
210
|
end
|
101
211
|
|
102
212
|
def success?
|
103
213
|
@success ||= search_result[:status][:@is_success] == 'true'
|
104
214
|
end
|
105
215
|
|
216
|
+
protected
|
217
|
+
def method_name
|
218
|
+
|
219
|
+
end
|
220
|
+
|
106
221
|
module Support
|
107
222
|
def self.included(base)
|
108
223
|
base.extend(ClassMethods)
|
@@ -9,17 +9,19 @@ module NetSuite
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def request
|
12
|
+
api_version = NetSuite::Configuration.api_version
|
13
|
+
|
12
14
|
NetSuite::Configuration.connection(
|
13
15
|
namespaces: {
|
14
|
-
'xmlns:platformMsgs' => "urn:messages_#{
|
15
|
-
'xmlns:platformCore' => "urn:core_#{
|
16
|
-
'xmlns:listRel' => "urn:relationships_#{
|
17
|
-
'xmlns:tranSales' => "urn:sales_#{
|
18
|
-
'xmlns:platformCommon' => "urn:common_#{
|
19
|
-
'xmlns:listAcct' => "urn:accounting_#{
|
20
|
-
'xmlns:actSched' => "urn:scheduling_#{
|
21
|
-
'xmlns:tranCust' => "urn:customers_#{
|
22
|
-
'xmlns:setupCustom' => "urn:customization_#{
|
16
|
+
'xmlns:platformMsgs' => "urn:messages_#{api_version}.platform.webservices.netsuite.com",
|
17
|
+
'xmlns:platformCore' => "urn:core_#{api_version}.platform.webservices.netsuite.com",
|
18
|
+
'xmlns:listRel' => "urn:relationships_#{api_version}.lists.webservices.netsuite.com",
|
19
|
+
'xmlns:tranSales' => "urn:sales_#{api_version}.transactions.webservices.netsuite.com",
|
20
|
+
'xmlns:platformCommon' => "urn:common_#{api_version}.platform.webservices.netsuite.com",
|
21
|
+
'xmlns:listAcct' => "urn:accounting_#{api_version}.lists.webservices.netsuite.com",
|
22
|
+
'xmlns:actSched' => "urn:scheduling_#{api_version}.activities.webservices.netsuite.com",
|
23
|
+
'xmlns:tranCust' => "urn:customers_#{api_version}.transactions.webservices.netsuite.com",
|
24
|
+
'xmlns:setupCustom' => "urn:customization_#{api_version}.setup.webservices.netsuite.com",
|
23
25
|
},
|
24
26
|
).call :update, :message => request_body
|
25
27
|
end
|
@@ -31,20 +33,18 @@ module NetSuite
|
|
31
33
|
# </platformMsgs:update>
|
32
34
|
def request_body
|
33
35
|
hash = {
|
34
|
-
'platformMsgs:record' =>
|
35
|
-
|
36
|
-
'
|
37
|
-
'xsi:type' => updated_record.record_type
|
38
|
-
}
|
36
|
+
'platformMsgs:record' => {
|
37
|
+
:content! => updated_record.to_record,
|
38
|
+
'@xsi:type' => updated_record.record_type
|
39
39
|
}
|
40
40
|
}
|
41
41
|
|
42
42
|
if updated_record.respond_to?(:internal_id) && updated_record.internal_id
|
43
|
-
hash[
|
43
|
+
hash['platformMsgs:record']['@platformMsgs:internalId'] = updated_record.internal_id
|
44
44
|
end
|
45
45
|
|
46
46
|
if updated_record.respond_to?(:external_id) && updated_record.external_id
|
47
|
-
hash[
|
47
|
+
hash['platformMsgs:record']['@platformMsgs:externalId'] = updated_record.external_id
|
48
48
|
end
|
49
49
|
|
50
50
|
hash
|
@@ -12,12 +12,13 @@ module NetSuite
|
|
12
12
|
|
13
13
|
def connection(params = {})
|
14
14
|
Savon.client({
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
wsdl: wsdl,
|
16
|
+
read_timeout: read_timeout,
|
17
|
+
namespaces: namespaces,
|
18
|
+
soap_header: auth_header,
|
19
|
+
pretty_print_xml: true,
|
20
|
+
logger: logger
|
21
|
+
# open_timeout: ???
|
21
22
|
}.merge(params))
|
22
23
|
end
|
23
24
|
|
@@ -70,23 +71,36 @@ module NetSuite
|
|
70
71
|
'platformCore:email' => email,
|
71
72
|
'platformCore:password' => password,
|
72
73
|
'platformCore:account' => account.to_s,
|
73
|
-
'platformCore:role' => role
|
74
|
-
:attributes! => {
|
75
|
-
'platformCore:role' => role.attributes!
|
76
|
-
}
|
74
|
+
'platformCore:role' => { :'@type' => 'role', :@internalId => role }
|
77
75
|
}
|
78
76
|
}
|
79
77
|
end
|
80
|
-
|
78
|
+
|
79
|
+
def namespaces
|
80
|
+
{
|
81
|
+
'xmlns:platformMsgs' => "urn:messages_#{api_version}.platform.webservices.netsuite.com",
|
82
|
+
'xmlns:platformCore' => "urn:core_#{api_version}.platform.webservices.netsuite.com",
|
83
|
+
'xmlns:platformCommon' => "urn:common_#{api_version}.platform.webservices.netsuite.com",
|
84
|
+
'xmlns:listRel' => "urn:relationships_#{api_version}.lists.webservices.netsuite.com",
|
85
|
+
'xmlns:tranSales' => "urn:sales_#{api_version}.transactions.webservices.netsuite.com",
|
86
|
+
'xmlns:actSched' => "urn:scheduling_#{api_version}.activities.webservices.netsuite.com",
|
87
|
+
'xmlns:setupCustom' => "urn:customization_#{api_version}.setup.webservices.netsuite.com",
|
88
|
+
'xmlns:listAcct' => "urn:accounting_#{api_version}.lists.webservices.netsuite.com",
|
89
|
+
'xmlns:tranCust' => "urn:customers_#{api_version}.transactions.webservices.netsuite.com",
|
90
|
+
'xmlns:listSupport' => "urn:support_#{api_version}.lists.webservices.netsuite.com",
|
91
|
+
'xmlns:tranGeneral' => "urn:general_#{api_version}.transactions.webservices.netsuite.com",
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
81
95
|
def role=(role)
|
82
|
-
attributes[:role] =
|
96
|
+
attributes[:role] = role
|
83
97
|
end
|
84
|
-
|
98
|
+
|
85
99
|
def role(role = nil)
|
86
100
|
if role
|
87
101
|
self.role = role
|
88
|
-
else
|
89
|
-
attributes[:role] ||=
|
102
|
+
else
|
103
|
+
attributes[:role] ||= '3'
|
90
104
|
end
|
91
105
|
end
|
92
106
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# TODO needs spec
|
2
|
+
|
3
|
+
module NetSuite
|
4
|
+
module Records
|
5
|
+
class BaseRefList
|
6
|
+
include Support::Fields
|
7
|
+
include Support::Actions
|
8
|
+
include Namespaces::PlatformCore
|
9
|
+
|
10
|
+
actions :get_select_value
|
11
|
+
|
12
|
+
fields :base_ref
|
13
|
+
|
14
|
+
def initialize(attrs = {})
|
15
|
+
initialize_from_attributes_hash(attrs)
|
16
|
+
end
|
17
|
+
|
18
|
+
def base_ref=(refs)
|
19
|
+
case refs
|
20
|
+
when Hash
|
21
|
+
self.base_ref << RecordRef.new(refs)
|
22
|
+
when Array
|
23
|
+
refs.each { |ref| self.base_ref << RecordRef.new(ref) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def base_ref
|
28
|
+
@base_ref ||= []
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -4,7 +4,8 @@ module NetSuite
|
|
4
4
|
include Support::Fields
|
5
5
|
include Support::Records
|
6
6
|
|
7
|
-
attr_reader :internal_id
|
7
|
+
attr_reader :internal_id
|
8
|
+
attr_accessor :type
|
8
9
|
|
9
10
|
def initialize(attributes = {})
|
10
11
|
@internal_id = attributes.delete(:internal_id) || attributes.delete(:@internal_id)
|
@@ -20,39 +20,89 @@ module NetSuite
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def method_missing(sym, *args, &block)
|
23
|
-
|
23
|
+
# read custom field if already set
|
24
|
+
if @custom_fields_assoc.include?(sym)
|
25
|
+
return @custom_fields_assoc[sym]
|
26
|
+
end
|
27
|
+
|
28
|
+
# write custom field
|
29
|
+
if sym.to_s.end_with?('=')
|
30
|
+
return create_custom_field(sym.to_s[0..-2], args.first)
|
31
|
+
end
|
32
|
+
|
24
33
|
super(sym, *args, &block)
|
25
34
|
end
|
26
35
|
|
27
36
|
def respond_to?(sym, include_private = false)
|
28
|
-
return true if @custom_fields_assoc.include?
|
37
|
+
return true if @custom_fields_assoc.include?(sym)
|
29
38
|
super
|
30
39
|
end
|
31
40
|
|
32
41
|
def to_record
|
33
|
-
# TODO this is the best way I could find to handle this, there *has* to be a better way
|
34
|
-
# http://stackoverflow.com/questions/7001957/savon-array-of-xml-tags
|
35
|
-
|
36
42
|
{
|
37
|
-
"#{record_namespace}:customField" => custom_fields.map
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
43
|
+
"#{record_namespace}:customField" => custom_fields.map do |custom_field|
|
44
|
+
if custom_field.value.respond_to?(:to_record)
|
45
|
+
custom_field_value = custom_field.value.to_record
|
46
|
+
else
|
47
|
+
custom_field_value = custom_field.value.to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
{
|
51
|
+
"platformCore:value" => custom_field_value,
|
52
|
+
'@internalId' => custom_field.internal_id,
|
53
|
+
'@xsi:type' => custom_field.type
|
42
54
|
}
|
43
|
-
|
55
|
+
end
|
44
56
|
}
|
45
57
|
end
|
46
58
|
|
47
59
|
private
|
48
60
|
def extract_custom_field(custom_field_data)
|
49
|
-
# TODO this
|
61
|
+
# TODO this seems brittle, but might sufficient, watch out for this if something breaks
|
50
62
|
if custom_field_data[:"@xsi:type"] == "platformCore:SelectCustomFieldRef"
|
51
63
|
custom_field_data[:value] = CustomRecordRef.new(custom_field_data.delete(:value))
|
52
64
|
end
|
53
65
|
|
54
66
|
custom_fields << CustomField.new(custom_field_data)
|
55
67
|
end
|
68
|
+
|
69
|
+
def create_custom_field(internal_id, field_value)
|
70
|
+
# all custom fields need types; infer type based on class sniffing
|
71
|
+
field_type = case
|
72
|
+
when field_value.is_a?(Hash)
|
73
|
+
'SelectCustomFieldRef'
|
74
|
+
when field_value.is_a?(DateTime),
|
75
|
+
field_value.is_a?(Time),
|
76
|
+
field_value.is_a?(Date)
|
77
|
+
'DateCustomFieldRef'
|
78
|
+
when field_value.is_a?(FalseClass),
|
79
|
+
field_value.is_a?(TrueClass)
|
80
|
+
'BooleanCustomFieldRef'
|
81
|
+
else
|
82
|
+
'StringCustomFieldRef'
|
83
|
+
end
|
84
|
+
|
85
|
+
# TODO seems like DateTime doesn't need the iso8601 call
|
86
|
+
# not sure if this is specific to my env though
|
87
|
+
|
88
|
+
custom_field_value = case
|
89
|
+
when field_value.is_a?(Hash)
|
90
|
+
CustomRecordRef.new(field_value)
|
91
|
+
when field_value.is_a?(Time)
|
92
|
+
field_value.iso8601
|
93
|
+
else
|
94
|
+
field_value
|
95
|
+
end
|
96
|
+
|
97
|
+
custom_field = CustomField.new(
|
98
|
+
internal_id: internal_id,
|
99
|
+
value: custom_field_value,
|
100
|
+
type: "#{record_namespace}:#{field_type}"
|
101
|
+
)
|
102
|
+
|
103
|
+
custom_fields << custom_field
|
104
|
+
@custom_fields_assoc[internal_id.to_sym] = custom_field
|
105
|
+
end
|
56
106
|
end
|
57
107
|
end
|
58
108
|
end
|