Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CD-4491] Adding async add list action #43

Merged
merged 1 commit into from
Mar 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/netsuite.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ module Support

module Actions
autoload :Add, 'netsuite/actions/add'
autoload :AsyncAddList, 'netsuite/actions/async_add_list'
autoload :Attach, 'netsuite/actions/attach'
autoload :Delete, 'netsuite/actions/delete'
autoload :DeleteList, 'netsuite/actions/delete_list'
Expand Down
122 changes: 122 additions & 0 deletions lib/netsuite/actions/async_add_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# https://system.netsuite.com/help/helpcenter/en_US/Output/Help/SuiteCloudCustomizationScriptingWebServices/SuiteTalkWebServices/asyncAddList.html
module NetSuite
module Actions
class AsyncAddList
include Support::Requests

def initialize(*objects)
@objects = objects
end

private

def request(credentials={})
NetSuite::Configuration.connection(
{}, credentials
).call(:async_add_list, message: request_body)
end

# <soap:Body>
# <platformMsgs:asyncAddList>
# <platformMsgs:record xsi:type="listRel:Customer">
# <listRel:entityId>Shutter Fly</listRel:entityId>
# <listRel:companyName>Shutter Fly, Inc</listRel:companyName>
# </platformMsgs:record>
# <platformMsgs:record xsi:type="listRel:Customer">
# <listRel:entityId>Target</listRel:entityId>
# <listRel:companyName>Target</listRel:companyName>
# </platformMsgs:record>
# </platformMsgs:asyncAddList>
# </soap:Body>
def request_body
attrs = @objects.map do |o|
hash = o.to_record.merge({
'@xsi:type' => o.record_type
})

if o.respond_to?(:internal_id) && o.internal_id
hash['@internalId'] = o.internal_id
end

if o.respond_to?(:external_id) && o.external_id
hash['@externalId'] = o.external_id
end

hash
end

{ 'record' => attrs }
end

def response_hash
binding.pry
@response_hash ||= Array[@response.body[:async_add_list_response][:async_status_result]]
end

def response_body
@response_body ||= response_hash.map { |h| h[:job_id] }
end

def response_errors
binding.pry
if response_hash[0].any? { |h| h[:status] && h[:status][:status_detail] }
@response_errors ||= errors
end
end

def errors
errors = response_hash.select { |h| h[:status] && h[:status][:status_detail] }.map do |obj|
error_obj = obj[:status][:status_detail]
error_obj = [error_obj] if error_obj.class == Hash
errors = error_obj.map do |error|
NetSuite::Error.new(error)
end

[obj[:base_ref][:@external_id], errors]
end
Hash[errors]
end

def success?
#binding.pry
response_hash[0][:job_id]
end

module Support

def self.included(base)
base.extend(ClassMethods)
end

module ClassMethods
def async_add_list(records, credentials = {})
netsuite_records = records.map do |r|
if r.kind_of?(self)
r
else
self.new(r)
end
end

response = NetSuite::Actions::AsyncAddList.call(netsuite_records, credentials)

if response.success?
response.body.map do |attr|
record = netsuite_records.find do |r|
r.external_id == attr[:@external_id]
end

record.instance_variable_set('@internal_id', attr[:@internal_id])
end

netsuite_records

else
false
end
end
end
end
end
end
end
2 changes: 1 addition & 1 deletion lib/netsuite/records/journal_entry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class JournalEntry
include Support::Actions
include Namespaces::TranGeneral

actions :get, :get_list, :add, :delete, :search, :upsert, :update
actions :get, :get_list, :add, :async_add_list, :delete, :search, :upsert, :update

fields :approved, :created_date, :exchange_rate, :last_modified_date, :memo, :reversal_date, :reversal_defer, :reversal_entry,
:tran_date, :tran_id, :is_book_specific
Expand Down
2 changes: 2 additions & 0 deletions lib/netsuite/support/actions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ def action(name)
self.send(:include, NetSuite::Actions::Initialize::Support)
when :attach
self.send(:include, NetSuite::Actions::Attach::Support)
when :async_add_list
self.send(:include, NetSuite::Actions::AsyncAddList::Support)
else
raise "Unknown action: #{name.inspect}"
end
Expand Down
113 changes: 113 additions & 0 deletions spec/netsuite/actions/async_add_list_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
require 'spec_helper'
require 'lib/netsuite/actions/async_add_list'

describe NetSuite::Actions::AsyncAddList do
before { savon.mock! }
after { savon.unmock! }

