netsuite 0.8.11 → 0.8.12

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/codeql-analysis.yml +1 -1
  3. data/HISTORY.md +9 -0
  4. data/README.md +81 -20
  5. data/lib/netsuite/actions/delete.rb +1 -1
  6. data/lib/netsuite/actions/delete_list.rb +1 -1
  7. data/lib/netsuite/actions/get.rb +1 -1
  8. data/lib/netsuite/actions/get_deleted.rb +1 -1
  9. data/lib/netsuite/actions/get_list.rb +1 -1
  10. data/lib/netsuite/actions/initialize.rb +2 -2
  11. data/lib/netsuite/actions/search.rb +1 -1
  12. data/lib/netsuite/records/assembly_item.rb +1 -1
  13. data/lib/netsuite/records/cash_refund_item.rb +1 -1
  14. data/lib/netsuite/records/credit_memo.rb +1 -0
  15. data/lib/netsuite/records/description_item.rb +2 -2
  16. data/lib/netsuite/records/discount_item.rb +1 -1
  17. data/lib/netsuite/records/employee.rb +1 -1
  18. data/lib/netsuite/records/inventory_item.rb +1 -1
  19. data/lib/netsuite/records/invoice.rb +1 -0
  20. data/lib/netsuite/records/item_group.rb +2 -2
  21. data/lib/netsuite/records/kit_item.rb +1 -1
  22. data/lib/netsuite/records/lot_numbered_assembly_item.rb +1 -1
  23. data/lib/netsuite/records/lot_numbered_inventory_item.rb +1 -1
  24. data/lib/netsuite/records/non_inventory_purchase_item.rb +1 -1
  25. data/lib/netsuite/records/non_inventory_resale_item.rb +1 -1
  26. data/lib/netsuite/records/non_inventory_sale_item.rb +1 -1
  27. data/lib/netsuite/records/null_field_list.rb +15 -0
  28. data/lib/netsuite/records/other_charge_sale_item.rb +1 -1
  29. data/lib/netsuite/records/payment_item.rb +2 -2
  30. data/lib/netsuite/records/record_ref.rb +1 -1
  31. data/lib/netsuite/records/serialized_assembly_item.rb +1 -1
  32. data/lib/netsuite/records/serialized_inventory_item.rb +1 -1
  33. data/lib/netsuite/records/service_resale_item.rb +1 -1
  34. data/lib/netsuite/records/service_sale_item.rb +1 -1
  35. data/lib/netsuite/records/subtotal_item.rb +2 -3
  36. data/lib/netsuite/support/records.rb +15 -6
  37. data/lib/netsuite/support/sublist.rb +1 -1
  38. data/lib/netsuite/utilities/strings.rb +15 -0
  39. data/lib/netsuite/version.rb +1 -1
  40. data/lib/netsuite.rb +2 -1
  41. data/netsuite.gemspec +1 -1
  42. data/spec/netsuite/records/cash_refund_item_spec.rb +1 -1
  43. data/spec/netsuite/records/credit_memo_spec.rb +14 -0
  44. data/spec/netsuite/records/invoice_spec.rb +14 -0
  45. data/spec/netsuite/records/null_field_list_spec.rb +30 -0
  46. data/spec/netsuite/support/records_spec.rb +33 -7
  47. metadata +8 -5
  48. data/lib/netsuite/core_ext/string/lower_camelcase.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6137faebee57aa9e3bdaa9cca35d82765f5e9943075eb09bc8bd867b1893ad6b
4
- data.tar.gz: 8ee0308ee67c2dcd440ea17a1107220e394b5b1e15829f76b47ca2769d4be9f2
3
+ metadata.gz: 6f61f6e044bec13cb11de64e320044febb52108b63214d28cb6446ae98e172f9
4
+ data.tar.gz: 93a84083918815d7407a1464a4462a448f35751a37d1972cc6ff35b518a17ff7
5
5
  SHA512:
6
- metadata.gz: a297cc64a543bdf34c086432c78a36b038205998794ae67a968c3c9bdd506a99bfd7a1048bb8aec821fd2edd1c2d89ce715719f035e1a09e5f4b38b560df98b6
7
- data.tar.gz: a536956ed7da89d0fa0e7ec2dcaeba3539ec5dcbddbb3c9249a3b17b93caadaa13b9cba9b7cbe6f0a9b9de786541e4bc190e2771bef03c6cec71d1881c79f7e9
6
+ metadata.gz: 914d9e8b9effdfc2815de7907404d89b9ddf71b03ab08a78f95c762de470a63f5c51c4af138bc326cad2757ce0e5e076cbd0695330794c324d1e224d1ab04b17
7
+ data.tar.gz: ba72989cd165db27b6420b4b09e93c2aec018bf27e10b516872068cebf20c2405dd17d4015f45beeb274f8d27bc1db7e8d0074795c03c8ae070a9e2ec08dd5b0
@@ -38,7 +38,7 @@ jobs:
38
38
 
39
39
  steps:
40
40
  - name: Checkout repository
41
- uses: actions/checkout@v2
41
+ uses: actions/checkout@v3
42
42
 
43
43
  # Initializes the CodeQL tools for scanning.
44
44
  - name: Initialize CodeQL
data/HISTORY.md CHANGED
@@ -4,6 +4,15 @@
4
4
 
5
5
  ### Fixed
6
6
 
