netsuite 0.8.2 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +69 -20
- data/lib/netsuite.rb +11 -0
- data/lib/netsuite/actions/search.rb +1 -6
- data/lib/netsuite/actions/update_list.rb +109 -0
- data/lib/netsuite/records/bin_transfer.rb +38 -0
- data/lib/netsuite/records/bin_transfer_inventory.rb +20 -0
- data/lib/netsuite/records/bin_transfer_inventory_list.rb +10 -0
- data/lib/netsuite/records/cash_refund_item.rb +1 -1
- data/lib/netsuite/records/classification.rb +1 -1
- data/lib/netsuite/records/inbound_shipment.rb +33 -0
- data/lib/netsuite/records/inbound_shipment_item.rb +39 -0
- data/lib/netsuite/records/inbound_shipment_item_list.rb +11 -0
- data/lib/netsuite/records/inter_company_journal_entry.rb +48 -0
- data/lib/netsuite/records/inter_company_journal_entry_line.rb +28 -0
- data/lib/netsuite/records/inter_company_journal_entry_line_list.rb +14 -0
- data/lib/netsuite/records/inventory_item.rb +1 -1
- data/lib/netsuite/records/price_level.rb +26 -0
- data/lib/netsuite/records/return_authorization_item.rb +1 -1
- data/lib/netsuite/records/sales_order_item.rb +12 -5
- data/lib/netsuite/records/support_case.rb +1 -1
- data/lib/netsuite/support/actions.rb +2 -0
- data/lib/netsuite/support/search_result.rb +7 -3
- data/lib/netsuite/utilities.rb +26 -0
- data/lib/netsuite/version.rb +1 -1
- data/spec/netsuite/actions/update_list_spec.rb +107 -0
- data/spec/netsuite/records/basic_record_spec.rb +5 -1
- data/spec/netsuite/records/inter_company_journal_entry_line_list_spec.rb +26 -0
- data/spec/netsuite/records/inter_company_journal_entry_line_spec.rb +60 -0
- data/spec/netsuite/records/inter_company_journal_entry_spec.rb +156 -0
- data/spec/netsuite/records/inventory_item_spec.rb +57 -0
- data/spec/netsuite/records/price_level_spec.rb +16 -0
- data/spec/netsuite/records/return_authorization_item_spec.rb +1 -1
- data/spec/netsuite/records/sales_order_item_spec.rb +11 -5
- data/spec/netsuite/utilities_spec.rb +21 -0
- data/spec/support/fixtures/update_list/update_list_items.xml +22 -0
- data/spec/support/fixtures/update_list/update_list_one_item.xml +18 -0
- data/spec/support/fixtures/update_list/update_list_with_errors.xml +32 -0
- metadata +29 -2
@@ -0,0 +1,33 @@
|
|
1
|
+
module NetSuite
|
2
|
+
module Records
|
3
|
+
class InboundShipment
|
4
|
+
include Support::Fields
|
5
|
+
include Support::RecordRefs
|
6
|
+
include Support::Records
|
7
|
+
include Support::Actions
|
8
|
+
include Namespaces::TranPurch
|
9
|
+
|
10
|
+
actions :get, :get_list, :add, :initialize, :delete, :update, :upsert, :upsert_list, :search, :update_list
|
11
|
+
|
12
|
+
fields :shipment_number, :external_document_number, :shipment_status, :expected_shipping_date,
|
13
|
+
:actual_shipping_date, :expected_delivery_date, :actual_delivery_date, :shipment_memo,
|
14
|
+
:vessel_number, :bill_of_lading
|
15
|
+
|
16
|
+
field :items_list, InboundShipmentItemList
|
17
|
+
field :custom_field_list, CustomFieldList
|
18
|
+
|
19
|
+
record_refs :custom_form
|
20
|
+
|
21
|
+
attr_reader :internal_id
|
22
|
+
attr_accessor :external_id
|
23
|
+
attr_accessor :search_joins
|
24
|
+
|
25
|
+
def initialize(attributes = {})
|
26
|
+
@internal_id = attributes.delete(:internal_id) || attributes.delete(:@internal_id)
|
27
|
+
@external_id = attributes.delete(:external_id) || attributes.delete(:@external_id)
|
28
|
+
initialize_from_attributes_hash(attributes)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module NetSuite
|
2
|
+
module Records
|
3
|
+
class InboundShipmentItem
|
4
|
+
include Support::Fields
|
5
|
+
include Support::RecordRefs
|
6
|
+
include Support::Records
|
7
|
+
include Namespaces::TranPurch
|
8
|
+
|
9
|
+
fields :id, :shipment_item_description, :po_vendor, :quantity_received, :quantity_expected,
|
10
|
+
:quantity_remaining, :po_rate, :expected_rate, :shipment_item_amount
|
11
|
+
|
12
|
+
field :custom_field_list, CustomFieldList
|
13
|
+
|
14
|
+
record_refs :purchase_order, :shipment_item, :receiving_location, :po_currency, :incoterm
|
15
|
+
|
16
|
+
def initialize(attributes_or_record = {})
|
17
|
+
case attributes_or_record
|
18
|
+
when Hash
|
19
|
+
initialize_from_attributes_hash(attributes_or_record)
|
20
|
+
when self.class
|
21
|
+
initialize_from_record(attributes_or_record)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize_from_record(record)
|
26
|
+
self.attributes = record.send(:attributes)
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_record
|
30
|
+
rec = super
|
31
|
+
if rec["#{record_namespace}:customFieldList"]
|
32
|
+
rec["#{record_namespace}:customFieldList!"] = rec.delete("#{record_namespace}:customFieldList")
|
33
|
+
end
|
34
|
+
rec
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module NetSuite
|
2
|
+
module Records
|
3
|
+
class InterCompanyJournalEntry
|
4
|
+
include Support::Fields
|
5
|
+
include Support::RecordRefs
|
6
|
+
include Support::Records
|
7
|
+
include Support::Actions
|
8
|
+
include Namespaces::TranGeneral
|
9
|
+
|
10
|
+
actions :get, :get_list, :add, :delete, :search, :upsert
|
11
|
+
|
12
|
+
fields :approved, :created_date, :exchange_rate, :is_book_specific, :last_modified_date, :memo, :reversal_date, :reversal_defer,
|
13
|
+
:reversal_entry, :tran_date, :tran_id
|
14
|
+
|
15
|
+
field :custom_field_list, CustomFieldList
|
16
|
+
field :line_list, InterCompanyJournalEntryLineList
|
17
|
+
|
18
|
+
record_refs :created_from, :currency, :custom_form, :department, :klass, :location, :parent_expense_alloc,
|
19
|
+
:posting_period, :subsidiary, :to_subsidiary
|
20
|
+
|
21
|
+
attr_reader :internal_id
|
22
|
+
attr_accessor :external_id
|
23
|
+
|
24
|
+
def initialize(attributes = {})
|
25
|
+
@internal_id = attributes.delete(:internal_id) || attributes.delete(:@internal_id)
|
26
|
+
@external_id = attributes.delete(:external_id) || attributes.delete(:@external_id)
|
27
|
+
initialize_from_attributes_hash(attributes)
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_record
|
31
|
+
rec = super
|
32
|
+
if rec["#{record_namespace}:customFieldList"]
|
33
|
+
rec["#{record_namespace}:customFieldList!"] = rec.delete("#{record_namespace}:customFieldList")
|
34
|
+
end
|
35
|
+
rec
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.search_class_name
|
39
|
+
"Transaction"
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.search_class_namespace
|
43
|
+
"tranSales"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module NetSuite
|
2
|
+
module Records
|
3
|
+
class InterCompanyJournalEntryLine
|
4
|
+
include Support::Fields
|
5
|
+
include Support::RecordRefs
|
6
|
+
include Support::Records
|
7
|
+
include Namespaces::TranGeneral
|
8
|
+
|
9
|
+
fields :amortization_end_date, :amortization_residual, :amortiz_start_date, :credit, :debit, :eliminate, :end_date, :gross_amt, :memo,
|
10
|
+
:residual, :start_date, :tax1_amt, :tax_rate1
|
11
|
+
field :custom_field_list, CustomFieldList
|
12
|
+
record_refs :account, :department, :entity, :klass, :line_subsidiary, :location, :schedule, :schedule_num, :tax1_acct, :tax_code
|
13
|
+
|
14
|
+
def initialize(attributes = {})
|
15
|
+
initialize_from_attributes_hash(attributes)
|
16
|
+
end
|
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
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module NetSuite
|
2
|
+
module Records
|
3
|
+
class InterCompanyJournalEntryLineList < Support::Sublist
|
4
|
+
include Namespaces::TranGeneral
|
5
|
+
|
6
|
+
attr_accessor :replace_all
|
7
|
+
|
8
|
+
sublist :line, InterCompanyJournalEntryLine
|
9
|
+
|
10
|
+
alias :lines :line
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -20,7 +20,7 @@ module NetSuite
|
|
20
20
|
# }
|
21
21
|
# ]
|
22
22
|
#
|
23
|
-
actions :get, :get_list, :add, :delete, :search, :update, :upsert
|
23
|
+
actions :get, :get_list, :add, :delete, :search, :update, :upsert, :update_list
|
24
24
|
|
25
25
|
fields :auto_lead_time, :auto_preferred_stock_level, :auto_reorder_point, :available_to_partners, :average_cost,
|
26
26
|
:copy_description, :cost, :cost_estimate, :cost_estimate_type, :cost_estimate_units, :cost_units, :costing_method,
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module NetSuite
|
2
|
+
module Records
|
3
|
+
class PriceLevel
|
4
|
+
include Support::Fields
|
5
|
+
include Support::Records
|
6
|
+
include Support::Actions
|
7
|
+
include Support::RecordRefs
|
8
|
+
include Namespaces::ListAcct
|
9
|
+
|
10
|
+
actions :get, :update, :get_list, :add, :delete, :search, :upsert
|
11
|
+
|
12
|
+
# http://www.netsuite.com/help/helpcenter/en_US/srbrowser/Browser2017_1/schema/record/pricelevel.html
|
13
|
+
fields :discountpct, :name, :is_online, :update_existing_prices,
|
14
|
+
:is_inactive
|
15
|
+
|
16
|
+
attr_reader :internal_id
|
17
|
+
attr_accessor :external_id
|
18
|
+
|
19
|
+
def initialize(attributes = {})
|
20
|
+
@internal_id = attributes.delete(:internal_id) || attributes.delete(:@internal_id)
|
21
|
+
@external_id = attributes.delete(:external_id) || attributes.delete(:@external_id)
|
22
|
+
initialize_from_attributes_hash(attributes)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -10,7 +10,7 @@ module NetSuite
|
|
10
10
|
:cost_estimate, :cost_estimate_rate, :cost_estimate_type, :days_before_expiration, :defer_rev_rec, :description,
|
11
11
|
:gift_cert_from, :gift_cert_message, :gift_cert_recipient_email, :gift_cert_recipient_name, :id, :inventory_detail,
|
12
12
|
:is_closed, :is_drop_shipment, :is_taxable, :is_vsoe_bundle, :item_subtype, :item_type, :line, :line_number,
|
13
|
-
:matrix_type, :options, :print_items, :quantity, :quantity_billed, :quantity_received, :quantity_rev_committed,
|
13
|
+
:matrix_type, :options, :order_line, :print_items, :quantity, :quantity_billed, :quantity_received, :quantity_rev_committed,
|
14
14
|
:rate, :rate_schedule, :rev_rec_end_date, :rev_rec_start_date, :tax_rate1, :vsoe_allocation, :vsoe_amount,
|
15
15
|
:vsoe_deferral, :vsoe_delivered, :vsoe_is_estimate, :vsoe_permit_discount, :vsoe_price, :vsoe_sop_group
|
16
16
|
|
@@ -6,11 +6,18 @@ module NetSuite
|
|
6
6
|
include Support::Records
|
7
7
|
include Namespaces::TranSales
|
8
8
|
|
9
|
-
fields :amount, :bin_numbers, :cost_estimate,
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
9
|
+
fields :amount, :bin_numbers, :cost_estimate,
|
10
|
+
:cost_estimate_type, :defer_rev_rec, :description,
|
11
|
+
:expand_item_group, :gift_cert_from, :gift_cert_message,
|
12
|
+
:gift_cert_number, :gift_cert_recipient_email,
|
13
|
+
:gift_cert_recipient_name, :gross_amt, :is_closed,
|
14
|
+
:is_taxable, :line, :order_line, :po_currency, :quantity,
|
15
|
+
:quantity_back_ordered, :quantity_billed, :quantity_committed,
|
16
|
+
:quantity_fulfilled, :rate, :rev_rec_end_date,
|
17
|
+
:rev_rec_start_date, :rev_rec_term_in_months, :serial_numbers,
|
18
|
+
:shipping_cost, :tax1_amt, :tax_rate1, :tax_rate2,
|
19
|
+
:vsoe_allocation, :vsoe_amount, :vsoe_deferral,
|
20
|
+
:vsoe_delivered, :vsoe_permit_discount, :vsoe_price
|
14
21
|
|
15
22
|
field :custom_field_list, CustomFieldList
|
16
23
|
|
@@ -7,7 +7,7 @@ module NetSuite
|
|
7
7
|
include Support::Actions
|
8
8
|
include Namespaces::ListSupport
|
9
9
|
|
10
|
-
actions :get, :get_list, :add, :delete, :update, :upsert
|
10
|
+
actions :get, :get_list, :add, :delete, :update, :upsert, :search
|
11
11
|
|
12
12
|
fields :end_date, :incoming_message, :outgoing_message, :search_solution, :email_form,
|
13
13
|
:internal_only, :title, :case_number, :start_date, :email, :phone, :inbound_email,
|
@@ -42,6 +42,8 @@ module NetSuite
|
|
42
42
|
self.send(:include, NetSuite::Actions::DeleteList::Support)
|
43
43
|
when :update
|
44
44
|
self.send(:include, NetSuite::Actions::Update::Support)
|
45
|
+
when :update_list
|
46
|
+
self.send(:include, NetSuite::Actions::UpdateList::Support)
|
45
47
|
when :initialize
|
46
48
|
self.send(:include, NetSuite::Actions::Initialize::Support)
|
47
49
|
else
|
@@ -17,9 +17,10 @@ module NetSuite
|
|
17
17
|
# <platformCore:pageIndex>1</platformCore:pageIndex>
|
18
18
|
# <platformCore:searchId>WEBSERVICES_738944_SB2_03012013650784545962753432_28d96bd280</platformCore:searchId>
|
19
19
|
|
20
|
-
def initialize(response, result_class)
|
20
|
+
def initialize(response, result_class, credentials)
|
21
21
|
@result_class = result_class
|
22
22
|
@response = response
|
23
|
+
@credentials = credentials
|
23
24
|
|
24
25
|
@total_records = response.body[:total_records].to_i
|
25
26
|
@total_pages = response.body[:total_pages].to_i
|
@@ -98,8 +99,11 @@ module NetSuite
|
|
98
99
|
yield results
|
99
100
|
|
100
101
|
next_search = @result_class.search(
|
101
|
-
|
102
|
-
|
102
|
+
{
|
103
|
+
search_id: @response.body[:search_id],
|
104
|
+
page_index: @response.body[:page_index].to_i + 1
|
105
|
+
},
|
106
|
+
@credentials
|
103
107
|
)
|
104
108
|
|
105
109
|
@results = next_search.results
|
data/lib/netsuite/utilities.rb
CHANGED
@@ -37,6 +37,28 @@ module NetSuite
|
|
37
37
|
server_time_response.body[:get_server_time_response][:get_server_time_result][:server_time]
|
38
38
|
end
|
39
39
|
|
40
|
+
def netsuite_data_center_urls(account_id)
|
41
|
+
data_center_call_response = NetSuite::Configuration.connection({
|
42
|
+
# NOTE force a production WSDL so the sandbox settings are ignored
|
43
|
+
wsdl: 'https://webservices.netsuite.com/wsdl/v2017_2_0/netsuite.wsdl',
|
44
|
+
|
45
|
+
# NOTE don't inherit default namespace settings, it includes the API version
|
46
|
+
namespaces: {
|
47
|
+
'xmlns:platformCore' => "urn:core_2017_2.platform.webservices.netsuite.com"
|
48
|
+
},
|
49
|
+
|
50
|
+
soap_header: {}
|
51
|
+
}).call(:get_data_center_urls, message: {
|
52
|
+
'platformMsgs:account' => account_id
|
53
|
+
})
|
54
|
+
|
55
|
+
if data_center_call_response.success?
|
56
|
+
data_center_call_response.body[:get_data_center_urls_response][:get_data_center_urls_result][:data_center_urls]
|
57
|
+
else
|
58
|
+
false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
40
62
|
def backoff(options = {})
|
41
63
|
# TODO the default backoff attempts should be customizable the global config
|
42
64
|
options[:attempts] ||= 8
|
@@ -86,9 +108,13 @@ module NetSuite
|
|
86
108
|
!e.message.include?('com.netledger.common.exceptions.NLDatabaseOfflineException') &&
|
87
109
|
!e.message.include?('com.netledger.database.NLConnectionUtil$NoCompanyDbsOnlineException') &&
|
88
110
|
!e.message.include?('com.netledger.cache.CacheUnavailableException') &&
|
111
|
+
!e.message.include?('java.lang.IllegalStateException') &&
|
89
112
|
!e.message.include?('An unexpected error occurred.') &&
|
113
|
+
!e.message.include?('An unexpected error has occurred. Technical Support has been alerted to this problem.') &&
|
90
114
|
!e.message.include?('Session invalidation is in progress with different thread') &&
|
91
115
|
!e.message.include?('SuiteTalk concurrent request limit exceeded. Request blocked.') &&
|
116
|
+
# maintenance is the new outage: this message is being used for intermittent errors
|
117
|
+
!e.message.include?('The account you are trying to access is currently unavailable while we undergo our regularly scheduled maintenance.') &&
|
92
118
|
!e.message.include?('The Connection Pool is not intialized.') &&
|
93
119
|
# it looks like NetSuite mispelled their error message...
|
94
120
|
!e.message.include?('The Connection Pool is not intiialized.')
|
data/lib/netsuite/version.rb
CHANGED
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NetSuite::Actions::UpdateList do
|
4
|
+
before { savon.mock! }
|
5
|
+
after { savon.unmock! }
|
6
|
+
|
7
|
+
context 'Items' do
|
8
|
+
context 'one item' do
|
9
|
+
let(:item) do
|
10
|
+
[
|
11
|
+
NetSuite::Records::InventoryItem.new(internal_id: '624113', item_id: 'Target', upccode: 'Target')
|
12
|
+
]
|
13
|
+
end
|
14
|
+
|
15
|
+
before do
|
16
|
+
savon.expects(:update_list).with(:message =>
|
17
|
+
{
|
18
|
+
'record' => [{
|
19
|
+
'listAcct:itemId' => 'Target',
|
20
|
+
'@xsi:type' => 'listAcct:InventoryItem',
|
21
|
+
'@internalId' => '624113'
|
22
|
+
}]
|
23
|
+
}).returns(File.read('spec/support/fixtures/update_list/update_list_one_item.xml'))
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'makes a valid request to the NetSuite API' do
|
27
|
+
NetSuite::Actions::UpdateList.call(item)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns a valid Response object' do
|
31
|
+
response = NetSuite::Actions::UpdateList.call(item)
|
32
|
+
expect(response).to be_kind_of(NetSuite::Response)
|
33
|
+
expect(response).to be_success
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'two items' do
|
38
|
+
let(:items) do
|
39
|
+
[
|
40
|
+
NetSuite::Records::InventoryItem.new(internal_id: '624172', item_id: 'Shutter Fly', upccode: 'Shutter Fly, Inc.'),
|
41
|
+
NetSuite::Records::InventoryItem.new(internal_id: '624113', item_id: 'Target', upccode: 'Target')
|
42
|
+
]
|
43
|
+
end
|
44
|
+
|
45
|
+
before do
|
46
|
+
savon.expects(:update_list).with(:message =>
|
47
|
+
{
|
48
|
+
'record' => [{
|
49
|
+
'listAcct:itemId' => 'Shutter Fly',
|
50
|
+
'@xsi:type' => 'listAcct:InventoryItem',
|
51
|
+
'@internalId' => '624172'
|
52
|
+
},
|
53
|
+
{
|
54
|
+
'listAcct:itemId' => 'Target',
|
55
|
+
'@xsi:type' => 'listAcct:InventoryItem',
|
56
|
+
'@internalId' => '624113'
|
57
|
+
}
|
58
|
+
]
|
59
|
+
}).returns(File.read('spec/support/fixtures/update_list/update_list_items.xml'))
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'makes a valid request to the NetSuite API' do
|
63
|
+
NetSuite::Actions::UpdateList.call(items)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'returns a valid Response object' do
|
67
|
+
response = NetSuite::Actions::UpdateList.call(items)
|
68
|
+
expect(response).to be_kind_of(NetSuite::Response)
|
69
|
+
expect(response).to be_success
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'with errors' do
|
75
|
+
let(:items) do
|
76
|
+
[
|
77
|
+
NetSuite::Records::InventoryItem.new(internal_id: '624172-bad', item_id: 'Shutter Fly', upccode: 'Shutter Fly, Inc.'),
|
78
|
+
NetSuite::Records::InventoryItem.new(internal_id: '624113-bad', item_id: 'Target', upccode: 'Target')
|
79
|
+
]
|
80
|
+
end
|
81
|
+
|
82
|
+
before do
|
83
|
+
savon.expects(:update_list).with(:message =>
|
84
|
+
{
|
85
|
+
'record' => [{
|
86
|
+
'listAcct:itemId' => 'Shutter Fly',
|
87
|
+
'@xsi:type' => 'listAcct:InventoryItem',
|
88
|
+
'@internalId' => '624172-bad'
|
89
|
+
},
|
90
|
+
{
|
91
|
+
'listAcct:itemId' => 'Target',
|
92
|
+
'@xsi:type' => 'listAcct:InventoryItem',
|
93
|
+
'@internalId' => '624113-bad'
|
94
|
+
}
|
95
|
+
]
|
96
|
+
}).returns(File.read('spec/support/fixtures/update_list/update_list_with_errors.xml'))
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'constructs error objects' do
|
100
|
+
response = NetSuite::Actions::UpdateList.call(items)
|
101
|
+
expect(response.errors.keys).to match_array(['624172', '624113'])
|
102
|
+
expect(response.errors['624172'].first.code).to eq('USER_ERROR')
|
103
|
+
expect(response.errors['624172'].first.message).to eq('Please enter value(s) for: ItemId')
|
104
|
+
expect(response.errors['624172'].first.type).to eq('ERROR')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|