netsuite 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|