netsuite 0.5.8 → 0.5.9
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/.ruby-version +1 -0
- data/README.md +52 -12
- data/lib/netsuite/records/address.rb +2 -1
- data/lib/netsuite/records/cash_refund_item.rb +11 -2
- data/lib/netsuite/records/customer_deposit.rb +3 -2
- data/lib/netsuite/records/item_fulfillment.rb +6 -1
- data/lib/netsuite/records/sales_order_item.rb +1 -1
- data/lib/netsuite/utilities.rb +116 -2
- data/lib/netsuite/version.rb +1 -1
- data/spec/netsuite/records/address_spec.rb +1 -1
- metadata +20 -13
- checksums.yaml +0 -7
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.9.3-p550
|
data/README.md
CHANGED
@@ -178,13 +178,16 @@ search = NetSuite::Records::Customer.search({
|
|
178
178
|
`open https://system.netsuite.com/app/common/entity/custjob.nl?id=#{search.results.first.internal_id}`
|
179
179
|
|
180
180
|
# searching for custom records
|
181
|
-
NetSuite::Records::CustomRecord.search(
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
181
|
+
NetSuite::Records::CustomRecord.search(
|
182
|
+
basic: [
|
183
|
+
{
|
184
|
+
field: 'recType',
|
185
|
+
operator: 'is',
|
186
|
+
# custom record type
|
187
|
+
value: NetSuite::Records::CustomRecordRef.new(:internal_id => 10),
|
188
|
+
}
|
189
|
+
]
|
190
|
+
).results
|
188
191
|
|
189
192
|
# advanced search building on saved search
|
190
193
|
NetSuite::Records::Customer.search({
|
@@ -216,11 +219,11 @@ NetSuite::Records::Customer.search({
|
|
216
219
|
NetSuite::Records::CustomRecordRef.new(:internal_id => 2),
|
217
220
|
]
|
218
221
|
},
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
222
|
+
{
|
223
|
+
field: 'custbody_internetorder',
|
224
|
+
type: 'SearchBooleanCustomField',
|
225
|
+
value: true
|
226
|
+
}
|
224
227
|
]
|
225
228
|
}
|
226
229
|
]
|
@@ -316,6 +319,43 @@ NetSuite::Records::Transaction.search({
|
|
316
319
|
}
|
317
320
|
}).results
|
318
321
|
|
322
|
+
NetSuite::Records::ItemFulfillment.search({
|
323
|
+
criteria: {
|
324
|
+
basic: [
|
325
|
+
{
|
326
|
+
field: 'type',
|
327
|
+
operator: 'anyOf',
|
328
|
+
type: 'SearchEnumMultiSelectField',
|
329
|
+
value: ["_itemFulfillment"]
|
330
|
+
},
|
331
|
+
{
|
332
|
+
field: 'lastModifiedDate',
|
333
|
+
type: 'SearchDateField',
|
334
|
+
operator: 'within',
|
335
|
+
value: [
|
336
|
+
DateTime.now - 2.hours,
|
337
|
+
DateTime.now
|
338
|
+
]
|
339
|
+
}
|
340
|
+
],
|
341
|
+
createdFromJoin: [
|
342
|
+
{
|
343
|
+
field: 'type',
|
344
|
+
operator: 'anyOf',
|
345
|
+
value: [ '_salesOrder' ]
|
346
|
+
},
|
347
|
+
{
|
348
|
+
field: 'internalIdNumber',
|
349
|
+
operator: 'notEmpty'
|
350
|
+
}
|
351
|
+
]
|
352
|
+
},
|
353
|
+
preferences: {
|
354
|
+
pageSize: 1000,
|
355
|
+
bodyFieldsOnly: false
|
356
|
+
}
|
357
|
+
}).results
|
358
|
+
|
319
359
|
# basic search with pagination / SearchMorewithId
|
320
360
|
search = NetSuite::Records::Customer.search(
|
321
361
|
criteria: {
|
@@ -8,9 +8,10 @@ module NetSuite
|
|
8
8
|
# internalId is a bit strange on this record
|
9
9
|
# https://github.com/NetSweet/netsuite/wiki/Miscellaneous-Web-Services-Quirks#customer
|
10
10
|
|
11
|
-
fields :addr1, :addr2, :addressee, :addr_phone, :attention, :city, :
|
11
|
+
fields :addr1, :addr2, :addr3, :addressee, :addr_phone, :attention, :city, :internal_id, :override, :state, :zip
|
12
12
|
|
13
13
|
field :country, NetSuite::Support::Country
|
14
|
+
field :custom_field_list, CustomFieldList
|
14
15
|
|
15
16
|
read_only_fields :addr_text
|
16
17
|
|
@@ -6,14 +6,23 @@ module NetSuite
|
|
6
6
|
include Support::Records
|
7
7
|
include Namespaces::TranCust
|
8
8
|
|
9
|
-
|
9
|
+
fields :amount, :rate, :quantity
|
10
|
+
field :custom_field_list, CustomFieldList
|
10
11
|
|
11
|
-
record_refs :item, :klass
|
12
|
+
record_refs :item, :klass, :price
|
12
13
|
|
13
14
|
def initialize(attributes_or_record = {})
|
14
15
|
initialize_from_attributes_hash(attributes_or_record)
|
15
16
|
end
|
16
17
|
|
18
|
+
def to_record
|
19
|
+
rec = super
|
20
|
+
if rec["#{record_namespace}:customFieldList"]
|
21
|
+
rec["#{record_namespace}:customFieldList!"] = rec.delete("#{record_namespace}:customFieldList")
|
22
|
+
end
|
23
|
+
rec
|
24
|
+
end
|
25
|
+
|
17
26
|
end
|
18
27
|
end
|
19
28
|
end
|
@@ -14,11 +14,12 @@ module NetSuite
|
|
14
14
|
actions :get, :get_list, :initialize, :add, :delete, :update, :upsert
|
15
15
|
|
16
16
|
fields :created_date, :last_modified_date, :status, :payment, :tran_date, :exchange_rate, :undep_funds, :memo,
|
17
|
-
:check_num, :klass, :currency_name, :is_recurring_payment
|
17
|
+
:check_num, :klass, :currency_name, :is_recurring_payment, :charge_it
|
18
18
|
|
19
19
|
field :custom_field_list, CustomFieldList
|
20
20
|
|
21
|
-
record_refs :customer, :sales_order, :account, :department, :payment_method,
|
21
|
+
record_refs :customer, :sales_order, :account, :department, :payment_method,
|
22
|
+
:custom_form, :currency, :posting_period, :subsidiary
|
22
23
|
|
23
24
|
attr_reader :internal_id
|
24
25
|
attr_accessor :external_id
|
@@ -15,10 +15,15 @@ module NetSuite
|
|
15
15
|
|
16
16
|
read_only_fields :handling_cost
|
17
17
|
|
18
|
-
record_refs :custom_form, :entity, :created_from, :ship_carrier, :ship_method,
|
18
|
+
record_refs :custom_form, :entity, :created_from, :ship_carrier, :ship_method,
|
19
19
|
:ship_address_list, :klass, :ship_country
|
20
20
|
|
21
|
+
# NOTE API version < 2015_1 only
|
21
22
|
field :transaction_ship_address, ShipAddress
|
23
|
+
|
24
|
+
# NOTE API version >= 2015_1
|
25
|
+
field :shipping_address, Address
|
26
|
+
|
22
27
|
field :item_list, ItemFulfillmentItemList
|
23
28
|
field :package_list, ItemFulfillmentPackageList
|
24
29
|
field :custom_field_list, CustomFieldList
|
@@ -13,7 +13,7 @@ module NetSuite
|
|
13
13
|
:gift_cert_message, :gift_cert_number, :gift_cert_recipient_email, :gift_cert_recipient_name, :gross_amt, :is_taxable,
|
14
14
|
:line, :order_line, :po_currency, :quantity, :rate, :rev_rec_end_date, :rev_rec_start_date, :rev_rec_term_in_months,
|
15
15
|
:serial_numbers, :shipping_cost, :tax1_amt, :tax_rate1, :tax_rate2, :vsoe_allocation, :vsoe_amount, :vsoe_deferral,
|
16
|
-
:vsoe_delivered, :vsoe_permit_discount, :vsoe_price, :is_closed
|
16
|
+
:vsoe_delivered, :vsoe_permit_discount, :vsoe_price, :is_closed, :quantity_commited, :quantity_fulfilled
|
17
17
|
|
18
18
|
field :custom_field_list, CustomFieldList
|
19
19
|
|
data/lib/netsuite/utilities.rb
CHANGED
@@ -1,5 +1,119 @@
|
|
1
1
|
module NetSuite
|
2
2
|
module Utilities
|
3
|
+
extend self
|
4
|
+
|
5
|
+
# TODO need structured logger for various statements
|
6
|
+
|
7
|
+
def backoff(options = {})
|
8
|
+
count = 0
|
9
|
+
begin
|
10
|
+
count += 1
|
11
|
+
yield
|
12
|
+
rescue options[:exception] || Savon::SOAPFault => e
|
13
|
+
if !e.message.include?("Only one request may be made against a session at a time")
|
14
|
+
raise e
|
15
|
+
end
|
16
|
+
if count >= (options[:attempts] || 8)
|
17
|
+
raise e
|
18
|
+
end
|
19
|
+
# log.warn("concurrent request failure", sleep: count, attempt: count)
|
20
|
+
sleep(count)
|
21
|
+
retry
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def request_failed?(ns_object)
|
26
|
+
return false if ns_object.errors.nil? || ns_object.errors.empty?
|
27
|
+
|
28
|
+
warnings = ns_object.errors.select { |x| x.type == "WARN" }
|
29
|
+
errors = ns_object.errors.select { |x| x.type == "ERROR" }
|
30
|
+
|
31
|
+
# warnings.each do |warn|
|
32
|
+
# log.warn(warn.message, code: warn.code)
|
33
|
+
# end
|
34
|
+
|
35
|
+
return errors.size > 0
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_record(record_klass, id, opts = {})
|
39
|
+
opts[:external_id] ||= false
|
40
|
+
|
41
|
+
begin
|
42
|
+
# log.debug("get record", netsuite_record_type: record_klass.name, netsuite_record_id: id)
|
43
|
+
|
44
|
+
if opts[:external_id]
|
45
|
+
return backoff { record_klass.get(external_id: id) }
|
46
|
+
else
|
47
|
+
return backoff { record_klass.get(id) }
|
48
|
+
end
|
49
|
+
rescue ::NetSuite::RecordNotFound
|
50
|
+
# log.warn("record not found", ns_record_type: record_klass.name, ns_record_id: id)
|
51
|
+
return nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def find_record(record, names, opts = {})
|
56
|
+
field_name = opts[:field_name]
|
57
|
+
|
58
|
+
names = [ names ] if names.is_a?(String)
|
59
|
+
|
60
|
+
# FIXME: Records that have the same name but different types will break
|
61
|
+
# the cache
|
62
|
+
names.each do |name|
|
63
|
+
@netsuite_find_record_cache ||= {}
|
64
|
+
|
65
|
+
if @netsuite_find_record_cache.has_key?(name)
|
66
|
+
return @netsuite_find_record_cache[name]
|
67
|
+
end
|
68
|
+
|
69
|
+
# sniff for an email-like input; useful for employee/customer searches
|
70
|
+
if !field_name && /@.*\./ =~ name
|
71
|
+
field_name = 'email'
|
72
|
+
end
|
73
|
+
|
74
|
+
field_name ||= 'name'
|
75
|
+
|
76
|
+
# TODO remove backoff when it's built-in to search
|
77
|
+
search = backoff { record.search({
|
78
|
+
basic: [
|
79
|
+
{
|
80
|
+
field: field_name,
|
81
|
+
operator: 'contains',
|
82
|
+
value: name,
|
83
|
+
}
|
84
|
+
]
|
85
|
+
}) }
|
86
|
+
|
87
|
+
if search.results.first
|
88
|
+
return @netsuite_find_record_cache[name] = search.results.first
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
nil
|
93
|
+
end
|
94
|
+
|
95
|
+
def data_center_url(netsuite_account)
|
96
|
+
begin
|
97
|
+
data_center_call_response = NetSuite::Configuration.connection({}, {
|
98
|
+
email: '',
|
99
|
+
password: '',
|
100
|
+
account: ''
|
101
|
+
}).call(:get_data_center_urls, message: {
|
102
|
+
'platformMsgs:account' => netsuite_account
|
103
|
+
})
|
104
|
+
|
105
|
+
if data_center_call_response.success?
|
106
|
+
return data_center_call_response.body[:get_data_center_urls_response][:get_data_center_urls_result][:data_center_urls][:webservices_domain]
|
107
|
+
else
|
108
|
+
# log.error "error getting data center url"
|
109
|
+
end
|
110
|
+
rescue Exception => e
|
111
|
+
# log.error "error determining correct datacenter for account #{netsuite_account}. #{e.message}"
|
112
|
+
|
113
|
+
# TODO silence this later: for now we need to investigate when this would occur
|
114
|
+
raise(e)
|
115
|
+
end
|
116
|
+
end
|
3
117
|
|
4
118
|
# Warning this was developed with a Web Services user whose time zone was set to CST
|
5
119
|
# the time zone setting of the user seems to effect how times work in NS
|
@@ -11,7 +125,7 @@ module NetSuite
|
|
11
125
|
# http://stackoverflow.com/questions/279769/convert-to-from-datetime-and-time-in-ruby
|
12
126
|
|
13
127
|
# use when sending times to NS
|
14
|
-
def
|
128
|
+
def normalize_datetime_to_netsuite(datetime)
|
15
129
|
# normalize the time to UCT0
|
16
130
|
# add 6 hours (21600 seconds) of padding (CST offset)
|
17
131
|
# to force the same time to be displayed in the NS UI
|
@@ -22,7 +136,7 @@ module NetSuite
|
|
22
136
|
end
|
23
137
|
|
24
138
|
# use when displaying times from a NS record
|
25
|
-
def
|
139
|
+
def normalize_datetime_from_netsuite(datetime)
|
26
140
|
# the code below eliminates the TimeZone offset then shifts the date forward 2 hours (7200 seconds)
|
27
141
|
# this ensures that ActiveRecord is given a UTC0 DateTime with the exact hour that
|
28
142
|
# was displayed in the NS UI (CST time zone), which will result in the correct display on the web side
|
data/lib/netsuite/version.rb
CHANGED
@@ -21,7 +21,7 @@ describe NetSuite::Records::Address do
|
|
21
21
|
|
22
22
|
it 'has all the right fields' do
|
23
23
|
[
|
24
|
-
:addr1, :addr2, :addressee, :addr_phone, :attention, :city, :
|
24
|
+
:addr1, :addr2, :addressee, :addr_phone, :attention, :city, :internal_id, :override, :state, :zip
|
25
25
|
].each do |field|
|
26
26
|
expect(list).to have_field(field)
|
27
27
|
end
|
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: netsuite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.9
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Ryan Moran
|
@@ -9,34 +10,38 @@ authors:
|
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2016-
|
13
|
+
date: 2016-05-05 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: savon
|
16
17
|
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
17
19
|
requirements:
|
18
|
-
- -
|
20
|
+
- - ! '>='
|
19
21
|
- !ruby/object:Gem::Version
|
20
22
|
version: 2.3.0
|
21
23
|
type: :runtime
|
22
24
|
prerelease: false
|
23
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
24
27
|
requirements:
|
25
|
-
- -
|
28
|
+
- - ! '>='
|
26
29
|
- !ruby/object:Gem::Version
|
27
30
|
version: 2.3.0
|
28
31
|
- !ruby/object:Gem::Dependency
|
29
32
|
name: rspec
|
30
33
|
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
31
35
|
requirements:
|
32
|
-
- -
|
36
|
+
- - ~>
|
33
37
|
- !ruby/object:Gem::Version
|
34
38
|
version: 3.1.0
|
35
39
|
type: :development
|
36
40
|
prerelease: false
|
37
41
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
38
43
|
requirements:
|
39
|
-
- -
|
44
|
+
- - ~>
|
40
45
|
- !ruby/object:Gem::Version
|
41
46
|
version: 3.1.0
|
42
47
|
description: NetSuite SuiteTalk API Wrapper
|
@@ -47,8 +52,9 @@ executables: []
|
|
47
52
|
extensions: []
|
48
53
|
extra_rdoc_files: []
|
49
54
|
files:
|
50
|
-
-
|
51
|
-
-
|
55
|
+
- .gitignore
|
56
|
+
- .rspec
|
57
|
+
- .ruby-version
|
52
58
|
- Gemfile
|
53
59
|
- LICENSE
|
54
60
|
- README.md
|
@@ -403,26 +409,27 @@ files:
|
|
403
409
|
- wsdl/2012_1.wsdl
|
404
410
|
homepage: https://github.com/NetSweet/netsuite
|
405
411
|
licenses: []
|
406
|
-
metadata: {}
|
407
412
|
post_install_message:
|
408
413
|
rdoc_options: []
|
409
414
|
require_paths:
|
410
415
|
- lib
|
411
416
|
required_ruby_version: !ruby/object:Gem::Requirement
|
417
|
+
none: false
|
412
418
|
requirements:
|
413
|
-
- -
|
419
|
+
- - ! '>='
|
414
420
|
- !ruby/object:Gem::Version
|
415
421
|
version: '0'
|
416
422
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
423
|
+
none: false
|
417
424
|
requirements:
|
418
|
-
- -
|
425
|
+
- - ! '>='
|
419
426
|
- !ruby/object:Gem::Version
|
420
427
|
version: '0'
|
421
428
|
requirements: []
|
422
429
|
rubyforge_project:
|
423
|
-
rubygems_version:
|
430
|
+
rubygems_version: 1.8.23.2
|
424
431
|
signing_key:
|
425
|
-
specification_version:
|
432
|
+
specification_version: 3
|
426
433
|
summary: NetSuite SuiteTalk API (SOAP) Wrapper
|
427
434
|
test_files:
|
428
435
|
- spec/netsuite/actions/add_spec.rb
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 63eeb2f2515c54bab1663a2683ed3f234f978d44
|
4
|
-
data.tar.gz: 6aaf5ad5cb70cdfb433a4a9c6c9798f2cf6c29ba
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 16405b1ce41bc3b287eebfa347316998d66507bfa6b6dfa6c2bb0c7a9d6ef158adef44bd19ec229d235e7fb7abca7013369450c5c038fdc4b17392cc1c671893
|
7
|
-
data.tar.gz: 1b214d4f1f23e608920b6556f7440286db57fcf8925d0bf9f3af4dd1bf6b28f5a7839bb19c7fe4767b6c62c22b0dee5c4b0a2da3e2b9fc1b931a4dddc0f7e780
|