netsuite_rails 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/.gitignore +3 -0
- data/.travis.yml +3 -0
- data/Gemfile +17 -7
- data/README.md +9 -4
- data/lib/netsuite_rails/configuration.rb +3 -1
- data/lib/netsuite_rails/list_sync/poll_manager.rb +30 -0
- data/lib/netsuite_rails/list_sync.rb +2 -2
- data/lib/netsuite_rails/netsuite_rails.rb +13 -3
- data/lib/netsuite_rails/poll_timestamp.rb +5 -0
- data/lib/netsuite_rails/{poll_manager.rb → poll_trigger.rb} +18 -3
- data/lib/netsuite_rails/record_sync/poll_manager.rb +186 -0
- data/lib/netsuite_rails/record_sync/pull_manager.rb +10 -137
- data/lib/netsuite_rails/record_sync/push_manager.rb +59 -21
- data/lib/netsuite_rails/record_sync.rb +142 -140
- data/lib/netsuite_rails/spec/spec_helper.rb +34 -6
- data/lib/netsuite_rails/sync_trigger.rb +80 -75
- data/lib/netsuite_rails/tasks/netsuite.rb +26 -30
- data/lib/netsuite_rails/url_helper.rb +12 -3
- data/netsuite_rails.gemspec +3 -3
- data/spec/models/poll_manager_spec.rb +45 -0
- data/spec/models/poll_trigger_spec.rb +26 -0
- data/spec/models/record_sync/push_manager_spec.rb +0 -0
- data/spec/models/spec_helper_spec.rb +29 -0
- data/spec/models/sync_trigger_spec.rb +62 -0
- data/spec/models/url_helper_spec.rb +23 -0
- data/spec/spec_helper.rb +17 -1
- data/spec/support/config/database.yml +11 -0
- data/spec/support/dynamic_models/class_builder.rb +48 -0
- data/spec/support/dynamic_models/model_builder.rb +83 -0
- data/spec/support/example_models.rb +31 -0
- data/spec/support/netsuite_rails.rb +1 -0
- data/spec/support/test_application.rb +55 -0
- metadata +36 -10
- data/lib/netsuite_rails/list_sync/pull_manager.rb +0 -33
@@ -4,18 +4,27 @@ module NetSuiteRails
|
|
4
4
|
class PushManager
|
5
5
|
class << self
|
6
6
|
|
7
|
-
def push(local_record, opts)
|
7
|
+
def push(local_record, opts = {})
|
8
8
|
# TODO check to see if anything is changed before moving forward
|
9
9
|
# if changes_keys.blank? && local_record.netsuite_manual_fields
|
10
10
|
|
11
|
-
|
11
|
+
if opts[:modified_fields]
|
12
|
+
# if Array, we need to convert info fields hash based on the record definition
|
13
|
+
if opts[:modified_fields].is_a?(Array)
|
14
|
+
opts[:modified_fields] = all_netsuite_fields(local_record).select { |k,v| opts[:modified_fields].include?(k) }
|
15
|
+
end
|
16
|
+
else
|
17
|
+
opts[:modified_fields] = modified_local_fields(local_record)
|
18
|
+
end
|
19
|
+
|
20
|
+
netsuite_record = build_netsuite_record(local_record, opts)
|
12
21
|
|
13
22
|
local_record.netsuite_execute_callbacks(local_record.class.before_netsuite_push, netsuite_record)
|
14
23
|
|
15
24
|
if !local_record.new_netsuite_record?
|
16
|
-
push_update(local_record, netsuite_record)
|
25
|
+
push_update(local_record, netsuite_record, opts)
|
17
26
|
else
|
18
|
-
push_add(local_record, netsuite_record)
|
27
|
+
push_add(local_record, netsuite_record, opts)
|
19
28
|
end
|
20
29
|
|
21
30
|
# :aggressive is for custom fields which are based on input – need pull updated values after
|
@@ -30,7 +39,7 @@ module NetSuiteRails
|
|
30
39
|
true
|
31
40
|
end
|
32
41
|
|
33
|
-
def push_add(local_record, netsuite_record)
|
42
|
+
def push_add(local_record, netsuite_record, opts = {})
|
34
43
|
if netsuite_record.add
|
35
44
|
# update_column to avoid triggering another save
|
36
45
|
local_record.update_column(:netsuite_id, netsuite_record.internal_id)
|
@@ -40,17 +49,17 @@ module NetSuiteRails
|
|
40
49
|
end
|
41
50
|
end
|
42
51
|
|
43
|
-
def push_update(local_record, netsuite_record)
|
52
|
+
def push_update(local_record, netsuite_record, opts = {})
|
44
53
|
# build change hash to limit the number of fields pushed to NS on change
|
45
54
|
# NS could have logic which could change field functionality depending on
|
46
55
|
# input data; it's safest to limit the number of field changes pushed to NS
|
47
56
|
|
48
57
|
custom_field_list = local_record.netsuite_field_map[:custom_field_list] || {}
|
49
|
-
|
58
|
+
modified_fields_list = opts[:modified_fields]
|
50
59
|
|
51
60
|
update_list = {}
|
52
61
|
|
53
|
-
|
62
|
+
modified_fields_list.each do |local_field, netsuite_field|
|
54
63
|
if custom_field_list.keys.include?(local_field)
|
55
64
|
# if custom field has changed, mark and copy over customFieldList later
|
56
65
|
update_list[:custom_field_list] = true
|
@@ -87,15 +96,21 @@ module NetSuiteRails
|
|
87
96
|
end
|
88
97
|
end
|
89
98
|
|
90
|
-
def build_netsuite_record(local_record)
|
99
|
+
def build_netsuite_record(local_record, opts = {})
|
91
100
|
netsuite_record = build_netsuite_record_reference(local_record)
|
92
101
|
|
93
102
|
# TODO need to normalize datetime fields
|
94
103
|
|
95
|
-
all_field_list =
|
104
|
+
all_field_list = opts[:modified_fields]
|
96
105
|
custom_field_list = local_record.netsuite_field_map[:custom_field_list] || {}
|
97
106
|
field_hints = local_record.netsuite_field_hints
|
98
107
|
|
108
|
+
reflections = if NetSuiteRails.rails4?
|
109
|
+
local_record.class.reflections
|
110
|
+
else
|
111
|
+
local_record.reflections
|
112
|
+
end
|
113
|
+
|
99
114
|
all_field_list.each do |local_field, netsuite_field|
|
100
115
|
# allow Procs as field mapping in the record definition for custom mapping
|
101
116
|
if netsuite_field.is_a?(Proc)
|
@@ -105,7 +120,7 @@ module NetSuiteRails
|
|
105
120
|
|
106
121
|
# TODO pretty sure this will break if we are dealing with has_many
|
107
122
|
|
108
|
-
netsuite_field_value = if
|
123
|
+
netsuite_field_value = if reflections.has_key?(local_field)
|
109
124
|
if (remote_internal_id = local_record.send(local_field).try(:netsuite_id)).present?
|
110
125
|
{ internal_id: remote_internal_id }
|
111
126
|
else
|
@@ -145,20 +160,24 @@ module NetSuiteRails
|
|
145
160
|
netsuite_record
|
146
161
|
end
|
147
162
|
|
148
|
-
def
|
149
|
-
|
150
|
-
all_field_list = local_record.netsuite_field_map.except(:custom_field_list) || {}
|
151
|
-
|
152
|
-
all_field_list.merge!(custom_field_list)
|
163
|
+
def modified_local_fields(local_record)
|
164
|
+
synced_netsuite_fields = all_netsuite_fields(local_record)
|
153
165
|
|
154
166
|
changed_keys = changed_attributes(local_record)
|
155
167
|
|
156
168
|
# filter out unchanged keys when updating record
|
157
169
|
unless local_record.new_netsuite_record?
|
158
|
-
|
170
|
+
synced_netsuite_fields.select! { |k,v| changed_keys.include?(k) }
|
159
171
|
end
|
160
172
|
|
161
|
-
|
173
|
+
synced_netsuite_fields
|
174
|
+
end
|
175
|
+
|
176
|
+
def all_netsuite_fields(local_record)
|
177
|
+
custom_netsuite_field_list = local_record.netsuite_field_map[:custom_field_list] || {}
|
178
|
+
standard_netsuite_field_list = local_record.netsuite_field_map.except(:custom_field_list) || {}
|
179
|
+
|
180
|
+
custom_netsuite_field_list.merge(standard_netsuite_field_list)
|
162
181
|
end
|
163
182
|
|
164
183
|
def changed_attributes(local_record)
|
@@ -167,13 +186,32 @@ module NetSuiteRails
|
|
167
186
|
|
168
187
|
# TODO think about has_many / join table changes
|
169
188
|
|
170
|
-
|
171
|
-
|
189
|
+
reflections = if NetSuiteRails.rails4?
|
190
|
+
local_record.class.reflections
|
191
|
+
else
|
192
|
+
local_record.reflections
|
193
|
+
end
|
194
|
+
|
195
|
+
association_field_key_mapping = reflections.values.reject(&:collection?).inject({}) do |h, a|
|
196
|
+
begin
|
197
|
+
h[a.association_foreign_key.to_sym] = a.name
|
198
|
+
rescue Exception => e
|
199
|
+
# occurs when `has_one through:` exists on a record but `through` is not a valid reference
|
200
|
+
Rails.logger.error "NetSuite: error detecting foreign key #{a.name}"
|
201
|
+
end
|
202
|
+
|
172
203
|
h
|
173
204
|
end
|
174
205
|
|
206
|
+
changed_attributes_keys = local_record.changed_attributes.keys
|
207
|
+
|
208
|
+
# TODO documentation about serialized values
|
209
|
+
changed_attributes_keys += local_record.serialized_attributes.keys.map do |k|
|
210
|
+
local_record.send(k.to_sym).keys.map(&:to_s)
|
211
|
+
end.flatten
|
212
|
+
|
175
213
|
# convert relationship symbols from :object_id to :object
|
176
|
-
|
214
|
+
changed_attributes_keys.map do |k|
|
177
215
|
association_field_key_mapping[k.to_sym] || k.to_sym
|
178
216
|
end
|
179
217
|
end
|
@@ -2,72 +2,81 @@ module NetSuiteRails
|
|
2
2
|
module RecordSync
|
3
3
|
|
4
4
|
def self.included(klass)
|
5
|
+
klass.class_eval do
|
6
|
+
class_attribute :netsuite_settings
|
7
|
+
|
8
|
+
self.netsuite_settings = {
|
9
|
+
before_netsuite_push: [],
|
10
|
+
after_netsuite_push: [],
|
11
|
+
after_netsuite_pull: [],
|
12
|
+
|
13
|
+
netsuite_sync: :read,
|
14
|
+
netsuite_field_map: {},
|
15
|
+
netsuite_field_hints: {},
|
16
|
+
netsuite_record_class: nil,
|
17
|
+
}
|
18
|
+
|
19
|
+
cattr_accessor :netsuite_custom_record_type_id
|
20
|
+
cattr_accessor :netsuite_sync_options
|
21
|
+
end
|
22
|
+
|
5
23
|
klass.send(:extend, ClassMethods)
|
24
|
+
klass.send(:include, InstanceMethods)
|
6
25
|
|
7
26
|
SyncTrigger.attach(klass)
|
8
|
-
|
27
|
+
PollTrigger.attach(klass)
|
9
28
|
end
|
10
29
|
|
11
30
|
module ClassMethods
|
12
31
|
def netsuite_poll(opts = {})
|
13
|
-
RecordSync::
|
32
|
+
RecordSync::PollManager.poll(self, opts)
|
14
33
|
end
|
15
34
|
|
16
35
|
attr_accessor :netsuite_custom_record_type_id
|
17
36
|
attr_accessor :netsuite_sync_options
|
18
|
-
attr_accessor :netsuite_credentials
|
19
37
|
|
20
38
|
# TODO is there a better way to implement callback chains?
|
21
39
|
# https://github.com/rails/rails/blob/0c0f278ab20f3042cdb69604166e18a61f8605ad/activesupport/lib/active_support/callbacks.rb#L491
|
22
40
|
|
23
41
|
def before_netsuite_push(callback = nil, &block)
|
24
|
-
|
25
|
-
|
26
|
-
@before_netsuite_push
|
42
|
+
self.netsuite_settings[:before_netsuite_push] << (callback || block) if callback || block
|
43
|
+
self.netsuite_settings[:before_netsuite_push]
|
27
44
|
end
|
28
45
|
|
29
46
|
def after_netsuite_push(callback = nil, &block)
|
30
|
-
|
31
|
-
|
32
|
-
@after_netsuite_push
|
47
|
+
self.netsuite_settings[:after_netsuite_push] << (callback || block) if callback || block
|
48
|
+
self.netsuite_settings[:after_netsuite_push]
|
33
49
|
end
|
34
50
|
|
35
51
|
def after_netsuite_pull(callback = nil, &block)
|
36
|
-
|
37
|
-
|
38
|
-
@after_netsuite_pull
|
52
|
+
self.netsuite_settings[:after_netsuite_pull] << (callback || block) if callback || block
|
53
|
+
self.netsuite_settings[:after_netsuite_pull]
|
39
54
|
end
|
40
55
|
|
41
56
|
def netsuite_field_map(field_mapping = nil)
|
42
|
-
if field_mapping.nil?
|
43
|
-
|
44
|
-
else
|
45
|
-
@netsuite_field_map = field_mapping
|
57
|
+
if !field_mapping.nil?
|
58
|
+
self.netsuite_settings[:netsuite_field_map] = field_mapping
|
46
59
|
end
|
47
60
|
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
def netsuite_local_fields
|
52
|
-
@netsuite_field_map.except(:custom_field_list).keys + (@netsuite_field_map[:custom_field_list] || {}).keys
|
61
|
+
self.netsuite_settings[:netsuite_field_map]
|
53
62
|
end
|
54
63
|
|
55
64
|
def netsuite_field_hints(list = nil)
|
56
|
-
if list.nil?
|
57
|
-
|
58
|
-
else
|
59
|
-
@netsuite_field_hints = list
|
65
|
+
if !list.nil?
|
66
|
+
self.netsuite_settings[:netsuite_field_hints] = list
|
60
67
|
end
|
68
|
+
|
69
|
+
self.netsuite_settings[:netsuite_field_hints]
|
61
70
|
end
|
62
71
|
|
63
72
|
# TODO persist type for CustomRecordRef
|
64
73
|
def netsuite_record_class(record_class = nil, custom_record_type_id = nil)
|
65
|
-
if record_class.nil?
|
66
|
-
|
67
|
-
|
68
|
-
@netsuite_record_class = record_class
|
69
|
-
@netsuite_custom_record_type_id = custom_record_type_id
|
74
|
+
if !record_class.nil?
|
75
|
+
self.netsuite_settings[:netsuite_record_class] = record_class
|
76
|
+
self.netsuite_custom_record_type_id = custom_record_type_id
|
70
77
|
end
|
78
|
+
|
79
|
+
self.netsuite_settings[:netsuite_record_class]
|
71
80
|
end
|
72
81
|
|
73
82
|
# there is a model level of this method in order to be based on the model level record class
|
@@ -75,160 +84,153 @@ module NetSuiteRails
|
|
75
84
|
self.netsuite_record_class == NetSuite::Records::CustomRecord
|
76
85
|
end
|
77
86
|
|
78
|
-
# :
|
87
|
+
# :read, :aggressive (push & update on save), :write_only, :read_write
|
79
88
|
def netsuite_sync(flag = nil, opts = {})
|
80
|
-
if flag.nil?
|
81
|
-
|
82
|
-
|
83
|
-
else
|
84
|
-
@netsuite_sync = flag
|
85
|
-
@netsuite_sync_options = opts
|
89
|
+
if !flag.nil?
|
90
|
+
self.netsuite_sync_options = opts
|
91
|
+
self.netsuite_settings[:netsuite_sync] = flag
|
86
92
|
end
|
93
|
+
|
94
|
+
self.netsuite_settings[:netsuite_sync]
|
87
95
|
end
|
88
96
|
end
|
89
97
|
|
90
|
-
|
98
|
+
module InstanceMethods
|
99
|
+
attr_accessor :netsuite_manual_fields
|
91
100
|
|
92
|
-
|
101
|
+
# these methods are here for easy model override
|
93
102
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
def netsuite_sync
|
99
|
-
self.class.netsuite_sync
|
100
|
-
end
|
103
|
+
def netsuite_sync_options
|
104
|
+
self.class.netsuite_sync_options
|
105
|
+
end
|
101
106
|
|
102
|
-
|
103
|
-
|
104
|
-
|
107
|
+
def netsuite_sync
|
108
|
+
self.class.netsuite_sync
|
109
|
+
end
|
105
110
|
|
106
|
-
|
107
|
-
|
108
|
-
|
111
|
+
def netsuite_record_class
|
112
|
+
self.class.netsuite_record_class
|
113
|
+
end
|
109
114
|
|
110
|
-
|
111
|
-
|
112
|
-
|
115
|
+
def netsuite_field_map
|
116
|
+
self.class.netsuite_field_map
|
117
|
+
end
|
113
118
|
|
114
|
-
|
119
|
+
def netsuite_field_hints
|
120
|
+
self.class.netsuite_field_hints
|
121
|
+
end
|
115
122
|
|
116
|
-
|
117
|
-
@netsuite_pulling ||= false
|
118
|
-
end
|
123
|
+
# assumes netsuite_id field on activerecord
|
119
124
|
|
120
|
-
|
121
|
-
|
122
|
-
|
125
|
+
def netsuite_pulling?
|
126
|
+
@netsuite_pulling ||= false
|
127
|
+
end
|
123
128
|
|
124
|
-
|
125
|
-
|
126
|
-
|
129
|
+
def netsuite_pulled?
|
130
|
+
@netsuite_pulled ||= false
|
131
|
+
end
|
127
132
|
|
128
|
-
|
129
|
-
|
130
|
-
NetSuite::Records::CustomRecord.get(
|
131
|
-
internal_id: self.netsuite_id,
|
132
|
-
type_id: self.class.netsuite_custom_record_type_id
|
133
|
-
)
|
134
|
-
else
|
135
|
-
self.netsuite_record_class.get(self.netsuite_id)
|
133
|
+
def netsuite_pull
|
134
|
+
netsuite_extract_from_record(netsuite_pull_record)
|
136
135
|
end
|
137
|
-
end
|
138
136
|
|
139
|
-
|
140
|
-
|
141
|
-
|
137
|
+
def netsuite_pull_record
|
138
|
+
if netsuite_custom_record?
|
139
|
+
NetSuite::Records::CustomRecord.get(
|
140
|
+
internal_id: self.netsuite_id,
|
141
|
+
type_id: self.class.netsuite_custom_record_type_id
|
142
|
+
)
|
143
|
+
else
|
144
|
+
self.netsuite_record_class.get(self.netsuite_id)
|
145
|
+
end
|
146
|
+
end
|
142
147
|
|
143
|
-
|
144
|
-
|
148
|
+
def netsuite_push(opts = {})
|
149
|
+
NetSuiteRails::RecordSync::PushManager.push(self, opts)
|
150
|
+
end
|
145
151
|
|
146
|
-
|
152
|
+
def netsuite_extract_from_record(netsuite_record)
|
153
|
+
@netsuite_pulling = true
|
147
154
|
|
148
|
-
|
155
|
+
field_hints = self.netsuite_field_hints
|
149
156
|
|
150
|
-
|
151
|
-
all_field_list.merge!(custom_field_list)
|
157
|
+
custom_field_list = self.netsuite_field_map[:custom_field_list] || {}
|
152
158
|
|
153
|
-
|
159
|
+
all_field_list = self.netsuite_field_map.except(:custom_field_list) || {}
|
160
|
+
all_field_list.merge!(custom_field_list)
|
154
161
|
|
155
|
-
|
156
|
-
association_keys = self.reflections.values.reject(&:collection?).map(&:name)
|
162
|
+
# self.netsuite_normalize_datetimes(:pull)
|
157
163
|
|
158
|
-
|
159
|
-
|
164
|
+
# handle non-collection associations
|
165
|
+
association_keys = self.reflections.values.reject(&:collection?).map(&:name)
|
160
166
|
|
161
|
-
|
162
|
-
|
163
|
-
next
|
164
|
-
end
|
167
|
+
all_field_list.each do |local_field, netsuite_field|
|
168
|
+
is_custom_field = custom_field_list.keys.include?(local_field)
|
165
169
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
end
|
170
|
+
if netsuite_field.is_a?(Proc)
|
171
|
+
netsuite_field.call(self, netsuite_record, :pull)
|
172
|
+
next
|
173
|
+
end
|
171
174
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
175
|
+
field_value = if is_custom_field
|
176
|
+
netsuite_record.custom_field_list.send(netsuite_field).value rescue ""
|
177
|
+
else
|
178
|
+
netsuite_record.send(netsuite_field)
|
179
|
+
end
|
176
180
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
# TODO I believe this only handles a subset of all the possibly CustomField values
|
181
|
-
if field_value.present? && field_value.is_a?(Hash) && field_value.has_key?(:name)
|
182
|
-
field_value = field_value[:name]
|
181
|
+
if field_value.blank?
|
182
|
+
# TODO possibly nil out the local value?
|
183
|
+
next
|
183
184
|
end
|
184
185
|
|
185
|
-
if
|
186
|
-
field_value =
|
186
|
+
if association_keys.include?(local_field)
|
187
|
+
field_value = self.reflections[local_field].klass.where(netsuite_id: field_value.internal_id).first_or_initialize
|
188
|
+
elsif is_custom_field
|
189
|
+
field_value = NetSuiteRails::RecordSync::PullManager.extract_custom_field_value(field_value)
|
190
|
+
else
|
191
|
+
# then it's not a custom field
|
187
192
|
end
|
188
|
-
else
|
189
|
-
# then it's not a custom field
|
190
|
-
end
|
191
193
|
|
192
|
-
|
194
|
+
# TODO should we just check for nil? vs present?
|
193
195
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
196
|
+
# TODO should be moved to Transformations with a direction flag
|
197
|
+
if field_hints.has_key?(local_field) && field_value.present?
|
198
|
+
case field_hints[local_field]
|
199
|
+
when :datetime
|
200
|
+
field_value = field_value.change(offset: "00:00") - (Time.zone.utc_offset / 3600).hours + (8 + NetSuiteRails::Configuration.netsuite_instance_time_zone_offset).hours
|
201
|
+
end
|
199
202
|
end
|
200
|
-
end
|
201
203
|
|
202
|
-
|
203
|
-
|
204
|
+
self.send(:"#{local_field}=", field_value)
|
205
|
+
end
|
204
206
|
|
205
|
-
|
207
|
+
netsuite_execute_callbacks(self.class.after_netsuite_pull, netsuite_record)
|
206
208
|
|
207
|
-
|
208
|
-
|
209
|
+
@netsuite_pulling = false
|
210
|
+
@netsuite_pulled = true
|
211
|
+
end
|
209
212
|
|
210
|
-
# return netsuite record for debugging
|
211
|
-
netsuite_record
|
212
|
-
end
|
213
213
|
|
214
|
-
|
215
|
-
|
216
|
-
|
214
|
+
def new_netsuite_record?
|
215
|
+
self.netsuite_id.blank?
|
216
|
+
end
|
217
217
|
|
218
|
-
|
219
|
-
|
220
|
-
|
218
|
+
def netsuite_custom_record?
|
219
|
+
self.netsuite_record_class == NetSuite::Records::CustomRecord
|
220
|
+
end
|
221
221
|
|
222
|
-
|
222
|
+
# TODO this should be protected; it needs to be pushed down to the Push/Pull manager level
|
223
223
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
224
|
+
def netsuite_execute_callbacks(list, record)
|
225
|
+
list.each do |callback|
|
226
|
+
if callback.is_a?(Symbol)
|
227
|
+
self.send(callback, record)
|
228
|
+
else
|
229
|
+
instance_exec(record, &callback)
|
230
|
+
end
|
230
231
|
end
|
231
232
|
end
|
233
|
+
|
232
234
|
end
|
233
235
|
|
234
236
|
end
|
@@ -10,15 +10,26 @@ module NetSuiteRails::TestHelpers
|
|
10
10
|
if stamp.nil?
|
11
11
|
@netsuite_timestamp ||= (Time.now - (60 * 2)).to_datetime
|
12
12
|
else
|
13
|
-
@netsuite_timestamp
|
13
|
+
@netsuite_timestamp = stamp
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
def get_last_netsuite_object(record)
|
18
|
-
|
18
|
+
# TODO support passing custom record ref
|
19
|
+
|
20
|
+
if record.is_a?(Class)
|
21
|
+
record_class = record
|
22
|
+
is_custom_record = false
|
23
|
+
else
|
24
|
+
record_class = record.netsuite_record_class
|
25
|
+
is_custom_record = record.netsuite_custom_record?
|
26
|
+
end
|
27
|
+
|
28
|
+
search = record_class.search({
|
19
29
|
criteria: {
|
20
30
|
basic:
|
21
|
-
|
31
|
+
(
|
32
|
+
if is_custom_record
|
22
33
|
[
|
23
34
|
{
|
24
35
|
field: 'recType',
|
@@ -39,18 +50,35 @@ module NetSuiteRails::TestHelpers
|
|
39
50
|
value: netsuite_timestamp
|
40
51
|
}
|
41
52
|
]
|
53
|
+
end +
|
54
|
+
|
55
|
+
if record_class == NetSuite::Records::SalesOrder
|
56
|
+
[
|
57
|
+
{
|
58
|
+
field: 'type',
|
59
|
+
operator: 'anyOf',
|
60
|
+
value: [ '_salesOrder' ]
|
61
|
+
}
|
62
|
+
]
|
63
|
+
else
|
64
|
+
[]
|
42
65
|
end
|
66
|
+
)
|
43
67
|
}
|
44
68
|
})
|
45
69
|
|
46
|
-
if
|
70
|
+
if is_custom_record
|
47
71
|
NetSuite::Records::CustomRecord.get(
|
48
72
|
internal_id: search.results.first.internal_id.to_i,
|
49
73
|
type_id: record.class.netsuite_custom_record_type_id
|
50
74
|
)
|
51
75
|
else
|
52
|
-
|
76
|
+
record_class.get(search.results.first.internal_id.to_i)
|
53
77
|
end
|
54
78
|
end
|
55
79
|
|
56
|
-
end
|
80
|
+
end
|
81
|
+
|
82
|
+
RSpec.configure do |config|
|
83
|
+
config.include NetSuiteRails::TestHelpers, type: :feature
|
84
|
+
end
|