7
+ ## 0.8.12
8
+
9
+ ### Added
10
+
11
+ * Add NullFieldList record (to credit memos and invoices) (#529)
12
+ * Add `get_deleted` action to item records (#530)
13
+ * Add `get_deleted` action to Employee records (#531)
14
+ * Remove monkey patched `lower_camelcase` method on String (#533)
15
+
7
16
  ## 0.8.11
8
17
 
9
18
  ### Added
data/README.md CHANGED
@@ -4,13 +4,13 @@
4
4
 
5
5
  # NetSuite SuiteTalk API Ruby Gem
6
6
 
7
- * This gem will act as a wrapper around the NetSuite SuiteTalk WebServices API.
7
+ * This gem will act as a wrapper around the NetSuite SuiteTalk Web Services API.
8
8
  * The gem does not cover the entire API, only the subset contributors have used so far. Please submit a PR for any functionality that's missing!
9
9
  * NetSuite is a complex system. There's a lot to learn and sparse resources available to learn from. Here's a list of [NetSuite Development Resources](https://github.com/NetSweet/netsuite/wiki/NetSuite-Development-Resources).
10
10
 
11
11
  # Help & Support
12
12
 
13
- Join the [slack channel](http://opensuite-slackin.herokuapp.com) for help with any NetSuite issues. Please do not post usage questions as issues in GitHub.
13
+ Join the [Slack channel](http://opensuite-slackin.herokuapp.com) for help with any NetSuite issues. Please do not post usage questions as issues in GitHub.
14
14
 
15
15
  There is some additional helpful resources for NetSuite development [listed here](https://dashboard.suitesync.io/docs/resources#netsuite).
16
16
 
@@ -36,20 +36,20 @@ gem 'netsuite'
36
36
 
37
37
  If you'd like more accurate time conversion support, include the `tzinfo` gem.
38
38
 
39
- This gem is built for ruby 2.6.x+, but should work on older versions down to 1.9. There's a [1-8-stable](https://github.com/NetSweet/netsuite/tree/1-8-stable) branch for ruby 1.8.x support.
39
+ This gem is built for Ruby 2.6.x+, but should work on older versions down to 1.9. There's a [1-8-stable](https://github.com/NetSweet/netsuite/tree/1-8-stable) branch for Ruby 1.8.x support.
40
40
 
41
41
  ## Configuration
42
42
 
43
- The most important thing you'll need is your NetSuite account ID. Not sure how to find your account id? [Here's a guide.](http://mikebian.co/find-netsuite-web-services-account-number/)
43
+ The most important thing you'll need is your NetSuite account ID. Not sure how to find your account ID? [Here's a guide.](http://mikebian.co/find-netsuite-web-services-account-number/)
44
44
 
45
45
  How you connect to NetSuite has changed a lot over the years and differs between API versions. For instance:
46
46
 
47
47
  * Older API versions (~2015) allowed authentication via username and password
48
- * Newever API versions (> 2016) still allowed for username and password authentication, but required an application ID
48
+ * Newer API versions (> 2016) still allowed for username and password authentication, but required an application ID
49
49
  * "OAuth", which requires four separate keys to be manually generated, was supported sometime after 2015
50
50
  * API versions greater than 2018_2 require `endpoint` to be set directly ([more info](https://github.com/NetSweet/netsuite/pull/473))
51
51
 
52
- Here's an example connection configuration. You don't want to actually use username + password config; token based authentication is detailed below in a separate section:
52
+ Here's an example connection configuration. You don't want to actually use username + password config; Token Based Authentication is detailed [in a separate section](#token-based-authentication):
53
53
 
54
54
  ```ruby
55
55
  NetSuite.configure do
@@ -60,13 +60,13 @@ NetSuite.configure do
60
60
  api_version '2018_2'
61
61
 
62
62
  # password-based login information
63
- # in most cases you should use token based authentication instead
63
+ # in most cases you should use Token Based Authentication instead
64
64
  email 'email@example.com'
65
65
  password 'password'
66
66
  role 10
67
67
 
68
- # recent API versions require a account-specific endpoint o be set
69
- # use `NetSuite::Utilities.data_center_url('TSTDRV1576318')` to retrieve wsdl URL
68
+ # recent API versions require an account-specific endpoint to be set
69
+ # use `NetSuite::Utilities.data_center_url('TSTDRV1576318')` to retrieve WSDL URL
70
70
  # you'll want to do this in a background process and strip the protocol out of the return string
71
71
  wsdl_domain 'tstdrv1576318.suitetalk.api.netsuite.com'
72
72
 
@@ -87,17 +87,17 @@ NetSuite.configure do
87
87
 
88
88
  api_version '2018_2'
89
89
 
90
- # optionally specify full wsdl URL (to switch to sandbox, for example)
90
+ # optionally specify full WSDL URL (to switch to sandbox, for example)
91
91
  wsdl "https://webservices.sandbox.netsuite.com/wsdl/v#{api_version}_0/netsuite.wsdl"
92
92
 
93
- # if your datacenter is being switched, you'll have to manually set your wsdl location
93
+ # if your datacenter is being switched, you'll have to manually set your WSDL location
94
94
  wsdl "https://webservices.na2.netsuite.com/wsdl/v#{api_version}_0/netsuite.wsdl"
95
95
 
96
96
  # or specify the wsdl_domain if you want to specify the datacenter and let the configuration
97
97
  # construct the full wsdl location - e.g. "https://#{wsdl_domain}/wsdl/v#{api_version}_0/netsuite.wsdl"
98
98
  wsdl_domain "webservices.na2.netsuite.com"
99
99
 
100
- # often the netsuite servers will hang which would cause a timeout exception to be raised
100
+ # often the NetSuite servers will hang which would cause a timeout exception to be raised
101
101
  # if you don't mind waiting (e.g. processing NS via a background worker), increasing the timeout should fix the issue
102
102
  read_timeout 100_000
103
103
 
@@ -111,7 +111,7 @@ NetSuite.configure do
111
111
  # log_level :debug
112
112
 
113
113
  # password-based login information
114
- # in most cases you should use token based authentication instead
114
+ # in most cases you should use Token Based Authentication instead
115
115
  email 'email@domain.com'
116
116
  password 'password'
117
117
  account '12345'
@@ -124,7 +124,7 @@ NetSuite.configure do
124
124
  end
125
125
  ```
126
126
 
127
- If are using username + password authentication (which you shouldn't be!) *and* you'd like to use a API endpoints greater than 2015_1 you'll need to specify an application ID:
127
+ If you are using username + password authentication (which you shouldn't be!) *and* you'd like to use an API endpoint greater than 2015_1, you'll need to specify an application ID:
128
128
 
129
129
  ```ruby
130
130
  NetSuite::Configuration.soap_header = {
@@ -134,9 +134,9 @@ NetSuite::Configuration.soap_header = {
134
134
  }
135
135
  ```
136
136
 
137
- ### Token based Authentication
137
+ ### Token Based Authentication
138
138
 
139
- OAuth credentials are supported and the recommended authentication approach. [Learn more about how to set up token based authentication here](http://mikebian.co/using-netsuites-token-based-authentication-with-suitetalk/).
139
+ OAuth credentials are supported and the recommended authentication approach. [Learn more about how to set up Token Based Authentication here](http://mikebian.co/using-netsuites-token-based-authentication-with-suitetalk/).
140
140
 
141
141
  ```ruby
142
142
  NetSuite.configure do
@@ -152,7 +152,7 @@ NetSuite.configure do
152
152
  # oauth does not work with API versions less than 2015_2
153
153
  api_version '2016_2'
154
154
 
155
- # the endpoint indicated in the > 2018_2 wsdl is invalid
155
+ # the endpoint indicated in the > 2018_2 WSDL is invalid
156
156
  # you must set the endpoint directly
157
157
  # https://github.com/NetSweet/netsuite/pull/473
158
158
  endpoint "https://#{wsdl_domain}/services/NetSuitePort_#{api_version}"
@@ -284,6 +284,20 @@ NetSuite::Records::BaseRefList.get_select_value(
284
284
  )
285
285
  ```
286
286
 
287
+ ## Null Fields
288
+
289
+ ```ruby
290
+ # updating a field on a record to be null
291
+ invoice = NetSuite::Records::Invoice.get(12345)
292
+ invoice.update(null_field_list: 'shipMethod')
293
+
294
+ # updating multiple fields on a record to be null
295
+ invoice.update(null_field_list: ['shipAddressList', 'shipMethod'])
296
+
297
+ # updating a custom fields on a record to be null, using custom field ID
298
+ invoice.update(null_field_list: 'custBody9')
299
+ ```
300
+
287
301
  ## Searching
288
302
 
289
303
  ```ruby
@@ -300,7 +314,7 @@ search = NetSuite::Records::Customer.search({
300
314
 
301
315
  `open https://system.netsuite.com/app/common/entity/custjob.nl?id=#{search.results.first.internal_id}`
302
316
 
303
- # find the avalara tax item. Some records don't support search.
317
+ # find the Avalara tax item. Some records don't support search.
304
318
  all_sales_taxes = NetSuite::Utilities.backoff { NetSuite::Records::SalesTaxItem.get_all }
305
319
  ns_tax_code = all_sales_taxes.detect { |st| st.item_id == 'AVATAX' }
306
320
 
@@ -411,13 +425,13 @@ NetSuite::Records::SalesOrder.search({
411
425
  ]
412
426
  },
413
427
 
414
- # the column syntax is a WIP. This will change in the future
428
+ # the column syntax is a WIP. This will change in the future.
415
429
  columns: {
416
430
  'tranSales:basic' => [
417
431
  'platformCommon:internalId/' => {},
418
432
  'platformCommon:email/' => {},
419
433
  'platformCommon:tranDate/' => {},
420
- # If you include columns that are only part of the *SearchRowBasic (ie. TransactionSearchRowBasic),
434
+ # If you include columns that are only part of the *SearchRowBasic (ie. TransactionSearchRowBasic),
421
435
  # they'll be readable on the resulting record just like regular fields (my_record.close_date).
422
436
  'platformCommon:closeDate/' => {}
423
437
  ],
@@ -593,6 +607,53 @@ deposit.payment = 20
593
607
  deposit.add
594
608
  ```
595
609
 
610
+ ## Getting Deleted Records
611
+
612
+ ```ruby
613
+ response = NetSuite::Records::LotNumberedInventoryItem.get_deleted({
614
+ criteria: [
615
+ {
616
+ # If you don't specify a type criteria, you'll get all deleted records,
617
+ # regardless of the type of record you called this on.
618
+ field: 'type',
619
+ operator: 'anyOf',
620
+ value: 'lotNumberedInventoryItem',
621
+ }
622
+ ],
623
+ })
624
+
625
+ Array(response.body.fetch(:deleted_record_list)).first
626
+ # => {
627
+ # :deleted_date => Wed, 16 Feb 2022 17:43:45 -0800,
628
+ # :record => {
629
+ # :name => "My Item",
630
+ # :@internal_id => "12485",
631
+ # :@type => "lotNumberedInventoryItem",
632
+ # :"@xsi:type" => "platformCore:RecordRef"
633
+ # }
634
+ # }
635
+
636
+ # deleted_record_list could be:
637
+ # nil - No records matching criteria were deleted
638
+ # Hash - A single record matching criteria was deleted
639
+ # Array - Multiple records matching criteria were deleted
640
+
641
+ # Simple pagination
642
+ page = 1
643
+ begin
644
+ response = NetSuite::Records::LotNumberedInventoryItem.get_deleted({
645
+ criteria: [
646
+ # your criteria
647
+ ],
648
+ page: page,
649
+ })
650
+
651
+ # Do your thing with response.body.fetch(:deleted_record_list)
652
+
653
+ page += 1
654
+ end until page > Integer(response.fetch(:total_pages))
655
+ ```
656
+
596
657
  ## Non-standard Operations
597
658
 
598
659
  ```ruby
@@ -21,7 +21,7 @@ module NetSuite
21
21
  end
22
22
 
23
23
  def soap_type
24
- @object.class.to_s.split('::').last.lower_camelcase
24
+ NetSuite::Support::Records.netsuite_type(@object)
25
25
  end
26
26
 
27
27
  # <soap:Body>
@@ -40,7 +40,7 @@ module NetSuite
40
40
  }
41
41
  end
42
42
  else
43
- type = @klass.to_s.split('::').last.lower_camelcase
43
+ type = NetSuite::Support::Records.netsuite_type(@klass)
44
44
  record_type = 'platformCore:RecordRef'
45
45
 
46
46
  list.map do |internal_id|
@@ -21,7 +21,7 @@ module NetSuite
21
21
  end
22
22
 
23
23
  def soap_type
24
- @klass.to_s.split('::').last.lower_camelcase
24
+ NetSuite::Support::Records.netsuite_type(@klass)
25
25
  end
26
26
 
27
27
  # <soap:Body>
@@ -20,7 +20,7 @@ module NetSuite
20
20
  end
21
21
 
22
22
  def soap_type
23
- @object.class.to_s.split('::').last.lower_camelcase
23
+ NetSuite::Support::Records.netsuite_type(@object)
24
24
  end
25
25
 
26
26
  # <soap:Body>
@@ -33,7 +33,7 @@ module NetSuite
33
33
  }
34
34
  end
35
35
  else
36
- type = @klass.to_s.split('::').last.lower_camelcase
36
+ type = NetSuite::Support::Records.netsuite_type(@klass)
37
37
  record_type = 'platformCore:RecordRef'
38
38
 
39
39
  list.map do |internal_id|
@@ -28,12 +28,12 @@ module NetSuite
28
28
  def request_body
29
29
  {
30
30
  'platformMsgs:initializeRecord' => {
31
- 'platformCore:type' => @klass.to_s.split('::').last.lower_camelcase,
31
+ 'platformCore:type' => NetSuite::Support::Records.netsuite_type(@klass),
32
32
  'platformCore:reference' => {},
33
33
  :attributes! => {
34
34
  'platformCore:reference' => {
35
35
  'internalId' => @object.internal_id,
36
- :type => @object.class.to_s.split('::').last.lower_camelcase
36
+ :type => NetSuite::Support::Records.netsuite_type(@object)
37
37
  }
38
38
  }
39
39
  }
@@ -26,7 +26,7 @@ module NetSuite
26
26
  .update(NetSuite::Configuration.soap_header)
27
27
  .merge(
28
28
  (@options.delete(:preferences) || {}).inject({'platformMsgs:SearchPreferences' => {}}) do |h, (k, v)|
29
- h['platformMsgs:SearchPreferences'][k.to_s.lower_camelcase] = v
29
+ h['platformMsgs:SearchPreferences'][NetSuite::Utilities::Strings.lower_camelcase(k.to_s)] = v
30
30
  h
31
31
  end
32
32
  )
@@ -7,7 +7,7 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :get_select_value, :add, :delete, :update, :upsert, :upsert_list, :search
10
+ actions :get, :get_deleted, :get_list, :get_select_value, :add, :delete, :update, :upsert, :upsert_list, :search
11
11
 
12
12
  fields :auto_lead_time, :auto_preferred_stock_level, :auto_reorder_point, :available_to_partners, :average_cost, :build_entire_assembly,
13
13
  :copy_description, :cost, :cost_estimate, :cost_estimate_type, :cost_estimate_units, :cost_units, :costing_method,
@@ -6,7 +6,7 @@ module NetSuite
6
6
  include Support::Records
7
7
  include Namespaces::TranCust
8
8
 
9
- fields :amount, :rate, :quantity, :is_taxable, :order_line, :line, :description
9
+ fields :amount, :gross_amt, :rate, :quantity, :is_taxable, :order_line, :line, :description
10
10
  field :custom_field_list, CustomFieldList
11
11
 
12
12
  record_refs :item, :klass, :price
@@ -23,6 +23,7 @@ module NetSuite
23
23
  field :item_list, CreditMemoItemList
24
24
  field :apply_list, CreditMemoApplyList
25
25
  field :ship_group_list, SalesOrderShipGroupList
26
+ field :null_field_list, NullFieldList
26
27
 
27
28
  # field :bill_address_list,
28
29
  field :transaction_bill_address, BillAddress
@@ -7,12 +7,12 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :add, :delete, :search, :update, :upsert
10
+ actions :get, :get_deleted, :get_list, :add, :delete, :search, :update, :upsert
11
11
 
12
12
  fields :available_to_partners, :created_date, :description, :display_name, :include_children, :is_inactive, :item_id, :last_modified_date
13
13
 
14
14
  record_refs :custom_form, :department, :issue_product, :klass, :location
15
-
15
+
16
16
  field :custom_field_list, CustomFieldList
17
17
  field :subsidiary_list, RecordRefList
18
18
  field :translations_list, TranslationList
@@ -7,7 +7,7 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :add, :update, :delete, :search, :upsert
10
+ actions :get, :get_deleted, :get_list, :add, :update, :delete, :search, :upsert
11
11
 
12
12
  fields :available_to_partners, :created_date, :description, :display_name, :include_children, :is_inactive, :is_pre_tax,
13
13
  :item_id, :last_modified_date, :non_posting, :rate, :upc_code, :vendor_name
@@ -9,7 +9,7 @@ module NetSuite
9
9
 
10
10
  # https://system.netsuite.com/help/helpcenter/en_US/srbrowser/Browser2014_1/script/record/employee.html
11
11
 
12
- actions :get, :get_list, :add, :update, :upsert, :upsert_list, :delete, :search
12
+ actions :get, :get_deleted, :get_list, :add, :update, :upsert, :upsert_list, :delete, :search
13
13
 
14
14
  fields :alt_name, :phone, :first_name, :last_name, :is_inactive, :email, :give_access, :send_email, :is_support_rep,
15
15
  :birth_date, :hire_date, :last_review_date, :next_review_date, :title, :home_phone, :office_phone,
@@ -20,7 +20,7 @@ module NetSuite
20
20
  # }
21
21
  # ]
22
22
  #
23
- actions :get, :get_list, :add, :delete, :search, :update, :upsert, :update_list
23
+ actions :get, :get_deleted, :get_list, :add, :delete, :search, :update, :upsert, :update_list
24
24
 
25
25
  fields :auto_lead_time,
26
26
  :auto_preferred_stock_level,
@@ -38,6 +38,7 @@ module NetSuite
38
38
  field :custom_field_list, CustomFieldList
39
39
  field :shipping_address, Address
40
40
  field :billing_address, Address
41
+ field :null_field_list, NullFieldList
41
42
 
42
43
  read_only_fields :sub_total, :discount_total, :total, :recognized_revenue, :amount_remaining, :amount_paid,
43
44
  :alt_shipping_cost, :gift_cert_applied, :handling_cost, :alt_handling_cost
@@ -7,13 +7,13 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :add, :delete, :search, :update, :upsert
10
+ actions :get, :get_deleted, :get_list, :add, :delete, :search, :update, :upsert
11
11
 
12
12
  fields :available_to_partners, :created_date, :description, :display_name, :include_children, :include_start_end_lines,
13
13
  :is_inactive, :is_vsoe_bundle, :item_id, :last_modified_date, :print_items, :upc_code, :vendor_name
14
14
 
15
15
  record_refs :custom_form, :default_item_ship_method, :department, :issue_product, :item_ship_method_list, :klass, :location, :parent
16
-
16
+
17
17
  field :custom_field_list, CustomFieldList
18
18
  # TODO field :item_carrier, ShippingCarrier
19
19
  field :member_list, ItemMemberList
@@ -7,7 +7,7 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :add, :delete, :search, :update, :upsert
10
+ actions :get, :get_deleted, :get_list, :add, :delete, :search, :update, :upsert
11
11
 
12
12
  fields :available_to_partners, :cost_estimate, :created_date, :defer_rev_rec, :description, :display_name,
13
13
  :dont_show_price, :enforce_min_qty_internally, :exclude_from_sitemap, :featured_description, :handling_cost,
@@ -7,7 +7,7 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :get_select_value, :add, :delete, :update, :upsert, :upsert_list, :search
10
+ actions :get, :get_deleted, :get_list, :get_select_value, :add, :delete, :update, :upsert, :upsert_list, :search
11
11
 
12
12
  fields :auto_lead_time, :auto_preferred_stock_level, :auto_reorder_point, :available_to_partners, :average_cost, :build_entire_assembly,
13
13
  :copy_description, :cost, :cost_estimate, :cost_estimate_type, :cost_estimate_units, :cost_units, :costing_method,
@@ -27,7 +27,7 @@ module NetSuite
27
27
  # TODO: field :site_category_list, SiteCategoryList
28
28
  field :translations_list, TranslationList
29
29
 
30
- actions :get, :get_list, :add, :delete, :search, :update, :upsert, :update_list
30
+ actions :get, :get_deleted, :get_list, :add, :delete, :search, :update, :upsert, :update_list
31
31
 
32
32
  record_refs :alternate_demand_source_item,
33
33
  :asset_account,
@@ -7,7 +7,7 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :add, :delete, :search, :upsert
10
+ actions :get, :get_deleted, :get_list, :add, :delete, :search, :upsert
11
11
 
12
12
  fields :available_to_partners, :cost_estimate, :cost_estimate_type, :cost_estimate_units, :country_of_manufacture,
13
13
  :created_date, :display_name, :dont_show_price, :enforce_min_qty_internally, :exclude_from_sitemap,
@@ -7,7 +7,7 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :add, :delete, :search, :upsert, :update
10
+ actions :get, :get_deleted, :get_list, :add, :delete, :search, :upsert, :update
11
11
 
12
12
  fields :amortization_period,
13
13
  :available_to_partners,
@@ -7,7 +7,7 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :add, :delete, :search, :update, :upsert
10
+ actions :get, :get_deleted, :get_list, :add, :delete, :search, :update, :upsert
11
11
 
12
12
  fields :available_to_partners,
13
13
  :contingent_revenue_handling,
@@ -0,0 +1,15 @@
1
+ module NetSuite
2
+ module Records
3
+ class NullFieldList
4
+ include Support::Fields
5
+ include Support::Records
6
+ include Namespaces::PlatformCore
7
+
8
+ fields :name
9
+
10
+ def initialize(attributes = {})
11
+ initialize_from_attributes_hash(attributes)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -7,7 +7,7 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :add, :update, :delete, :upsert, :search
10
+ actions :get, :get_deleted, :get_list, :add, :update, :delete, :upsert, :search
11
11
 
12
12
  attr_reader :internal_id
13
13
  attr_accessor :external_id
@@ -7,7 +7,7 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :add, :delete, :search, :update, :upsert
10
+ actions :get, :get_deleted, :get_list, :add, :delete, :search, :update, :upsert
11
11
 
12
12
  fields :available_to_partners, :created_date, :description, :display_name, :include_children, :is_inactive, :item_id, :last_modified_date, :undep_funds
13
13
 
@@ -15,7 +15,7 @@ module NetSuite
15
15
 
16
16
  field :custom_field_list, CustomFieldList
17
17
  field :subsidiary_list, RecordRefList
18
-
18
+
19
19
  # TODO custom records need to be implemented
20
20
  field :translations_list, TranslationList
21
21
 
@@ -21,7 +21,7 @@ module NetSuite
21
21
  record = attributes_or_record
22
22
  @internal_id = record.internal_id if record.respond_to?(:internal_id)
23
23
  @external_id = record.external_id if record.respond_to?(:external_id)
24
- @type = record.class.to_s.split('::').last.lower_camelcase
24
+ @type = NetSuite::Support::Records.netsuite_type(record)
25
25
  end
26
26
  end
27
27
 
@@ -7,7 +7,7 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :add, :delete, :search, :update, :upsert
10
+ actions :get, :get_deleted, :get_list, :add, :delete, :search, :update, :upsert
11
11
 
12
12
  fields :alternate_demand_source_item,
13
13
  :asset_account,
@@ -7,7 +7,7 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :add, :delete, :search, :update, :upsert
10
+ actions :get, :get_deleted, :get_list, :add, :delete, :search, :update, :upsert
11
11
 
12
12
  record_refs :soft_descriptor,
13
13
  :stock_unit,
@@ -7,7 +7,7 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :add, :update, :delete, :upsert, :search
10
+ actions :get, :get_deleted, :get_list, :add, :update, :delete, :upsert, :search
11
11
 
12
12
  fields :amortization_period,
13
13
  :available_to_partners,
@@ -7,7 +7,7 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :add, :update, :delete, :upsert, :search
10
+ actions :get, :get_deleted, :get_list, :add, :update, :delete, :upsert, :search
11
11
 
12
12
  fields :available_to_partners, :cost_estimate, :cost_estimate_type, :cost_estimate_units, :create_job, :created_date,
13
13
  :display_name, :dont_show_price, :enforce_min_qty_internally, :exclude_from_sitemap, :featured_description,
@@ -7,12 +7,12 @@ module NetSuite
7
7
  include Support::Actions
8
8
  include Namespaces::ListAcct
9
9
 
10
- actions :get, :get_list, :add, :delete, :search, :update, :upsert
10
+ actions :get, :get_deleted, :get_list, :add, :delete, :search, :update, :upsert
11
11
 
12
12
  fields :available_to_partners, :created_date, :description, :include_children, :is_inactive, :item_id, :last_modified_date
13
13
 
14
14
  record_refs :custom_form, :department, :issue_product, :klass, :location
15
-
15
+
16
16
  field :custom_field_list, CustomFieldList
17
17
  field :subsidiary_list, RecordRefList
18
18
  field :translations_list, TranslationList
@@ -32,4 +32,3 @@ module NetSuite
32
32
  end
33
33
  end
34
34
  end
35
-
@@ -6,8 +6,8 @@ module NetSuite
6
6
 
7
7
  def to_record
8
8
  attributes.reject { |k,v| self.class.read_only_fields.include?(k) || self.class.search_only_fields.include?(k) }.inject({}) do |hash, (k,v)|
9
- kname = "#{record_namespace}:"
10
- kname += k == :klass ? 'class' : k.to_s.lower_camelcase
9
+ kname = "#{v.is_a?(NetSuite::Records::NullFieldList) ? v.record_namespace : record_namespace}:"
10
+ kname += k == :klass ? 'class' : NetSuite::Utilities::Strings.lower_camelcase(k.to_s)
11
11
 
12
12
  to_attributes!(hash, kname, v)
13
13
 
@@ -38,13 +38,13 @@ module NetSuite
38
38
  if v.kind_of?(NetSuite::Records::RecordRef) && v.type
39
39
  hash[:attributes!] ||= {}
40
40
  hash[:attributes!][kname] ||= {}
41
- hash[:attributes!][kname]['type'] = v.type.lower_camelcase
41
+ hash[:attributes!][kname]['type'] = NetSuite::Utilities::Strings.lower_camelcase(v.type)
42
42
  end
43
43
 
44
44
  if v.kind_of?(NetSuite::Records::CustomRecordRef) && v.type_id
45
45
  hash[:attributes!] ||= {}
46
46
  hash[:attributes!][kname] ||= {}
47
- hash[:attributes!][kname]['typeId'] = v.type_id.lower_camelcase
47
+ hash[:attributes!][kname]['typeId'] = NetSuite::Utilities::Strings.lower_camelcase(v.type_id)
48
48
  end
49
49
  end
50
50
 
@@ -53,11 +53,11 @@ module NetSuite
53
53
  end
54
54
 
55
55
  def netsuite_type
56
- record_type_without_namespace.lower_camelcase
56
+ Records.netsuite_type(self)
57
57
  end
58
58
 
59
59
  def record_type_without_namespace
60
- "#{self.class.to_s.split('::').last}"
60
+ Records.record_type_without_namespace(self)
61
61
  end
62
62
 
63
63
  def refresh(credentials = {})
@@ -75,6 +75,15 @@ module NetSuite
75
75
  self
76
76
  end
77
77
 
78
+ def self.netsuite_type(obj)
79
+ NetSuite::Utilities::Strings.lower_camelcase(record_type_without_namespace(obj))
80
+ end
81
+
82
+ def self.record_type_without_namespace(obj)
83
+ klass = obj.is_a?(Class) ? obj : obj.class
84
+ "#{klass.to_s.split('::').last}"
85
+ end
86
+
78
87
  end
79
88
  end
80
89
  end
@@ -35,7 +35,7 @@ module NetSuite
35
35
  end
36
36
 
37
37
  def to_record
38
- rec = { "#{record_namespace}:#{sublist_key.to_s.lower_camelcase}" => send(self.sublist_key).map(&:to_record) }
38
+ rec = { "#{record_namespace}:#{NetSuite::Utilities::Strings.lower_camelcase(sublist_key.to_s)}" => send(self.sublist_key).map(&:to_record) }
39
39
 
40
40
  if !replace_all.nil?
41
41
  rec["#{record_namespace}:replaceAll"] = !!replace_all
@@ -0,0 +1,15 @@
1
+ module NetSuite
2
+ module Utilities
3
+ module Strings
4
+ class << self
5
+ def lower_camelcase(obj)
6
+ str = obj.is_a?(String) ? obj.dup : obj.to_s
7
+ str.gsub!(/\/(.?)/) { "::#{$1.upcase}" }
8
+ str.gsub!(/(?:_+|-+)([a-z]|[0-9])/) { $1.upcase }
9
+ str.gsub!(/(\A|\s)([A-Z])/) { $1 + $2.downcase }
10
+ str
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
1
  module NetSuite
2
- VERSION = '0.8.11'
2
+ VERSION = '0.8.12'
3
3
  end
data/lib/netsuite.rb CHANGED
@@ -5,9 +5,9 @@ require 'netsuite/version'
5
5
  require 'netsuite/errors'
6
6
  require 'netsuite/utilities'
7
7
  require 'netsuite/utilities/data_center'
8
+ require 'netsuite/utilities/strings'
8
9
  require 'netsuite/rest/utilities/roles'
9
10
  require 'netsuite/rest/utilities/request'
10
- require 'netsuite/core_ext/string/lower_camelcase'
11
11
 
12
12
  module NetSuite
13
13
  autoload :Configuration, 'netsuite/configuration'
@@ -225,6 +225,7 @@ module NetSuite
225
225
  autoload :NonInventoryResaleItem, 'netsuite/records/non_inventory_resale_item'
226
226
  autoload :Note, 'netsuite/records/note'
227
227
  autoload :NoteType, 'netsuite/records/note_type'
228
+ autoload :NullFieldList, 'netsuite/records/null_field_list'
228
229
  autoload :Opportunity, 'netsuite/records/opportunity'
229
230
  autoload :OpportunityItem, 'netsuite/records/opportunity_item'
230
231
  autoload :OpportunityItemList, 'netsuite/records/opportunity_item_list'
data/netsuite.gemspec CHANGED
@@ -20,5 +20,5 @@ Gem::Specification.new do |gem|
20
20
  gem.add_dependency 'savon', '>= 2.3.0'
21
21
 
22
22
  gem.add_development_dependency 'rspec', '~> 3.11.0'
23
- gem.add_development_dependency 'rake', '~> 13'
23
+ gem.add_development_dependency 'rake', '~> 12.3.3'
24
24
  end
@@ -5,7 +5,7 @@ describe NetSuite::Records::CashRefundItem do
5
5
 
6
6
  it 'has all the right fields' do
7
7
  [
8
- :amount
8
+ :amount, :gross_amt, :rate, :quantity, :is_taxable, :order_line, :line, :description
9
9
  ].each do |field|
10
10
  expect(item).to have_field(field)
11
11
  end
@@ -20,6 +20,20 @@ describe NetSuite::Records::CreditMemo do
20
20
  end
21
21
  end
22
22
 
23
+ it 'has all the right fields with specific classes' do
24
+ {
25
+ custom_field_list: NetSuite::Records::CustomFieldList,
26
+ item_list: NetSuite::Records::CreditMemoItemList,
27
+ apply_list: NetSuite::Records::CreditMemoApplyList,
28
+ ship_group_list: NetSuite::Records::SalesOrderShipGroupList,
29
+ null_field_list: NetSuite::Records::NullFieldList,
30
+ transaction_bill_address: NetSuite::Records::BillAddress,
31
+ billing_address: NetSuite::Records::Address,
32
+ }.each do |field, klass|
33
+ expect(memo).to have_field(field, klass)
34
+ end
35
+ end
36
+
23
37
  it 'has all the right record refs' do
24
38
  [
25
39
  :account, :bill_address_list, :created_from, :custom_form, :department, :discount_item, :entity, :gift_cert,
@@ -32,6 +32,20 @@ describe NetSuite::Records::Invoice do
32
32
  end
33
33
  end
34
34
 
35
+ it 'has all the right fields with specific classes' do
36
+ {
37
+ transaction_bill_address: NetSuite::Records::BillAddress,
38
+ transaction_ship_address: NetSuite::Records::ShipAddress,
39
+ item_list: NetSuite::Records::InvoiceItemList,
40
+ custom_field_list: NetSuite::Records::CustomFieldList,
41
+ shipping_address: NetSuite::Records::Address,
42
+ billing_address: NetSuite::Records::Address,
43
+ null_field_list: NetSuite::Records::NullFieldList,
44
+ }.each do |field, klass|
45
+ expect(invoice).to have_field(field, klass)
46
+ end
47
+ end
48
+
35
49
  it 'has all the right read_only_fields' do
36
50
  [
37
51
  :sub_total, :discount_total, :total, :alt_handling_cost, :alt_shipping_cost, :gift_cert_applied,
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe NetSuite::Records::RecordRef do
4
+ let(:null_field_list) { NetSuite::Records::NullFieldList.new }
5
+
6
+ describe '#to_record' do
7
+ it 'can represent itself as a SOAP record for single value' do
8
+ null_field_list.name = 'blah'
9
+ record = {
10
+ 'platformCore:name' => 'blah'
11
+ }
12
+ expect(null_field_list.to_record).to eql(record)
13
+ end
14
+
15
+ it 'can represent itself as a SOAP record for multiple values' do
16
+ null_field_list.name = ['blah', 'foo']
17
+ record = {
18
+ 'platformCore:name' => ['blah', 'foo']
19
+ }
20
+ expect(null_field_list.to_record).to eql(record)
21
+ end
22
+ end
23
+
24
+ describe '#record_type' do
25
+ it 'returns a string of the SOAP type' do
26
+ expect(null_field_list.record_type).to eql('platformCore:NullFieldList')
27
+ end
28
+ end
29
+
30
+ end
@@ -4,11 +4,14 @@ module Foo
4
4
  module Bar
5
5
  class Baz
6
6
  include NetSuite::Support::Fields
7
+ include NetSuite::Support::RecordRefs
7
8
  include NetSuite::Support::Records
9
+ include NetSuite::Namespaces::TranSales
8
10
 
9
- def attributes
10
- { :source => 'Google', :total => 100.0 }
11
- end
11
+ fields :source, :total
12
+ field :null_field_list, NetSuite::Records::NullFieldList
13
+
14
+ record_ref :related_record
12
15
  end
13
16
  end
14
17
  end
@@ -16,18 +19,41 @@ end
16
19
  describe NetSuite::Support::Records do
17
20
  let(:instance) { Foo::Bar::Baz.new }
18
21
 
19
- describe '#record_type' do
22
+ describe '#to_record' do
20
23
  it 'returns a hash of attributes to be used in a SOAP request' do
24
+ instance.source = 'Google'
25
+ instance.total = 100.0
26
+
21
27
  expect(instance.to_record).to eql({
22
- 'platformCore:source' => 'Google',
23
- 'platformCore:total' => 100.0
28
+ 'tranSales:source' => 'Google',
29
+ 'tranSales:total' => 100.0
30
+ })
31
+ end
32
+
33
+ it 'uses the records namespace for the outer elements namespace and the field values namespace for the inner elements namespace' do
34
+ instance.related_record = NetSuite::Records::RecordRef.new(name: 'blah')
35
+
36
+ expect(instance.to_record).to eq({
37
+ 'tranSales:relatedRecord' => {
38
+ 'platformCore:name' => 'blah',
39
+ },
40
+ })
41
+ end
42
+
43
+ it 'uses the fields namespace for the outer elements namespace for NullFieldList value' do
44
+ instance.null_field_list.name = 'source'
45
+
46
+ expect(instance.to_record).to eq({
47
+ 'platformCore:nullFieldList' => {
48
+ 'platformCore:name' => 'source',
49
+ },
24
50
  })
25
51
  end
26
52
  end
27
53
 
28
54
  describe '#record_type' do
29
55
  it 'returns a string of the record type to be used in a SOAP request' do
30
- expect(instance.record_type).to eql('platformCore:Baz')
56
+ expect(instance.record_type).to eql('tranSales:Baz')
31
57
  end
32
58
  end
33
59
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: netsuite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.11
4
+ version: 0.8.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Moran
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-03-27 00:00:00.000000000 Z
12
+ date: 2022-04-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: savon
@@ -45,14 +45,14 @@ dependencies:
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: '13'
48
+ version: 12.3.3
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '13'
55
+ version: 12.3.3
56
56
  description: NetSuite SuiteTalk API Wrapper
57
57
  email:
58
58
  - ryan.moran@gmail.com
@@ -92,7 +92,6 @@ files:
92
92
  - lib/netsuite/actions/upsert.rb
93
93
  - lib/netsuite/actions/upsert_list.rb
94
94
  - lib/netsuite/configuration.rb
95
- - lib/netsuite/core_ext/string/lower_camelcase.rb
96
95
  - lib/netsuite/errors.rb
97
96
  - lib/netsuite/namespaces/act_sched.rb
98
97
  - lib/netsuite/namespaces/comm_general.rb
@@ -272,6 +271,7 @@ files:
272
271
  - lib/netsuite/records/non_inventory_sale_item.rb
273
272
  - lib/netsuite/records/note.rb
274
273
  - lib/netsuite/records/note_type.rb
274
+ - lib/netsuite/records/null_field_list.rb
275
275
  - lib/netsuite/records/opportunity.rb
276
276
  - lib/netsuite/records/opportunity_item.rb
277
277
  - lib/netsuite/records/opportunity_item_list.rb
@@ -376,6 +376,7 @@ files:
376
376
  - lib/netsuite/support/sublist.rb
377
377
  - lib/netsuite/utilities.rb
378
378
  - lib/netsuite/utilities/data_center.rb
379
+ - lib/netsuite/utilities/strings.rb
379
380
  - lib/netsuite/version.rb
380
381
  - netsuite.gemspec
381
382
  - spec/netsuite/actions/add_spec.rb
@@ -486,6 +487,7 @@ files:
486
487
  - spec/netsuite/records/non_inventory_sale_item_spec.rb
487
488
  - spec/netsuite/records/note_spec.rb
488
489
  - spec/netsuite/records/note_type_spec.rb
490
+ - spec/netsuite/records/null_field_list_spec.rb
489
491
  - spec/netsuite/records/partner_spec.rb
490
492
  - spec/netsuite/records/payment_item_spec.rb
491
493
  - spec/netsuite/records/payment_method_spec.rb
@@ -723,6 +725,7 @@ test_files:
723
725
  - spec/netsuite/records/non_inventory_sale_item_spec.rb
724
726
  - spec/netsuite/records/note_spec.rb
725
727
  - spec/netsuite/records/note_type_spec.rb
728
+ - spec/netsuite/records/null_field_list_spec.rb
726
729
  - spec/netsuite/records/partner_spec.rb
727
730
  - spec/netsuite/records/payment_item_spec.rb
728
731
  - spec/netsuite/records/payment_method_spec.rb
@@ -1,9 +0,0 @@
1
- class String
2
- def lower_camelcase
3
- str = dup
4
- str.gsub!(/\/(.?)/) { "::#{$1.upcase}" }
5
- str.gsub!(/(?:_+|-+)([a-z]|[0-9])/) { $1.upcase }
6
- str.gsub!(/(\A|\s)([A-Z])/) { $1 + $2.downcase }
7
- str
8
- end
9
- end