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.
- checksums.yaml +4 -4
- data/.github/workflows/codeql-analysis.yml +1 -1
- data/HISTORY.md +9 -0
- data/README.md +81 -20
- data/lib/netsuite/actions/delete.rb +1 -1
- data/lib/netsuite/actions/delete_list.rb +1 -1
- data/lib/netsuite/actions/get.rb +1 -1
- data/lib/netsuite/actions/get_deleted.rb +1 -1
- data/lib/netsuite/actions/get_list.rb +1 -1
- data/lib/netsuite/actions/initialize.rb +2 -2
- data/lib/netsuite/actions/search.rb +1 -1
- data/lib/netsuite/records/assembly_item.rb +1 -1
- data/lib/netsuite/records/cash_refund_item.rb +1 -1
- data/lib/netsuite/records/credit_memo.rb +1 -0
- data/lib/netsuite/records/description_item.rb +2 -2
- data/lib/netsuite/records/discount_item.rb +1 -1
- data/lib/netsuite/records/employee.rb +1 -1
- data/lib/netsuite/records/inventory_item.rb +1 -1
- data/lib/netsuite/records/invoice.rb +1 -0
- data/lib/netsuite/records/item_group.rb +2 -2
- data/lib/netsuite/records/kit_item.rb +1 -1
- data/lib/netsuite/records/lot_numbered_assembly_item.rb +1 -1
- data/lib/netsuite/records/lot_numbered_inventory_item.rb +1 -1
- data/lib/netsuite/records/non_inventory_purchase_item.rb +1 -1
- data/lib/netsuite/records/non_inventory_resale_item.rb +1 -1
- data/lib/netsuite/records/non_inventory_sale_item.rb +1 -1
- data/lib/netsuite/records/null_field_list.rb +15 -0
- data/lib/netsuite/records/other_charge_sale_item.rb +1 -1
- data/lib/netsuite/records/payment_item.rb +2 -2
- data/lib/netsuite/records/record_ref.rb +1 -1
- data/lib/netsuite/records/serialized_assembly_item.rb +1 -1
- data/lib/netsuite/records/serialized_inventory_item.rb +1 -1
- data/lib/netsuite/records/service_resale_item.rb +1 -1
- data/lib/netsuite/records/service_sale_item.rb +1 -1
- data/lib/netsuite/records/subtotal_item.rb +2 -3
- data/lib/netsuite/support/records.rb +15 -6
- data/lib/netsuite/support/sublist.rb +1 -1
- data/lib/netsuite/utilities/strings.rb +15 -0
- data/lib/netsuite/version.rb +1 -1
- data/lib/netsuite.rb +2 -1
- data/netsuite.gemspec +1 -1
- data/spec/netsuite/records/cash_refund_item_spec.rb +1 -1
- data/spec/netsuite/records/credit_memo_spec.rb +14 -0
- data/spec/netsuite/records/invoice_spec.rb +14 -0
- data/spec/netsuite/records/null_field_list_spec.rb +30 -0
- data/spec/netsuite/support/records_spec.rb +33 -7
- metadata +8 -5
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f61f6e044bec13cb11de64e320044febb52108b63214d28cb6446ae98e172f9
|
4
|
+
data.tar.gz: 93a84083918815d7407a1464a4462a448f35751a37d1972cc6ff35b518a17ff7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 914d9e8b9effdfc2815de7907404d89b9ddf71b03ab08a78f95c762de470a63f5c51c4af138bc326cad2757ce0e5e076cbd0695330794c324d1e224d1ab04b17
|
7
|
+
data.tar.gz: ba72989cd165db27b6420b4b09e93c2aec018bf27e10b516872068cebf20c2405dd17d4015f45beeb274f8d27bc1db7e8d0074795c03c8ae070a9e2ec08dd5b0
|
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
|
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 [
|
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
|
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
|
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
|
-
*
|
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;
|
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
|
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
|
69
|
-
# use `NetSuite::Utilities.data_center_url('TSTDRV1576318')` to retrieve
|
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
|
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
|
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
|
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
|
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
|
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
|
137
|
+
### Token Based Authentication
|
138
138
|
|
139
|
-
OAuth credentials are supported and the recommended authentication approach. [Learn more about how to set up
|
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
|
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
|
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
|
data/lib/netsuite/actions/get.rb
CHANGED
@@ -28,12 +28,12 @@ module NetSuite
|
|
28
28
|
def request_body
|
29
29
|
{
|
30
30
|
'platformMsgs:initializeRecord' => {
|
31
|
-
'platformCore:type' => @klass
|
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
|
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
|
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 =
|
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
|
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
|
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
|
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
|
-
|
56
|
+
Records.netsuite_type(self)
|
57
57
|
end
|
58
58
|
|
59
59
|
def record_type_without_namespace
|
60
|
-
|
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
|
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
|
data/lib/netsuite/version.rb
CHANGED
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,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
|
-
|
10
|
-
|
11
|
-
|
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 '#
|
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
|
-
'
|
23
|
-
'
|
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('
|
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.
|
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-
|
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:
|
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:
|
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
|