netsuite 0.5.8 → 0.5.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -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