netsuite 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|