context 'Customers' do
context 'one customer' do
let(:customers) do
[
NetSuite::Records::Customer.new(external_id: 'ext2', entity_id: 'Target', company_name: 'Target')
]
end

before do
savon.expects(:async_add_list).with(:message =>
{
'record' => [{
'listRel:entityId' => 'Target',
'listRel:companyName' => 'Target',
'@xsi:type' => 'listRel:Customer',
'@externalId' => 'ext2'
}]
}).returns(File.read('spec/support/fixtures/async_add_list/async_add_list_response.xml'))
end

it 'makes a valid request to the NetSuite API' do
NetSuite::Actions::AsyncAddList.call(customers)
end

it 'returns a valid Response object' do
response = NetSuite::Actions::AsyncAddList.call(customers)
expect(response).to be_kind_of(NetSuite::Response)
expect(response).to be_success
end
end

context 'two customers' do
let(:customers) do
[
NetSuite::Records::Customer.new(external_id: 'ext1', entity_id: 'Shutter Fly', company_name: 'Shutter Fly, Inc.'),
NetSuite::Records::Customer.new(external_id: 'ext2', entity_id: 'Target', company_name: 'Target')
]
end

before do
savon.expects(:async_add_list).with(:message =>
{
'record' => [{
'listRel:entityId' => 'Shutter Fly',
'listRel:companyName' => 'Shutter Fly, Inc.',
'@xsi:type' => 'listRel:Customer',
'@externalId' => 'ext1'
},
{
'listRel:entityId' => 'Target',
'listRel:companyName' => 'Target',
'@xsi:type' => 'listRel:Customer',
'@externalId' => 'ext2'
}
]
}).returns(File.read('spec/support/fixtures/async_add_list/async_add_list_response.xml'))
end

it 'makes a valid request to the NetSuite API' do
NetSuite::Actions::AsyncAddList.call(customers)
end

it 'returns a valid Response object' do
response = NetSuite::Actions::AsyncAddList.call(customers)
expect(response).to be_kind_of(NetSuite::Response)
expect(response).to be_success
end
end
end

context 'with errors' do
let(:customers) do
[
NetSuite::Records::Customer.new(external_id: 'ext1-bad', entity_id: 'Shutter Fly', company_name: 'Shutter Fly, Inc.'),
NetSuite::Records::Customer.new(external_id: 'ext2-bad', entity_id: 'Target', company_name: 'Target')
]
end

# before do
# savon.expects(:async_add_list).with(:message =>
# {
# 'record' => [{
# 'listRel:entityId' => 'Shutter Fly',
# 'listRel:companyName' => 'Shutter Fly, Inc.',
# '@xsi:type' => 'listRel:Customer',
# '@externalId' => 'ext1-bad'
# },
# {
# 'listRel:entityId' => 'Target',
# 'listRel:companyName' => 'Target',
# '@xsi:type' => 'listRel:Customer',
# '@externalId' => 'ext2-bad'
# }
# ]
# }).returns(File.read('spec/support/fixtures/upsert_list/upsert_list_with_errors.xml'))
# end

# it 'constructs error objects' do
# response = NetSuite::Actions::AsyncAddList.call(customers)
# expect(response.errors.keys).to match_array(['ext1', 'ext2'])
# expect(response.errors['ext1'].first.code).to eq('USER_ERROR')
# expect(response.errors['ext1'].first.message).to eq('Please enter value(s) for: Item')
# expect(response.errors['ext1'].first.type).to eq('ERROR')
# end
end
end
17 changes: 17 additions & 0 deletions spec/support/fixtures/async_add_list/async_add_list_response.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<platformMsgs:documentInfo xmlns:platformMsgs="urn:messages_2014_1.platform.webservices.netsuite.com">
<platformMsgs:nsId>WEBSERVICES_3392464_1220201115821392011296470399_67055c545d0</platformMsgs:nsId>
</platformMsgs:documentInfo>
</soapenv:Header>
<soapenv:Body>
<asyncAddListResponse xmlns="urn:messages_2017_1.platform.webservices.netsuite.com">
<asyncStatusResult xmlns="urn:core_2017_1.platform.webservices.netsuite.com">
<jobId>ASYNCWEBSERVICES_563214_053120061943428686160042948_4bee0685</jobId>
<status>pending</status>
<percentCompleted>0.0</percentCompleted>
<estRemainingDuration>0.0</estRemainingDuration>
</asyncStatusResult>
</asyncAddListResponse>
</soapenv:Body>