From 0606ad33c4fe947005e6cd56c3756cb28944011e Mon Sep 17 00:00:00 2001 From: Jordan Dedels Date: Wed, 24 Feb 2016 13:03:20 -0700 Subject: [PATCH 1/2] Add folder record ref field --- lib/netsuite/records/file.rb | 2 +- spec/netsuite/records/file_spec.rb | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 spec/netsuite/records/file_spec.rb diff --git a/lib/netsuite/records/file.rb b/lib/netsuite/records/file.rb index a531f5cb1..40fbef22b 100644 --- a/lib/netsuite/records/file.rb +++ b/lib/netsuite/records/file.rb @@ -11,7 +11,7 @@ class File < NetSuite::Support::Base fields :content, :description, :name, :media_type_name, :file_type, :text_file_encoding - record_refs :klass + record_refs :folder, :klass read_only_fields :url diff --git a/spec/netsuite/records/file_spec.rb b/spec/netsuite/records/file_spec.rb new file mode 100644 index 000000000..4d943d387 --- /dev/null +++ b/spec/netsuite/records/file_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe NetSuite::Records::File do + let(:file) { NetSuite::Records::File.new } + + it 'has all the right record refs' do + [:folder, :klass].each do |record_ref| + expect(file).to have_record_ref(record_ref) + end + end +end From 20cb89fa49ba59791529ab731c0a4441b3f2af73 Mon Sep 17 00:00:00 2001 From: Jordan Dedels Date: Thu, 25 Feb 2016 15:04:35 -0700 Subject: [PATCH 2/2] Add support for attaching Files --- lib/netsuite.rb | 1 + lib/netsuite/actions/attach_file.rb | 87 +++++++++++++++++++ lib/netsuite/records/invoice.rb | 2 +- lib/netsuite/support/actions.rb | 2 + lib/netsuite/support/records.rb | 10 ++- spec/netsuite/actions/attach_file_spec.rb | 59 +++++++++++++ spec/netsuite/records/invoice_spec.rb | 29 +++++++ .../attach/attach_file_to_invoice.xml | 16 ++++ .../attach/attach_file_to_invoice_error.xml | 20 +++++ 9 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 lib/netsuite/actions/attach_file.rb create mode 100644 spec/netsuite/actions/attach_file_spec.rb create mode 100644 spec/support/fixtures/attach/attach_file_to_invoice.xml create mode 100644 spec/support/fixtures/attach/attach_file_to_invoice_error.xml diff --git a/lib/netsuite.rb b/lib/netsuite.rb index 85ccee065..679006ddb 100644 --- a/lib/netsuite.rb +++ b/lib/netsuite.rb @@ -46,6 +46,7 @@ module Support module Actions autoload :Add, 'netsuite/actions/add' + autoload :AttachFile, 'netsuite/actions/attach_file' autoload :Delete, 'netsuite/actions/delete' autoload :DeleteList, 'netsuite/actions/delete_list' autoload :Get, 'netsuite/actions/get' diff --git a/lib/netsuite/actions/attach_file.rb b/lib/netsuite/actions/attach_file.rb new file mode 100644 index 000000000..e25720c36 --- /dev/null +++ b/lib/netsuite/actions/attach_file.rb @@ -0,0 +1,87 @@ +module NetSuite + module Actions + class AttachFile + include Support::Requests + + def initialize(object, file) + @object = object + @file = file + end + + private + + def request(credentials = {}) + NetSuite::Configuration.connection({}, credentials).call(:attach, :message => request_body) + end + + # + # + # + # + # + # + # + # + # + + def request_body + { + 'platformCore:attachReference' => { + '@xsi:type' => 'platformCore:AttachBasicReference', + 'platformCore:attachTo' => { + '@internalId' => @object.internal_id, + '@type' => @object.type, + '@xsi:type' => 'platformCore:RecordRef' + }, + 'platformCore:attachedRecord' => { + '@internalId' => @file.internal_id, + '@type' => 'file', + '@xsi:type' => 'platformCore:RecordRef' + } + } + } + end + + def success? + @success ||= response_hash[:status][:@is_success] == 'true' + end + + def response_body + @response_body ||= response_hash[:base_ref] + end + + def response_errors + if response_hash[:status] && response_hash[:status][:status_detail] + @response_errors ||= errors + end + end + + def response_hash + @response_hash ||= @response.to_hash[:attach_response][:write_response] + end + + def errors + error_obj = response_hash[:status][:status_detail] + error_obj = [error_obj] if error_obj.class == Hash + error_obj.map do |error| + NetSuite::Error.new(error) + end + end + + module Support + def attach_file(file, credentials = {}) + response = NetSuite::Actions::AttachFile.call([self, file], credentials) + + @errors = response.errors + + if response.success? + @internal_id = response.body[:@internal_id] + true + else + false + end + end + end + end + end +end diff --git a/lib/netsuite/records/invoice.rb b/lib/netsuite/records/invoice.rb index ca7c30fbd..c5628f489 100644 --- a/lib/netsuite/records/invoice.rb +++ b/lib/netsuite/records/invoice.rb @@ -9,7 +9,7 @@ class Invoice # https://system.netsuite.com/help/helpcenter/en_US/srbrowser/Browser2014_1/schema/record/invoice.html?mode=package - actions :get, :get_list, :initialize, :add, :update, :delete, :upsert, :search + actions :attach_file, :get, :get_list, :initialize, :add, :update, :delete, :upsert, :search fields :balance, :bill_address, :billing_schedule, :contrib_pct, :created_date, :currency_name, :custom_field_list, diff --git a/lib/netsuite/support/actions.rb b/lib/netsuite/support/actions.rb index bf1b7d1f8..8ebfedf36 100644 --- a/lib/netsuite/support/actions.rb +++ b/lib/netsuite/support/actions.rb @@ -18,6 +18,8 @@ def actions(*args) def action(name) case name + when :attach_file + self.send(:include, NetSuite::Actions::AttachFile::Support) when :get self.send(:include, NetSuite::Actions::Get::Support) when :get_all diff --git a/lib/netsuite/support/records.rb b/lib/netsuite/support/records.rb index 2291ecf21..c23a8312a 100644 --- a/lib/netsuite/support/records.rb +++ b/lib/netsuite/support/records.rb @@ -49,7 +49,15 @@ def to_attributes!(hash, kname, v) end def record_type - "#{record_namespace}:#{self.class.to_s.split('::').last}" + "#{record_namespace}:#{record_type_without_namespace}" + end + + def type + record_type_without_namespace.downcase + end + + def record_type_without_namespace + "#{self.class.to_s.split('::').last}" end def refresh(credentials = {}) diff --git a/spec/netsuite/actions/attach_file_spec.rb b/spec/netsuite/actions/attach_file_spec.rb new file mode 100644 index 000000000..abdcc9785 --- /dev/null +++ b/spec/netsuite/actions/attach_file_spec.rb @@ -0,0 +1,59 @@ +require 'spec_helper' + +describe NetSuite::Actions::AttachFile do + before(:all) { savon.mock! } + after(:all) { savon.unmock! } + + let(:invoice) { NetSuite::Records::Invoice.new(internal_id: 999) } + let(:file) { double('file', internal_id: 111) } + let(:message) do + { + 'platformCore:attachReference' => { + '@xsi:type' => 'platformCore:AttachBasicReference', + 'platformCore:attachTo' => { + '@internalId' => invoice.internal_id, + '@type' => invoice.type, + '@xsi:type' => 'platformCore:RecordRef' + }, + 'platformCore:attachedRecord' => { + '@internalId' => file.internal_id, + '@type' => 'file', + '@xsi:type' => 'platformCore:RecordRef' + } + } + } + end + + before do + savon.expects(:attach).with(:message => message).returns(envelope) + end + + context 'when successful' do + let(:envelope) { File.read('spec/support/fixtures/attach/attach_file_to_invoice.xml') } + + it 'returns a valid Response object' do + response = NetSuite::Actions::AttachFile.call([invoice, file]) + expect(response).to be_kind_of(NetSuite::Response) + expect(response).to be_success + end + end + + context 'when not successful' do + let(:envelope) { File.read('spec/support/fixtures/attach/attach_file_to_invoice_error.xml') } + + it 'provides an error method on the object with details about the error' do + invoice.attach_file(file) + error = invoice.errors.first + + expect(error).to be_kind_of(NetSuite::Error) + expect(error.type).to eq('ERROR') + expect(error.code).to eq('INVALID') + expect(error.message).to eq('Invalid request.') + end + + it 'provides an error method on the response' do + response = NetSuite::Actions::AttachFile.call([invoice, file]) + expect(response.errors.first).to be_kind_of(NetSuite::Error) + end + end +end diff --git a/spec/netsuite/records/invoice_spec.rb b/spec/netsuite/records/invoice_spec.rb index 41701e205..182689eaf 100644 --- a/spec/netsuite/records/invoice_spec.rb +++ b/spec/netsuite/records/invoice_spec.rb @@ -198,6 +198,35 @@ end end + describe '#attach_file' do + let(:test_data) { { :email => 'test@example.com', :fax => '1234567890' } } + let(:file) { double('file') } + + context 'when the response is successful' do + let(:response) { NetSuite::Response.new(:success => true, :body => { :internal_id => '1' }) } + + it 'returns true' do + invoice = NetSuite::Records::Invoice.new(test_data) + expect(NetSuite::Actions::AttachFile).to receive(:call). + with([invoice, file], {}). + and_return(response) + expect(invoice.attach_file(file)).to be_truthy + end + end + + context 'when the response is unsuccessful' do + let(:response) { NetSuite::Response.new(:success => false, :body => {}) } + + it 'returns false' do + invoice = NetSuite::Records::Invoice.new(test_data) + expect(NetSuite::Actions::AttachFile).to receive(:call). + with([invoice, file], {}). + and_return(response) + expect(invoice.attach_file(file)).to be_falsey + end + end + end + describe '#delete' do context 'when the response is successful' do let(:response) { NetSuite::Response.new(:success => true, :body => { :internal_id => '1' }) } diff --git a/spec/support/fixtures/attach/attach_file_to_invoice.xml b/spec/support/fixtures/attach/attach_file_to_invoice.xml new file mode 100644 index 000000000..c1323db87 --- /dev/null +++ b/spec/support/fixtures/attach/attach_file_to_invoice.xml @@ -0,0 +1,16 @@ + + + + + WEBSERVICES_3392464_1220201115821392011296470399_67055c545d0 + + + + + + + + + + + diff --git a/spec/support/fixtures/attach/attach_file_to_invoice_error.xml b/spec/support/fixtures/attach/attach_file_to_invoice_error.xml new file mode 100644 index 000000000..4be35e6ef --- /dev/null +++ b/spec/support/fixtures/attach/attach_file_to_invoice_error.xml @@ -0,0 +1,20 @@ + + + + + WEBSERVICES_3392464_1220201115821392011296470399_67055c545d0 + + + + + + + + INVALID + Invalid request. + + + + + +