netsuite_rails 0.2.2 → 0.3.1
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.
- checksums.yaml +15 -0
- data/Gemfile +4 -2
- data/README.md +186 -10
- data/circle.yml +3 -0
- data/lib/netsuite_rails/configuration.rb +7 -5
- data/lib/netsuite_rails/netsuite_rails.rb +24 -4
- data/lib/netsuite_rails/poll_trigger.rb +10 -9
- data/lib/netsuite_rails/record_sync/poll_manager.rb +23 -11
- data/lib/netsuite_rails/record_sync/pull_manager.rb +2 -0
- data/lib/netsuite_rails/record_sync/push_manager.rb +76 -38
- data/lib/netsuite_rails/record_sync.rb +28 -11
- data/lib/netsuite_rails/routines/company_contact_match.rb +98 -0
- data/lib/netsuite_rails/spec/disabler.rb +27 -0
- data/lib/netsuite_rails/spec/query_helpers.rb +93 -0
- data/lib/netsuite_rails/spec/spec_helper.rb +2 -79
- data/lib/netsuite_rails/sync_trigger.rb +40 -17
- data/lib/netsuite_rails/tasks/netsuite.rb +33 -4
- data/lib/netsuite_rails/transformations.rb +59 -19
- data/lib/netsuite_rails/url_helper.rb +45 -12
- data/netsuite_rails.gemspec +2 -2
- data/spec/models/configuration_spec.rb +11 -0
- data/spec/models/poll_manager_spec.rb +11 -2
- data/spec/models/poll_trigger_spec.rb +31 -11
- data/spec/models/record_sync/push_manager_spec.rb +51 -0
- data/spec/models/record_sync_spec.rb +16 -0
- data/spec/models/spec_helper_spec.rb +1 -2
- data/spec/models/transformations_spec.rb +62 -0
- data/spec/models/url_helper_spec.rb +20 -9
- data/spec/spec_helper.rb +19 -0
- data/spec/support/example_models.rb +33 -1
- metadata +19 -25
- data/.travis.yml +0 -3
- data/lib/netsuite_rails/netsuite_configure.rb +0 -14
- data/spec/support/netsuite_rails.rb +0 -1
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YTVkYzk2NDQyNzI5MGZjODkxOTM4MWFkYjExYTNlZWZkNGFjNjFmMQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NjdmOWIxMmE0MjNkYjE2MTU2ZDBmMzg4MDViNWZjMzdmZGIwZjgzOQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
OWJlMzFhMGJhNTM1NGZkMjRmMGMwNmU2ZmUzZTFhODQxMGQzYjZhMWNmMjE2
|
10
|
+
M2NlYjgwMTc0MWU4Y2FhMTBjNWVjZGM0NzU2NWIxNDY1NjMzYTE2N2ZlYWM4
|
11
|
+
N2NkOTY2ZTJhNzBiMDg2NjY0MTY4ZWYyYmMxNjk4NDc3NzQ5NjQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MDE5NmE5OWZmYjhjYzIyMGQ3ZmFmMzljZDc1ZTkwZDQ1MjRjYjUyZTk4MjAx
|
14
|
+
YjI2NTM1YmZmNWE5NjE0MGZhMzg1NmZlOTA5ZDA0NWU0OWU2ODgyNmM4NzMx
|
15
|
+
YzUxOTY5ODQ1MDQ0YWE3NTNkY2YwYjA1NmY4YThlNjUyNTgwMDc=
|
data/Gemfile
CHANGED
@@ -8,6 +8,8 @@ group :test do
|
|
8
8
|
# gem 'rack-test'
|
9
9
|
# gem 'webmock'
|
10
10
|
|
11
|
+
gem 'simplecov', :require => false
|
12
|
+
|
11
13
|
gem 'faker'
|
12
14
|
gem 'shoulda-matchers'
|
13
15
|
gem 'rails', '3.2.16'
|
@@ -15,7 +17,7 @@ group :test do
|
|
15
17
|
|
16
18
|
gem 'rspec-rails', '~> 3.1'
|
17
19
|
gem 'pry-nav'
|
18
|
-
|
20
|
+
|
19
21
|
gem 'rerun'
|
20
22
|
gem 'rb-fsevent'
|
21
|
-
end
|
23
|
+
end
|
data/README.md
CHANGED
@@ -1,10 +1,90 @@
|
|
1
|
-
[](https://circleci.com/gh/NetSweet/netsuite_rails)
|
2
|
+
[](http://opensuite-slackin.herokuapp.com)
|
2
3
|
|
3
4
|
# NetSuite Rails
|
4
5
|
|
5
|
-
|
6
|
+
**<span style="color: red">Note:</span>** Documentation is horrible: PRs welcome. Look at the code for details.
|
6
7
|
|
7
|
-
Build
|
8
|
+
Build Ruby on Rails applications that sync ActiveRecord (ActiveModel and plain old ruby objects too) in real-time to NetSuite. Here's an example:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
class Item < ActiveRecord::Base
|
12
|
+
include NetSuiteRails::RecordSync
|
13
|
+
|
14
|
+
# specify the NS record that your rails model maps to
|
15
|
+
netsuite_record_class NetSuite::Records::InventoryItem
|
16
|
+
|
17
|
+
netsuite_sync :read_write,
|
18
|
+
# specify the frequency that your app should poll NetSuite for updates
|
19
|
+
frequency: 1.day,
|
20
|
+
# it's possible to base syncing off of a saved search. Be sure that "Internal ID" is one of your search result columns
|
21
|
+
saved_search_id: 123,
|
22
|
+
# limit pushing to NetSuite based on conditional
|
23
|
+
if: -> { self.a_condition? },
|
24
|
+
# limit pulling from NetSuite based on conditional. This is only
|
25
|
+
# considered when handling a single pull
|
26
|
+
pull_if: -> { self.another_condition? },
|
27
|
+
|
28
|
+
# accepted values are :async and :sync. Default is :async
|
29
|
+
mode: :sync
|
30
|
+
|
31
|
+
|
32
|
+
# local => remote field mapping
|
33
|
+
netsuite_field_map({
|
34
|
+
:item_number => :item_id,
|
35
|
+
:name => :display_name,
|
36
|
+
|
37
|
+
# the corresponding NetSuite field must be manually specified in before_netsuite_push
|
38
|
+
:user => Proc.new do |local_rails_record, netsuite_record, sync_direction|
|
39
|
+
if direction == :pull
|
40
|
+
|
41
|
+
elsif direction == :push
|
42
|
+
|
43
|
+
end
|
44
|
+
end,
|
45
|
+
|
46
|
+
:custom_field_list => {
|
47
|
+
:a_local_field => :custrecord_remote_field
|
48
|
+
:a_special_local_field => Proc.new do |local, ns_record, direction|
|
49
|
+
if direction == :push
|
50
|
+
# if proc is used with a field mapping, the field must be specified in `netsuite_manual_fields`
|
51
|
+
ns_record.custom_field_list.custentity_special_long = 1
|
52
|
+
ns_record.custom_field_list.custentity_special_long.type = 'platformCore:LongCustomFieldRef'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
}
|
56
|
+
})
|
57
|
+
|
58
|
+
# sanitizes input from rails to ensure NS doesn't throw a fatal error
|
59
|
+
netsuite_field_hints({
|
60
|
+
:phone => :phone,
|
61
|
+
:email => :email
|
62
|
+
})
|
63
|
+
|
64
|
+
before_netsuite_push do |netsuite_record|
|
65
|
+
self.netsuite_manual_fields = [ :entity, :custom_field_list ]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
Your ruby model:
|
71
|
+
|
72
|
+
* Needs to have a `netsuite_id` and `netsuite_id=` method
|
73
|
+
* Does not need to be an `ActiveRecord` model. If you don't use ActiveRecord it is your responsibility
|
74
|
+
to trigger `Model#netsuite_push`.
|
75
|
+
|
76
|
+
Notes:
|
77
|
+
|
78
|
+
* If `sync_mode == :async` `model.save` will be run if a record is created referencing an existing NetSuite object: `model.create! netsuite_id: 123`
|
79
|
+
* If you are using `update`, a `update` call will not be run if no changed fields are detected. If you are manually using fields specify them with `netsuite_manual_fields`
|
80
|
+
|
81
|
+
## Using Upsert
|
82
|
+
|
83
|
+
TODO generating external ID tag
|
84
|
+
|
85
|
+
TODO configuring upsert
|
86
|
+
|
87
|
+
TODO add vs upsert consideration
|
8
88
|
|
9
89
|
## Installation
|
10
90
|
|
@@ -12,43 +92,121 @@ Build custom Ruby on Rails applications that sync to NetSuite.
|
|
12
92
|
gem 'netsuite_rails'
|
13
93
|
```
|
14
94
|
|
15
|
-
Install the database migration
|
95
|
+
Install the database migration to persist poll timestamps:
|
16
96
|
|
17
97
|
```bash
|
18
98
|
rails g netsuite_rails:install
|
19
99
|
```
|
20
100
|
|
21
|
-
|
101
|
+
This helps netsuite_rails to know when the last time your rails DB was synced with the NS.
|
102
|
+
|
103
|
+
## Date
|
104
|
+
|
105
|
+
|
106
|
+
## Time
|
107
|
+
|
108
|
+
"Time of Day" fields in NetSuite are especially tricky. To ensure that times don't shift when you push them to NetSuite here are some tips:
|
109
|
+
|
110
|
+
1. Take a look at the company time zone setup. This is in Setup
|
111
|
+
2. Ensure your WebService's Employee record has either:
|
112
|
+
* No time zone set
|
113
|
+
* The same time zone as the company
|
114
|
+
3. Ensure that the WebService's GUI preferences have the same time zone settings as the company. This effects how times are translated via SuiteTalk.
|
115
|
+
4. Set the `netsuite_instance_time_zone_offset` setting to your company's time zone
|
22
116
|
|
23
117
|
```ruby
|
24
118
|
# set your timezone offset
|
25
119
|
NetSuiteRails::Configuration.netsuite_instance_time_zone_offset(-6)
|
26
120
|
```
|
27
121
|
|
122
|
+
### Changing WebService User's TimeZone Preferences
|
123
|
+
|
124
|
+
It might take a couple hours for time zone changes to take effect. [From my experience](http://mikebian.co/netsuite-suitetalk-user-role-edits-are-delayed/), either the time zone changes have some delay associated with them or the time zone implementation is extremely buggy.
|
125
|
+
|
28
126
|
## Usage
|
29
127
|
|
30
|
-
|
128
|
+
### Syncing Options
|
129
|
+
|
130
|
+
```
|
131
|
+
netsuite_record_class NetSuite::Records::Customer
|
132
|
+
netsuite_record_class NetSuite::Records::CustomRecord, 123
|
133
|
+
|
134
|
+
netsuite_sync: :read
|
135
|
+
netsuite_sync: :read_write
|
136
|
+
# TODO not after_netsuite_push replacement for aggressive sync
|
137
|
+
|
138
|
+
netsuite_sync: :read, frequency: :never
|
139
|
+
netsuite_sync: :read, frequency: 5.minutes
|
140
|
+
netsuite_sync: :read, if: -> { self.condition_met? }
|
141
|
+
|
142
|
+
```
|
31
143
|
|
32
144
|
When using a proc in a NS mapping, you are responsible for setting local and remote values
|
33
145
|
|
146
|
+
The default sync frequency is [one day](https://github.com/NetSweet/netsuite_rails/blob/c453326a4190e68a2fd9d7690b2b1f2f105ec8b9/lib/netsuite_rails/poll_trigger.rb#L27).
|
147
|
+
|
34
148
|
for pushing tasks to DJ https://github.com/collectiveidea/delayed_job/wiki/Rake-Task-as-a-Delayed-Job
|
35
149
|
|
36
150
|
`:if` for controlling when syncing occurs
|
37
151
|
|
38
|
-
|
152
|
+
Easily disable/enable syncing via env vars:
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
NetSuiteRails.configure do
|
156
|
+
netsuite_pull_disabled ENV['NETSUITE_PULL_DISABLED'].present? && ENV['NETSUITE_PULL_DISABLED'] == "true"
|
157
|
+
netsuite_push_disabled ENV['NETSUITE_PUSH_DISABLED'].present? && ENV['NETSUITE_PUSH_DISABLED'] == "true"
|
158
|
+
|
159
|
+
if ENV['NETSUITE_DISABLE_SYNC'].present? && ENV['NETSUITE_DISABLE_SYNC'] == "true"
|
160
|
+
netsuite_pull_disabled true
|
161
|
+
netsuite_push_disabled true
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
```
|
166
|
+
|
167
|
+
### Hooks
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
# the netsuite record is passed a single argument to this block (or method reference)
|
171
|
+
# this provides the opportunity to set custom fields or run custom logic to prepare
|
172
|
+
# the record for the NetSuite envoirnment
|
173
|
+
before_netsuite_push
|
174
|
+
after_netsuite_push
|
175
|
+
|
176
|
+
# netsuite_pulling? is true when this callback is executed
|
177
|
+
after_netsuite_pull
|
178
|
+
```
|
39
179
|
|
40
|
-
### Syncing
|
180
|
+
### Rake Tasks for Syncing
|
41
181
|
|
42
182
|
```bash
|
183
|
+
# update & create local records modified in netsuite sync the last sync time
|
43
184
|
rake netsuite:sync
|
44
185
|
|
186
|
+
# pull all records in NetSuite and update/create local records
|
45
187
|
rake netsuite:fresh_sync
|
188
|
+
|
189
|
+
# only update records that have already been synced
|
190
|
+
rake netsuite:sync_local RECORD_MODELS=YourModel LIST_MODELS=YourListModel
|
46
191
|
```
|
47
192
|
|
48
193
|
Caveats:
|
49
194
|
|
50
195
|
* If you have date time fields, or custom fields that will trigger `changed_attributes` this might cause issues when pulling an existing record
|
51
|
-
* `changed_attributes` doesn't work well with store
|
196
|
+
* `changed_attributes` doesn't work well with `store`s
|
197
|
+
|
198
|
+
### Delayed Job
|
199
|
+
|
200
|
+
The more records that use netsuite_rails, the longer you'll need your job timeout to be:
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
# config/initializers/delayed_job.rb
|
204
|
+
Delayed::Worker.max_run_time = 80.minutes
|
205
|
+
```
|
206
|
+
|
207
|
+
## Non-AR Backed Model
|
208
|
+
|
209
|
+
Implement `changed_attributes` in your non-AR backed model
|
52
210
|
|
53
211
|
## Testing
|
54
212
|
|
@@ -57,6 +215,24 @@ Caveats:
|
|
57
215
|
require 'netsuite_rails/spec/spec_helper'
|
58
216
|
```
|
59
217
|
|
218
|
+
# Syncing Using Rake Tasks
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
# clockwork.rb
|
222
|
+
every(1.minutes, 'netsuite sync') {
|
223
|
+
# prevent multiple netsuite:sync DJ commands from being added; only one is needed in the queue at a time
|
224
|
+
unless Delayed::Job.where(failed_at: nil, locked_by: nil).detect { |j| j.payload_object.class == DelayedRake && j.payload_object.task == 'netsuite:sync'}
|
225
|
+
Delayed::Job.enqueue DelayedRake.new("netsuite:sync")
|
226
|
+
end
|
227
|
+
}
|
228
|
+
|
229
|
+
# schedule.rb
|
230
|
+
# DelayedRake: https://github.com/collectiveidea/delayed_job/wiki/Rake-Task-as-a-Delayed-Job
|
231
|
+
every 2.minutes do
|
232
|
+
runner 'Delayed::Job.enqueue(DelayedRake.new("netsuite:sync"),priority:1,run_at: Time.now);'
|
233
|
+
end
|
234
|
+
```
|
235
|
+
|
60
236
|
## Author
|
61
237
|
|
62
|
-
* Michael Bianco @iloveitaly
|
238
|
+
* Michael Bianco @iloveitaly
|
data/circle.yml
ADDED
@@ -14,7 +14,7 @@ module NetSuiteRails
|
|
14
14
|
|
15
15
|
def netsuite_sync_mode(mode = nil)
|
16
16
|
if mode.nil?
|
17
|
-
attributes[:sync_mode] ||= :
|
17
|
+
attributes[:sync_mode] ||= :async
|
18
18
|
else
|
19
19
|
attributes[:sync_mode] = mode
|
20
20
|
end
|
@@ -22,17 +22,19 @@ module NetSuiteRails
|
|
22
22
|
|
23
23
|
def netsuite_push_disabled(flag = nil)
|
24
24
|
if flag.nil?
|
25
|
-
attributes[:
|
25
|
+
attributes[:push_disabled] = false if attributes[:push_disabled].nil?
|
26
|
+
attributes[:push_disabled]
|
26
27
|
else
|
27
|
-
attributes[:
|
28
|
+
attributes[:push_disabled] = flag
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
31
32
|
def netsuite_pull_disabled(flag = nil)
|
32
33
|
if flag.nil?
|
33
|
-
attributes[:
|
34
|
+
attributes[:pull_disabled] = false if attributes[:pull_disabled].nil?
|
35
|
+
attributes[:pull_disabled]
|
34
36
|
else
|
35
|
-
attributes[:
|
37
|
+
attributes[:pull_disabled] = flag
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
@@ -14,6 +14,8 @@ require 'netsuite_rails/record_sync/poll_manager'
|
|
14
14
|
require 'netsuite_rails/record_sync/pull_manager'
|
15
15
|
require 'netsuite_rails/record_sync/push_manager'
|
16
16
|
|
17
|
+
require 'netsuite_rails/routines/company_contact_match'
|
18
|
+
|
17
19
|
require 'netsuite_rails/list_sync'
|
18
20
|
require 'netsuite_rails/list_sync/poll_manager'
|
19
21
|
|
@@ -23,14 +25,32 @@ module NetSuiteRails
|
|
23
25
|
Rails::VERSION::MAJOR >= 4
|
24
26
|
end
|
25
27
|
|
28
|
+
def self.configure_from_env(&block)
|
29
|
+
self.configure do
|
30
|
+
reset!
|
31
|
+
|
32
|
+
netsuite_pull_disabled ENV['NETSUITE_PULL_DISABLED'].present? && ENV['NETSUITE_PULL_DISABLED'] == "true"
|
33
|
+
netsuite_push_disabled ENV['NETSUITE_PUSH_DISABLED'].present? && ENV['NETSUITE_PUSH_DISABLED'] == "true"
|
34
|
+
|
35
|
+
if ENV['NETSUITE_DISABLE_SYNC'].present? && ENV['NETSUITE_DISABLE_SYNC'] == "true"
|
36
|
+
netsuite_pull_disabled true
|
37
|
+
netsuite_push_disabled true
|
38
|
+
end
|
39
|
+
|
40
|
+
polling_page_size if ENV['NETSUITE_POLLING_PAGE_SIZE'].present?
|
41
|
+
end
|
42
|
+
|
43
|
+
self.configure(&block) if block
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.configure(&block)
|
47
|
+
NetSuiteRails::Configuration.instance_eval(&block)
|
48
|
+
end
|
49
|
+
|
26
50
|
class Railtie < ::Rails::Railtie
|
27
51
|
rake_tasks do
|
28
52
|
load 'netsuite_rails/tasks/netsuite.rb'
|
29
53
|
end
|
30
|
-
|
31
|
-
config.before_configuration do
|
32
|
-
require 'netsuite_rails/netsuite_configure'
|
33
|
-
end
|
34
54
|
end
|
35
55
|
|
36
56
|
end
|
@@ -27,32 +27,33 @@ module NetSuiteRails
|
|
27
27
|
sync_frequency = klass.netsuite_sync_options[:frequency] || 1.day
|
28
28
|
|
29
29
|
if sync_frequency == :never
|
30
|
-
Rails.logger.info "Not syncing #{klass.to_s}"
|
30
|
+
Rails.logger.info "NetSuite: Not syncing #{klass.to_s}"
|
31
31
|
next
|
32
32
|
end
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
preference = PollTimestamp.for_class(klass)
|
34
|
+
last_class_poll = PollTimestamp.for_class(klass)
|
35
|
+
poll_execution_time = DateTime.now
|
37
36
|
|
38
37
|
# check if we've never synced before
|
39
|
-
if
|
38
|
+
if last_class_poll.new_record?
|
39
|
+
Rails.logger.info "NetSuite: Syncing #{klass} for the first time"
|
40
40
|
klass.netsuite_poll({ import_all: true }.merge(opts))
|
41
41
|
else
|
42
42
|
# TODO look into removing the conditional parsing; I don't think this is needed
|
43
|
-
last_poll_date =
|
43
|
+
last_poll_date = last_class_poll.value
|
44
44
|
last_poll_date = DateTime.parse(last_poll_date) unless last_poll_date.is_a?(DateTime)
|
45
45
|
|
46
46
|
if DateTime.now.to_i - last_poll_date.to_i > sync_frequency
|
47
|
-
Rails.logger.info "NetSuite:
|
47
|
+
Rails.logger.info "NetSuite: #{klass} is due to be synced, last checked #{last_poll_date}"
|
48
48
|
klass.netsuite_poll({ last_poll: last_poll_date }.merge(opts))
|
49
49
|
else
|
50
50
|
Rails.logger.info "NetSuite: Skipping #{klass} because of syncing frequency"
|
51
|
+
next
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
54
|
-
|
55
|
-
|
55
|
+
last_class_poll.value = poll_execution_time
|
56
|
+
last_class_poll.save!
|
56
57
|
end
|
57
58
|
end
|
58
59
|
|
@@ -19,7 +19,7 @@ module NetSuiteRails
|
|
19
19
|
end
|
20
20
|
|
21
21
|
unless netsuite_batch
|
22
|
-
|
22
|
+
raise "NetSuite: #{klass}. Error running NS search. No Netsuite batch found. Most likely a search timeout."
|
23
23
|
end
|
24
24
|
|
25
25
|
netsuite_batch.each do |netsuite_record|
|
@@ -35,12 +35,14 @@ module NetSuiteRails
|
|
35
35
|
}.merge(opts)
|
36
36
|
|
37
37
|
opts[:netsuite_record_class] ||= klass.netsuite_record_class
|
38
|
+
opts[:netsuite_custom_record_type_id] ||= klass.netsuite_custom_record_type_id if opts[:netsuite_record_class] == NetSuite::Records::CustomRecord
|
38
39
|
opts[:saved_search_id] ||= klass.netsuite_sync_options[:saved_search_id]
|
40
|
+
opts[:body_fields_only] ||= false
|
39
41
|
|
40
42
|
search = opts[:netsuite_record_class].search(
|
41
43
|
poll_criteria(klass, opts).merge({
|
42
44
|
preferences: {
|
43
|
-
body_fields_only:
|
45
|
+
body_fields_only: opts[:body_fields_only],
|
44
46
|
page_size: opts[:page_size]
|
45
47
|
}
|
46
48
|
})
|
@@ -48,7 +50,7 @@ module NetSuiteRails
|
|
48
50
|
|
49
51
|
# TODO more robust error reporting
|
50
52
|
unless search
|
51
|
-
raise
|
53
|
+
raise "NetSuite: #{klass}. Error running NS search. Most likely a search timeout."
|
52
54
|
end
|
53
55
|
|
54
56
|
process_search_results(klass, opts, search)
|
@@ -90,7 +92,7 @@ module NetSuiteRails
|
|
90
92
|
|
91
93
|
if opts[:netsuite_record_class] == NetSuite::Records::CustomRecord
|
92
94
|
opts[:netsuite_custom_record_type_id] ||= klass.netsuite_custom_record_type_id
|
93
|
-
|
95
|
+
|
94
96
|
criteria << {
|
95
97
|
field: 'recType',
|
96
98
|
operator: 'is',
|
@@ -116,14 +118,14 @@ module NetSuiteRails
|
|
116
118
|
full_record_data: -1,
|
117
119
|
}.merge(opts)
|
118
120
|
|
119
|
-
Rails.logger.info "NetSuite: Processing #{search.total_records} over #{search.total_pages} pages"
|
120
|
-
|
121
121
|
# TODO need to improve the conditional here to match the get_list call conditional belo
|
122
122
|
if opts[:import_all] && opts[:skip_existing]
|
123
123
|
synced_netsuite_list = klass.pluck(:netsuite_id)
|
124
124
|
end
|
125
|
-
|
125
|
+
|
126
126
|
search.results_in_batches do |batch|
|
127
|
+
Rails.logger.info "NetSuite: Syncing #{klass}. Current Page: #{search.current_page}. Processing #{search.total_records} over #{search.total_pages} pages."
|
128
|
+
|
127
129
|
# a saved search is processed as a advanced search; advanced search often does not allow you to retrieve
|
128
130
|
# all of the fields (ex: addressbooklist on customer) that a normal search does
|
129
131
|
# the only way to get those fields is to pull down the full record again using getAll
|
@@ -136,7 +138,16 @@ module NetSuiteRails
|
|
136
138
|
end
|
137
139
|
|
138
140
|
if filtered_netsuite_id_list.present?
|
139
|
-
|
141
|
+
Rails.logger.info "NetSuite: Syncing #{klass}. Running get_list for #{filtered_netsuite_id_list.length} records"
|
142
|
+
|
143
|
+
if opts[:netsuite_record_class] == NetSuite::Records::CustomRecord
|
144
|
+
NetSuite::Records::CustomRecord.get_list(
|
145
|
+
list: filtered_netsuite_id_list,
|
146
|
+
type_id: opts[:netsuite_custom_record_type_id]
|
147
|
+
)
|
148
|
+
else
|
149
|
+
opts[:netsuite_record_class].get_list(list: filtered_netsuite_id_list)
|
150
|
+
end
|
140
151
|
else
|
141
152
|
[]
|
142
153
|
end
|
@@ -164,7 +175,8 @@ module NetSuiteRails
|
|
164
175
|
end
|
165
176
|
|
166
177
|
def needs_get_list?(opts)
|
167
|
-
(opts[:saved_search_id].present? && opts[:full_record_data] != false) ||
|
178
|
+
(opts[:saved_search_id].present? && opts[:full_record_data] != false) ||
|
179
|
+
opts[:full_record_data] == true
|
168
180
|
end
|
169
181
|
|
170
182
|
# TODO this should remain in the pull manager
|
@@ -180,7 +192,7 @@ module NetSuiteRails
|
|
180
192
|
|
181
193
|
custom_field_value
|
182
194
|
end
|
183
|
-
|
195
|
+
|
184
196
|
end
|
185
197
|
end
|
186
|
-
end
|
198
|
+
end
|
@@ -3,6 +3,8 @@ module NetSuiteRails
|
|
3
3
|
module PullManager
|
4
4
|
extend self
|
5
5
|
|
6
|
+
# TODO pull relevant methods out of poll manager and into this class
|
7
|
+
|
6
8
|
def extract_custom_field_value(custom_field_value)
|
7
9
|
if custom_field_value.present? && custom_field_value.is_a?(Hash) && custom_field_value.has_key?(:name)
|
8
10
|
custom_field_value = custom_field_value[:name]
|