netsuite 0.0.3 → 0.0.4
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.
- data/lib/netsuite.rb +10 -3
- data/lib/netsuite/actions/add.rb +1 -1
- data/lib/netsuite/actions/get.rb +1 -1
- data/lib/netsuite/actions/initialize.rb +55 -0
- data/lib/netsuite/entities/customer.rb +41 -0
- data/lib/netsuite/field_support.rb +54 -0
- data/lib/netsuite/{actions/support.rb → savon_support.rb} +1 -1
- data/lib/netsuite/transactions/invoice.rb +38 -0
- data/lib/netsuite/version.rb +1 -1
- data/spec/netsuite/actions/add_spec.rb +1 -0
- data/spec/netsuite/actions/initialize_spec.rb +33 -0
- data/spec/netsuite/entities/customer_spec.rb +83 -0
- data/spec/netsuite/field_support_spec.rb +52 -0
- data/spec/netsuite/{actions/support_spec.rb → savon_support_spec.rb} +2 -2
- data/spec/netsuite/transactions/invoice_spec.rb +53 -0
- data/spec/support/field_matcher.rb +19 -0
- data/spec/support/fixtures/initialize/initialize_invoice_from_customer.xml +69 -0
- metadata +23 -10
- data/lib/netsuite/models/customer.rb +0 -31
- data/spec/netsuite/models/customer_spec.rb +0 -74
data/lib/netsuite.rb
CHANGED
@@ -1,15 +1,22 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
1
3
|
require 'netsuite/configuration'
|
2
4
|
require 'netsuite/errors'
|
3
5
|
require 'netsuite/response'
|
4
6
|
require 'netsuite/version'
|
7
|
+
require 'netsuite/field_support'
|
8
|
+
require 'netsuite/savon_support'
|
5
9
|
|
6
10
|
# ACTIONS
|
7
|
-
require 'netsuite/actions/support'
|
8
11
|
require 'netsuite/actions/add'
|
9
12
|
require 'netsuite/actions/get'
|
13
|
+
require 'netsuite/actions/initialize'
|
14
|
+
|
15
|
+
# ENTITIES
|
16
|
+
require 'netsuite/entities/customer'
|
10
17
|
|
11
|
-
#
|
12
|
-
require 'netsuite/
|
18
|
+
# TRANSACTIONS
|
19
|
+
require 'netsuite/transactions/invoice'
|
13
20
|
|
14
21
|
module NetSuite
|
15
22
|
|
data/lib/netsuite/actions/add.rb
CHANGED
data/lib/netsuite/actions/get.rb
CHANGED
@@ -0,0 +1,55 @@
|
|
1
|
+
module NetSuite
|
2
|
+
module Actions
|
3
|
+
class Initialize
|
4
|
+
include SavonSupport
|
5
|
+
|
6
|
+
def initialize(obj)
|
7
|
+
@obj = obj
|
8
|
+
end
|
9
|
+
|
10
|
+
def request
|
11
|
+
connection.request :platformMsgs, :initialize do
|
12
|
+
soap.namespaces['xmlns:platformMsgs'] = 'urn:messages_2011_2.platform.webservices.netsuite.com'
|
13
|
+
soap.namespaces['xmlns:platformCore'] = 'urn:core_2011_2.platform.webservices.netsuite.com'
|
14
|
+
soap.namespaces['xmlns:platformCoreTyp'] = 'urn:types.core_2011_2.platform.webservices.netsuite.com'
|
15
|
+
soap.header = auth_header
|
16
|
+
soap.body = request_body
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# <platformMsgs:initializeRecord>
|
21
|
+
# <platformCore:type>invoice</platformCore:type>
|
22
|
+
# <platformCore:reference internalId="1513" type="salesOrder">
|
23
|
+
# <platformCore:name>1511</platformCore:name>
|
24
|
+
# </platformCore:reference>
|
25
|
+
# </platformMsgs:initializeRecord>
|
26
|
+
def request_body
|
27
|
+
{
|
28
|
+
'platformMsgs:initializeRecord' => {
|
29
|
+
'platformCore:type' => 'invoice',
|
30
|
+
'platformCore:reference' => {},
|
31
|
+
:attributes! => {
|
32
|
+
'platformCore:reference' => {
|
33
|
+
'internalId' => @obj.internal_id,
|
34
|
+
:type => @obj.class.to_s.split('::').last.lower_camelcase
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def response_hash
|
42
|
+
@response_hash ||= @response.to_hash[:initialize_response][:read_response]
|
43
|
+
end
|
44
|
+
|
45
|
+
def success?
|
46
|
+
@success ||= response_hash[:status][:@is_success] == 'true'
|
47
|
+
end
|
48
|
+
|
49
|
+
def response_body
|
50
|
+
@response_body ||= response_hash[:record]
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module NetSuite
|
2
|
+
module Entities
|
3
|
+
class Customer
|
4
|
+
include FieldSupport
|
5
|
+
|
6
|
+
fields :internal_id, :external_id, :custom_form, :entity_id, :alt_name, :is_person, :phonetic_name,
|
7
|
+
:salutation, :first_name, :middle_name, :last_name, :company_name, :entity_status, :parent, :phone,
|
8
|
+
:fax, :email, :url, :default_address, :is_inactive, :category, :title, :print_on_check_as, :alt_phone,
|
9
|
+
:home_phone, :mobile_phone, :alt_email, :language, :comments, :date_created, :image, :email_preference,
|
10
|
+
:subsidiary, :representing_subsidiary, :sales_rep, :territory, :contrib_pct, :partner, :sales_group,
|
11
|
+
:vat_reg_number, :account_number, :tax_exempt, :terms, :credit_limit, :credit_hold_override, :balance,
|
12
|
+
:overdue_balance, :days_overdue, :unbilled_orders, :consol_unbilled_orders, :consol_overdue_balance,
|
13
|
+
:consol_deposit_balance, :consol_balance, :consol_aging, :consol_days_overdue, :price_level, :currency,
|
14
|
+
:pref_cc_processor, :deposit_balance, :ship_complete, :taxable, :tax_item, :resale_number, :aging,
|
15
|
+
:start_date, :end_date, :reminder_days, :shipping_item, :third_party_acct, :third_party_zipcode,
|
16
|
+
:third_party_country, :give_access, :estimated_budget, :access_role, :send_email, :password, :password_2,
|
17
|
+
:require_pwd_change, :campaign_category, :lead_source, :web_lead, :referrer, :keywords, :click_stream,
|
18
|
+
:last_page_visited, :visits, :first_visit, :last_visit, :bill_pay, :opening_balance, :last_modified,
|
19
|
+
:opening_balance_date, :opening_balance_account, :stage, :email_transactions, :print_transactions,
|
20
|
+
:fax_transactions, :sync_partner_teams, :is_budget_approved, :global_subscription_status, :sales_readiness,
|
21
|
+
:sales_team_list, :buying_reason, :download_list, :buying_time_frame, :addressbook_list, :subscriptions_list,
|
22
|
+
:contact_roles_list, :currency_list, :credit_cards_list, :partners_list, :group_pricing_list,
|
23
|
+
:item_pricing_list, :custom_field_list
|
24
|
+
|
25
|
+
def self.get(id)
|
26
|
+
response = NetSuite::Actions::Get.call(id)
|
27
|
+
if response.success?
|
28
|
+
new(response.body)
|
29
|
+
else
|
30
|
+
raise RecordNotFound, "#{self} with ID=#{id} could not be found"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def add
|
35
|
+
response = NetSuite::Actions::Add.call(@attributes)
|
36
|
+
response.success?
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module NetSuite
|
2
|
+
module FieldSupport
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.send(:extend, ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(attributes = {})
|
9
|
+
attributes = attributes.inject({}) do |hash, (k,v)|
|
10
|
+
if k.to_s.match(/@.+/)
|
11
|
+
hash.store(k.to_s.delete('@').to_sym, attributes[k])
|
12
|
+
else
|
13
|
+
hash.store(k,v)
|
14
|
+
end
|
15
|
+
hash
|
16
|
+
end
|
17
|
+
Hash[attributes.select { |k,v| self.class.fields.include?(k) }].each do |k,v|
|
18
|
+
send("#{k}=", v)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def attributes
|
23
|
+
@attributes ||= {}
|
24
|
+
end
|
25
|
+
private :attributes
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
|
29
|
+
def fields(*args)
|
30
|
+
if args.empty?
|
31
|
+
@fields
|
32
|
+
else
|
33
|
+
args.each do |arg|
|
34
|
+
field arg
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def field(name)
|
40
|
+
name_sym = name.to_sym
|
41
|
+
(@fields ||= Set.new) << name_sym
|
42
|
+
define_method(name_sym) do
|
43
|
+
attributes[name_sym]
|
44
|
+
end
|
45
|
+
|
46
|
+
define_method("#{name_sym}=") do |value|
|
47
|
+
attributes[name_sym] = value
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module NetSuite
|
2
|
+
module Transactions
|
3
|
+
class Invoice
|
4
|
+
include FieldSupport
|
5
|
+
|
6
|
+
fields :internal_id, :external_id, :created_date, :last_modified_date, :custom_form, :entity, :tran_date, :tran_id,
|
7
|
+
:source, :created_from, :posting_period, :opportunity, :department, :klass, :terms, :location, :subsidiary, :due_date,
|
8
|
+
:discount_date, :discount_amount, :sales_rep, :contrib_pct, :partner, :lead_source, :start_date, :end_date,
|
9
|
+
:other_ref_name, :memo, :sales_effective_date, :exclude_commission, :total_cost_estimate, :est_gross_profit,
|
10
|
+
:est_gross_profit_percent, :rev_rec_schedule, :rev_rec_start_date, :rev_rec_end_date, :amount_paid, :amount_remaining,
|
11
|
+
:balance, :account, :on_credit_hold, :exchange_rate, :currency_name, :promo_code, :discount_item, :discount_rate,
|
12
|
+
:is_taxable, :tax_item, :tax_rate, :to_be_printed, :to_be_emailed, :to_be_faxed, :fax, :message_sel, :message,
|
13
|
+
:transaction_bill_address, :bill_address_list, :bill_address, :transaction_ship_address, :ship_address_list,
|
14
|
+
:ship_address, :fob, :ship_date, :ship_method, :shipping_cost, :shipping_tax_1_rate, :shipping_tax_2_rate,
|
15
|
+
:shipping_tax_code, :handling_tax_code, :handling_tax_1_rate, :handling_cost, :handling_tax_2_rate, :tracking_numbers,
|
16
|
+
:linked_tracking_numbers, :sales_group, :sub_total, :revenue_status, :recognized_revenue, :deferred_revenue,
|
17
|
+
:rev_rec_on_rev_commitment, :sync_sales_teams, :discount_total, :tax_total, :alt_shipping_cost, :alt_handling_cost,
|
18
|
+
:total, :status, :job, :billing_schedule, :email, :tax_2_total, :vat_reg_num, :exp_cost_discount, :item_cost_discount,
|
19
|
+
:time_discount, :exp_cost_disc_rate, :item_cost_disc_rate, :time_disc_rate, :exp_cost_disc_amount, :exp_cost_tax_rate_1,
|
20
|
+
:exp_cost_tax_rate_2, :item_cost_disc_amount, :exp_cost_tax_code, :exp_cost_disc_tax_1_amt, :item_cost_tax_rate_1,
|
21
|
+
:time_disc_amount, :item_cost_tax_code, :exp_cost_disc_taxable, :item_cost_disc_taxable, :item_cost_tax_rate_2,
|
22
|
+
:item_cost_disc_tax_1_amt, :item_cost_disc_print, :time_disc_taxable, :time_tax_rate_1, :exp_cost_disc_print,
|
23
|
+
:time_tax_code, :time_disc_print, :gift_cert_applied, :time_disc_tax_1_amt, :tran_is_vsoe_bundle, :time_tax_rate_2,
|
24
|
+
:vsoe_auto_calc, :sync_partner_teams, :sales_team_list, :partners_list, :item_list, :item_cost_list,
|
25
|
+
:gift_cert_redemption_list, :exp_cost_list, :time_list, :ship_group_list, :custom_field_list
|
26
|
+
|
27
|
+
def self.initialize(customer)
|
28
|
+
response = NetSuite::Actions::Initialize.call(customer)
|
29
|
+
if response.success?
|
30
|
+
new(response.body)
|
31
|
+
else
|
32
|
+
raise RecordNotFound, "#{self} with ID=#{id} could not be found"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/netsuite/version.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NetSuite::Actions::Initialize do
|
4
|
+
let(:customer) { NetSuite::Entities::Customer.new(:internal_id => 1) }
|
5
|
+
|
6
|
+
before do
|
7
|
+
savon.expects(:initialize).with({
|
8
|
+
'platformMsgs:initializeRecord' => {
|
9
|
+
'platformCore:type' => 'invoice',
|
10
|
+
'platformCore:reference' => {
|
11
|
+
'platformCore:name' => 'Ryan Moran'
|
12
|
+
},
|
13
|
+
:attributes! => {
|
14
|
+
'platformCore:reference' => {
|
15
|
+
'internalId' => '1',
|
16
|
+
:type => 'customer'
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}).returns(:initialize_invoice_from_customer)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'makes a valid request to the NetSuite API' do
|
24
|
+
NetSuite::Actions::Initialize.call(customer)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'returns a valid Response object' do
|
28
|
+
response = NetSuite::Actions::Initialize.call(customer)
|
29
|
+
response.should be_kind_of(NetSuite::Response)
|
30
|
+
response.should be_success
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NetSuite::Entities::Customer do
|
4
|
+
let(:customer) { NetSuite::Entities::Customer.new }
|
5
|
+
|
6
|
+
it 'has all the right fields' do
|
7
|
+
[
|
8
|
+
:internal_id, :external_id, :custom_form, :entity_id, :alt_name, :is_person, :phonetic_name,
|
9
|
+
:salutation, :first_name, :middle_name, :last_name, :company_name, :entity_status, :parent,
|
10
|
+
:phone, :fax, :email, :url, :default_address, :is_inactive, :category, :title, :print_on_check_as,
|
11
|
+
:alt_phone, :home_phone, :mobile_phone, :alt_email, :language, :comments, :date_created, :image,
|
12
|
+
:email_preference, :subsidiary, :representing_subsidiary, :sales_rep, :territory, :contrib_pct,
|
13
|
+
:partner, :sales_group, :vat_reg_number, :account_number, :tax_exempt, :terms, :credit_limit,
|
14
|
+
:credit_hold_override, :balance, :overdue_balance, :days_overdue, :unbilled_orders,
|
15
|
+
:consol_unbilled_orders, :consol_overdue_balance, :consol_deposit_balance, :consol_balance,
|
16
|
+
:consol_aging, :consol_days_overdue, :price_level, :currency, :pref_cc_processor, :deposit_balance,
|
17
|
+
:ship_complete, :taxable, :tax_item, :resale_number, :aging, :start_date, :end_date, :reminder_days,
|
18
|
+
:shipping_item, :third_party_acct, :third_party_zipcode, :third_party_country, :give_access,
|
19
|
+
:estimated_budget, :access_role, :send_email, :password, :password_2, :require_pwd_change,
|
20
|
+
:campaign_category, :lead_source, :web_lead, :referrer, :keywords, :click_stream,
|
21
|
+
:last_page_visited, :visits, :first_visit, :last_visit, :bill_pay, :opening_balance, :last_modified,
|
22
|
+
:opening_balance_date, :opening_balance_account, :stage, :email_transactions, :print_transactions,
|
23
|
+
:fax_transactions, :sync_partner_teams, :is_budget_approved, :global_subscription_status,
|
24
|
+
:sales_readiness, :sales_team_list, :buying_reason, :download_list, :buying_time_frame,
|
25
|
+
:addressbook_list, :subscriptions_list, :contact_roles_list, :currency_list, :credit_cards_list,
|
26
|
+
:partners_list, :group_pricing_list, :item_pricing_list, :custom_field_list
|
27
|
+
].each do |field|
|
28
|
+
customer.should have_field(field)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '.get' do
|
33
|
+
context 'when the response is successful' do
|
34
|
+
let(:response) { NetSuite::Response.new(:success => true, :body => { :is_person => true }) }
|
35
|
+
|
36
|
+
it 'returns a Customer instance populated with the data from the response object' do
|
37
|
+
NetSuite::Actions::Get.should_receive(:call).with(1).and_return(response)
|
38
|
+
customer = NetSuite::Entities::Customer.get(1)
|
39
|
+
customer.should be_kind_of(NetSuite::Entities::Customer)
|
40
|
+
customer.is_person.should be_true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when the response is unsuccessful' do
|
45
|
+
let(:response) { NetSuite::Response.new(:success => false, :body => {}) }
|
46
|
+
|
47
|
+
it 'returns a Customer instance populated with the data from the response object' do
|
48
|
+
NetSuite::Actions::Get.should_receive(:call).with(1).and_return(response)
|
49
|
+
lambda {
|
50
|
+
NetSuite::Entities::Customer.get(1)
|
51
|
+
}.should raise_error(NetSuite::RecordNotFound, 'NetSuite::Entities::Customer with ID=1 could not be found')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#add' do
|
57
|
+
let(:test_data) { { :entity_id => 'TEST CUSTOMER', :is_person => true } }
|
58
|
+
|
59
|
+
context 'when the response is successful' do
|
60
|
+
let(:response) { NetSuite::Response.new(:success => true, :body => { :internal_id => '1' }) }
|
61
|
+
|
62
|
+
it 'returns true' do
|
63
|
+
NetSuite::Actions::Add.should_receive(:call).
|
64
|
+
with(test_data).
|
65
|
+
and_return(response)
|
66
|
+
customer = NetSuite::Entities::Customer.new(test_data)
|
67
|
+
customer.add.should be_true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when the response is unsuccessful' do
|
72
|
+
let(:response) { NetSuite::Response.new(:success => false, :body => {}) }
|
73
|
+
it 'returns false' do
|
74
|
+
NetSuite::Actions::Add.should_receive(:call).
|
75
|
+
with(test_data).
|
76
|
+
and_return(response)
|
77
|
+
customer = NetSuite::Entities::Customer.new(test_data)
|
78
|
+
customer.add.should be_false
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NetSuite::FieldSupport do
|
4
|
+
let(:klass) { Class.new.send(:include, NetSuite::FieldSupport) }
|
5
|
+
let(:instance) { klass.new }
|
6
|
+
|
7
|
+
describe '#initialize' do
|
8
|
+
before do
|
9
|
+
klass.field(:banana)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'stores the passed in attributes into the attributes instance variable' do
|
13
|
+
instance = klass.new(:banana => 'for a monkey')
|
14
|
+
instance.send(:attributes).should eql(:banana => 'for a monkey')
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'ignores passed in attributes that are not in the fields set' do
|
18
|
+
instance = klass.new(:apple => 'for a horse', :banana => 'for a monkey')
|
19
|
+
instance.send(:attributes).should eql(:banana => 'for a monkey')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'renames attributes with swirlies'
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '.fields' do
|
26
|
+
context 'with arguments' do
|
27
|
+
it 'calls .field with each argument passed to it' do
|
28
|
+
[:one, :two, :three].each do |field|
|
29
|
+
klass.should_receive(:field).with(field)
|
30
|
+
end
|
31
|
+
klass.fields(:one, :two, :three)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'without arguments' do
|
36
|
+
it 'returns a Set of the field arguments' do
|
37
|
+
arguments = [:one, :two, :three]
|
38
|
+
klass.fields(*arguments)
|
39
|
+
klass.fields.should eql(Set.new(arguments))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.field' do
|
45
|
+
it 'defines instance accessor methods for the given field' do
|
46
|
+
klass.field(:one)
|
47
|
+
instance.one = 1
|
48
|
+
instance.one.should eql(1)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NetSuite::Transactions::Invoice do
|
4
|
+
let(:invoice) { NetSuite::Transactions::Invoice.new }
|
5
|
+
let(:customer) { NetSuite::Entities::Customer.new }
|
6
|
+
let(:response) { NetSuite::Response.new(:success => true, :body => { :internal_id => '1' }) }
|
7
|
+
|
8
|
+
it 'has all the right fields' do
|
9
|
+
[
|
10
|
+
:internal_id, :external_id, :created_date, :last_modified_date, :custom_form, :entity, :tran_date, :tran_id,
|
11
|
+
:source, :created_from, :posting_period, :opportunity, :department, :klass, :terms, :location, :subsidiary,
|
12
|
+
:due_date, :discount_date, :discount_amount, :sales_rep, :contrib_pct, :partner, :lead_source, :start_date,
|
13
|
+
:end_date, :other_ref_name, :memo, :sales_effective_date, :exclude_commission, :total_cost_estimate,
|
14
|
+
:est_gross_profit, :est_gross_profit_percent, :rev_rec_schedule, :rev_rec_start_date, :rev_rec_end_date,
|
15
|
+
:amount_paid, :amount_remaining, :balance, :account, :on_credit_hold, :exchange_rate, :currency_name,
|
16
|
+
:promo_code, :discount_item, :discount_rate, :is_taxable, :tax_item, :tax_rate, :to_be_printed, :to_be_emailed,
|
17
|
+
:to_be_faxed, :fax, :message_sel, :message, :transaction_bill_address, :bill_address_list, :bill_address,
|
18
|
+
:transaction_ship_address, :ship_address_list, :ship_address, :fob, :ship_date, :ship_method, :shipping_cost,
|
19
|
+
:shipping_tax_1_rate, :shipping_tax_2_rate, :shipping_tax_code, :handling_tax_code, :handling_tax_1_rate,
|
20
|
+
:handling_cost, :handling_tax_2_rate, :tracking_numbers, :linked_tracking_numbers, :sales_group, :sub_total,
|
21
|
+
:revenue_status, :recognized_revenue, :deferred_revenue, :rev_rec_on_rev_commitment, :sync_sales_teams,
|
22
|
+
:discount_total, :tax_total, :alt_shipping_cost, :alt_handling_cost, :total, :status, :job, :billing_schedule,
|
23
|
+
:email, :tax_2_total, :vat_reg_num, :exp_cost_discount, :item_cost_discount, :time_discount, :exp_cost_disc_rate,
|
24
|
+
:item_cost_disc_rate, :time_disc_rate, :exp_cost_disc_amount, :exp_cost_tax_rate_1, :exp_cost_tax_rate_2,
|
25
|
+
:item_cost_disc_amount, :exp_cost_tax_code, :exp_cost_disc_tax_1_amt, :item_cost_tax_rate_1, :time_disc_amount,
|
26
|
+
:item_cost_tax_code, :exp_cost_disc_taxable, :item_cost_disc_taxable, :item_cost_tax_rate_2, :item_cost_disc_tax_1_amt,
|
27
|
+
:item_cost_disc_print, :time_disc_taxable, :time_tax_rate_1, :exp_cost_disc_print, :time_tax_code, :time_disc_print,
|
28
|
+
:gift_cert_applied, :time_disc_tax_1_amt, :tran_is_vsoe_bundle, :time_tax_rate_2, :vsoe_auto_calc, :sync_partner_teams,
|
29
|
+
:sales_team_list, :partners_list, :item_list, :item_cost_list, :gift_cert_redemption_list, :exp_cost_list, :time_list,
|
30
|
+
:ship_group_list, :custom_field_list
|
31
|
+
].each do |field|
|
32
|
+
invoice.should have_field(field)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'handles the "klass" field correctly'
|
37
|
+
# This field maps to 'class' but cannot be set as such in Ruby as it will cause runtime errors.
|
38
|
+
|
39
|
+
describe '.initialize' do
|
40
|
+
context 'when the request is successful' do
|
41
|
+
it 'returns an initialized invoice from the customer entity' do
|
42
|
+
NetSuite::Actions::Initialize.should_receive(:call).with(customer).and_return(response)
|
43
|
+
invoice = NetSuite::Transactions::Invoice.initialize(customer)
|
44
|
+
invoice.should be_kind_of(NetSuite::Transactions::Invoice)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'when the response is unsuccessful' do
|
49
|
+
pending
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
RSpec::Matchers.define :have_field do |attribute|
|
2
|
+
|
3
|
+
match do |model|
|
4
|
+
field_can_be_set_and_retrieved?(model, attribute) && field_can_be_set_on_instantiation?(model, attribute)
|
5
|
+
end
|
6
|
+
|
7
|
+
def field_can_be_set_and_retrieved?(model, attribute)
|
8
|
+
obj = Object.new
|
9
|
+
model.send("#{attribute}=".to_sym, obj)
|
10
|
+
model.send(attribute) == obj
|
11
|
+
end
|
12
|
+
|
13
|
+
def field_can_be_set_on_instantiation?(model, attribute)
|
14
|
+
obj = Object.new
|
15
|
+
new_model = model.class.new(attribute => obj)
|
16
|
+
new_model.send(attribute) == obj
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<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">
|
3
|
+
<soapenv:Header>
|
4
|
+
<platformMsgs:documentInfo xmlns:platformMsgs="urn:messages_2011_2.platform.webservices.netsuite.com">
|
5
|
+
<platformMsgs:nsId>WEBSERVICES_3392464_0102201215937064331518330846_2ba5246f66c</platformMsgs:nsId>
|
6
|
+
</platformMsgs:documentInfo>
|
7
|
+
</soapenv:Header>
|
8
|
+
<soapenv:Body>
|
9
|
+
<initializeResponse xmlns="urn:messages_2011_2.platform.webservices.netsuite.com">
|
10
|
+
<readResponse>
|
11
|
+
<platformCore:status isSuccess="true" xmlns:platformCore="urn:core_2011_2.platform.webservices.netsuite.com"/>
|
12
|
+
<record xsi:type="tranSales:Invoice" xmlns:tranSales="urn:sales_2011_2.transactions.webservices.netsuite.com">
|
13
|
+
<tranSales:customForm internalId="101" xmlns:platformCore="urn:core_2011_2.platform.webservices.netsuite.com">
|
14
|
+
<platformCore:name>RP Test Product Invoice</platformCore:name>
|
15
|
+
</tranSales:customForm>
|
16
|
+
<tranSales:entity internalId="988" xmlns:platformCore="urn:core_2011_2.platform.webservices.netsuite.com">
|
17
|
+
<platformCore:name>100157 200 Black Men of Chicago</platformCore:name>
|
18
|
+
</tranSales:entity>
|
19
|
+
<tranSales:tranDate>2012-01-02T00:00:00.000-08:00</tranSales:tranDate>
|
20
|
+
<tranSales:tranId>2582003</tranSales:tranId>
|
21
|
+
<tranSales:postingPeriod internalId="20" xmlns:platformCore="urn:core_2011_2.platform.webservices.netsuite.com">
|
22
|
+
<platformCore:name>Jan 2012</platformCore:name>
|
23
|
+
</tranSales:postingPeriod>
|
24
|
+
<tranSales:dueDate>2012-01-02T00:00:00.000-08:00</tranSales:dueDate>
|
25
|
+
<tranSales:excludeCommission>false</tranSales:excludeCommission>
|
26
|
+
<tranSales:account internalId="123" xmlns:platformCore="urn:core_2011_2.platform.webservices.netsuite.com">
|
27
|
+
<platformCore:name>1100 Accounts Receivable</platformCore:name>
|
28
|
+
</tranSales:account>
|
29
|
+
<tranSales:transactionBillAddress xmlns:platformCommon="urn:common_2011_2.platform.webservices.netsuite.com">
|
30
|
+
<platformCommon:billAddr1>3473 S Martin Luther King Dr, Ste 206</platformCommon:billAddr1>
|
31
|
+
<platformCommon:billCity>Chicago</platformCommon:billCity>
|
32
|
+
<platformCommon:billState>IL</platformCommon:billState>
|
33
|
+
<platformCommon:billZip>60616</platformCommon:billZip>
|
34
|
+
<platformCommon:billCountry>_unitedStates</platformCommon:billCountry>
|
35
|
+
</tranSales:transactionBillAddress>
|
36
|
+
<tranSales:billAddressList internalId="567" xmlns:platformCore="urn:core_2011_2.platform.webservices.netsuite.com">
|
37
|
+
<platformCore:name>3473 S Martin Luther King Dr, Ste 206</platformCore:name>
|
38
|
+
</tranSales:billAddressList>
|
39
|
+
<tranSales:billAddress>3473 S Martin Luther King Dr, Ste 206 Chicago IL 60616</tranSales:billAddress>
|
40
|
+
<tranSales:transactionShipAddress xmlns:platformCommon="urn:common_2011_2.platform.webservices.netsuite.com">
|
41
|
+
<platformCommon:shipAddr1>3473 S Martin Luther King Dr, Ste 206</platformCommon:shipAddr1>
|
42
|
+
<platformCommon:shipCity>Chicago</platformCommon:shipCity>
|
43
|
+
<platformCommon:shipState>IL</platformCommon:shipState>
|
44
|
+
<platformCommon:shipZip>60616</platformCommon:shipZip>
|
45
|
+
<platformCommon:shipCountry>_unitedStates</platformCommon:shipCountry>
|
46
|
+
<platformCommon:shipIsResidential>false</platformCommon:shipIsResidential>
|
47
|
+
</tranSales:transactionShipAddress>
|
48
|
+
<tranSales:shipAddressList internalId="567" xmlns:platformCore="urn:core_2011_2.platform.webservices.netsuite.com">
|
49
|
+
<platformCore:name>3473 S Martin Luther King Dr, Ste 206</platformCore:name>
|
50
|
+
</tranSales:shipAddressList>
|
51
|
+
<tranSales:shipAddress>3473 S Martin Luther King Dr, Ste 206 Chicago IL 60616</tranSales:shipAddress>
|
52
|
+
<tranSales:shipDate>2012-01-02T00:00:00.000-08:00</tranSales:shipDate>
|
53
|
+
<tranSales:subTotal>0.0</tranSales:subTotal>
|
54
|
+
<tranSales:syncSalesTeams>false</tranSales:syncSalesTeams>
|
55
|
+
<tranSales:discountTotal>0.0</tranSales:discountTotal>
|
56
|
+
<tranSales:taxTotal>0.0</tranSales:taxTotal>
|
57
|
+
<tranSales:total>0.0</tranSales:total>
|
58
|
+
<tranSales:itemCostDiscPrint>false</tranSales:itemCostDiscPrint>
|
59
|
+
<tranSales:expCostDiscPrint>false</tranSales:expCostDiscPrint>
|
60
|
+
<tranSales:customFieldList xmlns:platformCore="urn:core_2011_2.platform.webservices.netsuite.com">
|
61
|
+
<platformCore:customField internalId="custbody_3rd_party" xsi:type="platformCore:BooleanCustomFieldRef">
|
62
|
+
<platformCore:value>false</platformCore:value>
|
63
|
+
</platformCore:customField>
|
64
|
+
</tranSales:customFieldList>
|
65
|
+
</record>
|
66
|
+
</readResponse>
|
67
|
+
</initializeResponse>
|
68
|
+
</soapenv:Body>
|
69
|
+
</soapenv:Envelope>
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: netsuite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 4
|
10
|
+
version: 0.0.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ryan Moran
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2012-01-02 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -103,24 +103,32 @@ files:
|
|
103
103
|
- lib/netsuite.rb
|
104
104
|
- lib/netsuite/actions/add.rb
|
105
105
|
- lib/netsuite/actions/get.rb
|
106
|
-
- lib/netsuite/actions/
|
106
|
+
- lib/netsuite/actions/initialize.rb
|
107
107
|
- lib/netsuite/configuration.rb
|
108
|
+
- lib/netsuite/entities/customer.rb
|
108
109
|
- lib/netsuite/errors.rb
|
109
|
-
- lib/netsuite/
|
110
|
+
- lib/netsuite/field_support.rb
|
110
111
|
- lib/netsuite/response.rb
|
112
|
+
- lib/netsuite/savon_support.rb
|
113
|
+
- lib/netsuite/transactions/invoice.rb
|
111
114
|
- lib/netsuite/version.rb
|
112
115
|
- netsuite.gemspec
|
113
116
|
- spec/netsuite/actions/add_spec.rb
|
114
117
|
- spec/netsuite/actions/get_spec.rb
|
115
|
-
- spec/netsuite/actions/
|
118
|
+
- spec/netsuite/actions/initialize_spec.rb
|
116
119
|
- spec/netsuite/configuration_spec.rb
|
117
|
-
- spec/netsuite/
|
120
|
+
- spec/netsuite/entities/customer_spec.rb
|
121
|
+
- spec/netsuite/field_support_spec.rb
|
118
122
|
- spec/netsuite/response_spec.rb
|
123
|
+
- spec/netsuite/savon_support_spec.rb
|
124
|
+
- spec/netsuite/transactions/invoice_spec.rb
|
119
125
|
- spec/netsuite_spec.rb
|
120
126
|
- spec/spec_helper.rb
|
121
127
|
- spec/support/configuration.rb
|
128
|
+
- spec/support/field_matcher.rb
|
122
129
|
- spec/support/fixtures/add/add_customer.xml
|
123
130
|
- spec/support/fixtures/get/get_customer.xml
|
131
|
+
- spec/support/fixtures/initialize/initialize_invoice_from_customer.xml
|
124
132
|
- spec/support/savon.rb
|
125
133
|
- wsdl/2011_02.wsdl
|
126
134
|
has_rdoc: true
|
@@ -160,13 +168,18 @@ summary: NetSuite SuiteTalk API Wrapper
|
|
160
168
|
test_files:
|
161
169
|
- spec/netsuite/actions/add_spec.rb
|
162
170
|
- spec/netsuite/actions/get_spec.rb
|
163
|
-
- spec/netsuite/actions/
|
171
|
+
- spec/netsuite/actions/initialize_spec.rb
|
164
172
|
- spec/netsuite/configuration_spec.rb
|
165
|
-
- spec/netsuite/
|
173
|
+
- spec/netsuite/entities/customer_spec.rb
|
174
|
+
- spec/netsuite/field_support_spec.rb
|
166
175
|
- spec/netsuite/response_spec.rb
|
176
|
+
- spec/netsuite/savon_support_spec.rb
|
177
|
+
- spec/netsuite/transactions/invoice_spec.rb
|
167
178
|
- spec/netsuite_spec.rb
|
168
179
|
- spec/spec_helper.rb
|
169
180
|
- spec/support/configuration.rb
|
181
|
+
- spec/support/field_matcher.rb
|
170
182
|
- spec/support/fixtures/add/add_customer.xml
|
171
183
|
- spec/support/fixtures/get/get_customer.xml
|
184
|
+
- spec/support/fixtures/initialize/initialize_invoice_from_customer.xml
|
172
185
|
- spec/support/savon.rb
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module NetSuite
|
2
|
-
class Customer
|
3
|
-
|
4
|
-
def initialize(attributes = {})
|
5
|
-
@attributes = attributes
|
6
|
-
end
|
7
|
-
|
8
|
-
def self.get(id)
|
9
|
-
response = NetSuite::Actions::Get.call(id)
|
10
|
-
if response.success?
|
11
|
-
new(response.body)
|
12
|
-
else
|
13
|
-
raise RecordNotFound, "#{self} with ID=#{id} could not be found"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def add
|
18
|
-
response = NetSuite::Actions::Add.call(@attributes)
|
19
|
-
response.success?
|
20
|
-
end
|
21
|
-
|
22
|
-
def method_missing(m, *args, &block)
|
23
|
-
if @attributes.keys.include?(m.to_sym)
|
24
|
-
@attributes[m.to_sym]
|
25
|
-
else
|
26
|
-
super
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe NetSuite::Customer do
|
4
|
-
let(:customer) { NetSuite::Customer.new }
|
5
|
-
|
6
|
-
describe '.get' do
|
7
|
-
context 'when the response is successful' do
|
8
|
-
let(:response) { NetSuite::Response.new(:success => true, :body => { :is_person => true }) }
|
9
|
-
|
10
|
-
it 'returns a Customer instance populated with the data from the response object' do
|
11
|
-
NetSuite::Actions::Get.should_receive(:call).with(1).and_return(response)
|
12
|
-
customer = NetSuite::Customer.get(1)
|
13
|
-
customer.should be_kind_of(NetSuite::Customer)
|
14
|
-
customer.is_person.should be_true
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
context 'when the response is unsuccessful' do
|
19
|
-
let(:response) { NetSuite::Response.new(:success => false, :body => {}) }
|
20
|
-
|
21
|
-
it 'returns a Customer instance populated with the data from the response object' do
|
22
|
-
NetSuite::Actions::Get.should_receive(:call).with(1).and_return(response)
|
23
|
-
lambda {
|
24
|
-
NetSuite::Customer.get(1)
|
25
|
-
}.should raise_error(NetSuite::RecordNotFound, 'NetSuite::Customer with ID=1 could not be found')
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
describe '#add' do
|
31
|
-
let(:test_data) { { :entity_name => 'TEST CUSTOMER', :is_person => true } }
|
32
|
-
|
33
|
-
context 'when the response is successful' do
|
34
|
-
let(:response) { NetSuite::Response.new(:success => true, :body => { :internal_id => '1' }) }
|
35
|
-
|
36
|
-
it 'returns true' do
|
37
|
-
NetSuite::Actions::Add.should_receive(:call).
|
38
|
-
with(test_data).
|
39
|
-
and_return(response)
|
40
|
-
customer = NetSuite::Customer.new(test_data)
|
41
|
-
customer.add.should be_true
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context 'when the response is unsuccessful' do
|
46
|
-
let(:response) { NetSuite::Response.new(:success => false, :body => {}) }
|
47
|
-
it 'returns false' do
|
48
|
-
NetSuite::Actions::Add.should_receive(:call).
|
49
|
-
with(test_data).
|
50
|
-
and_return(response)
|
51
|
-
customer = NetSuite::Customer.new(test_data)
|
52
|
-
customer.add.should be_false
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
describe '#method_missing' do
|
58
|
-
context 'when calling a method that exists as an attribute' do
|
59
|
-
it 'returns the right value from the attributes hash' do
|
60
|
-
customer = NetSuite::Customer.new(:name => 'Mr. Banana')
|
61
|
-
customer.name.should eql('Mr. Banana')
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
context 'when calling a method that does not exist in the attributes hash' do
|
66
|
-
it 'raises a NoMethodError' do
|
67
|
-
lambda {
|
68
|
-
customer.banana
|
69
|
-
}.should raise_error(NoMethodError)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
end
|