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.
@@ -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(basic: [
182
- {
183
- field: 'recType',
184
- operator: 'is',
185
- # custom record type
186
- value: NetSuite::Records::CustomRecordRef.new(:internal_id => 10),
187
- }]).results
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
- field: 'custbody_internetorder',
221
- type: 'SearchBooleanCustomField',
222
- value: true
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, :custom_field_list, :internal_id, :override, :state, :zip
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
- field :amount
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, :custom_form, :currency, :posting_period
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
 
@@ -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 self.normalize_datetime_to_netsuite(datetime)
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 self.normalize_datetime_from_netsuite(datetime)
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
@@ -1,3 +1,3 @@
1
1
  module Netsuite
2
- VERSION = '0.5.8'
2
+ VERSION = '0.5.9'
3
3
  end
@@ -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, :custom_field_list, :internal_id, :override, :state, :zip
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.8
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-04-15 00:00:00.000000000 Z
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
- - ".gitignore"
51
- - ".rspec"
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: 2.5.1
430
+ rubygems_version: 1.8.23.2
424
431
  signing_key:
425
- specification_version: 4
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