netsuite 0.1.0 → 0.2.0
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/Gemfile +0 -2
- data/README.md +154 -0
- data/lib/netsuite.rb +7 -0
- data/lib/netsuite/actions/add.rb +6 -21
- data/lib/netsuite/actions/delete.rb +7 -10
- data/lib/netsuite/actions/get.rb +7 -10
- data/lib/netsuite/actions/get_list.rb +77 -0
- data/lib/netsuite/actions/get_select_value.rb +71 -0
- data/lib/netsuite/actions/search.rb +151 -36
- data/lib/netsuite/actions/search_more_with_id.rb +3 -2
- data/lib/netsuite/actions/update.rb +16 -16
- data/lib/netsuite/configuration.rb +29 -15
- data/lib/netsuite/namespaces/list_support.rb +11 -0
- data/lib/netsuite/records/account.rb +1 -0
- data/lib/netsuite/records/base_ref_list.rb +33 -0
- data/lib/netsuite/records/cash_sale.rb +7 -0
- data/lib/netsuite/records/custom_field.rb +2 -1
- data/lib/netsuite/records/custom_field_list.rb +62 -12
- data/lib/netsuite/records/custom_record.rb +1 -7
- data/lib/netsuite/records/custom_record_ref.rb +7 -0
- data/lib/netsuite/records/customer.rb +4 -3
- data/lib/netsuite/records/phone_call.rb +29 -0
- data/lib/netsuite/records/record_ref.rb +1 -9
- data/lib/netsuite/records/sales_order.rb +2 -1
- data/lib/netsuite/records/support_case.rb +32 -0
- data/lib/netsuite/records/task.rb +4 -3
- data/lib/netsuite/records/transaction.rb +4 -21
- data/lib/netsuite/support/actions.rb +4 -0
- data/lib/netsuite/support/records.rb +3 -0
- data/lib/netsuite/support/search_result.rb +53 -29
- data/lib/netsuite/version.rb +1 -1
- data/netsuite.gemspec +1 -1
- data/spec/netsuite/actions/add_spec.rb +9 -13
- data/spec/netsuite/actions/delete_spec.rb +5 -8
- data/spec/netsuite/actions/get_spec.rb +39 -24
- data/spec/netsuite/actions/search_spec.rb +149 -0
- data/spec/netsuite/actions/update_spec.rb +9 -13
- data/spec/netsuite/configuration_spec.rb +3 -9
- data/spec/netsuite/records/custom_field_list_spec.rb +19 -5
- data/spec/netsuite/records/customer_spec.rb +2 -2
- data/spec/netsuite/records/phone_call_spec.rb +23 -0
- data/spec/netsuite/records/support_case_spec.rb +157 -0
- data/spec/support/fixtures/search/saved_search_customer.xml +54 -0
- data/spec/support/fixtures/search/saved_search_joined_custom_customer.xml +87 -0
- metadata +21 -4
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NetSuite::Actions::Search do
|
4
|
+
before(:all) { savon.mock! }
|
5
|
+
after(:all) { savon.unmock! }
|
6
|
+
|
7
|
+
context "saved search" do
|
8
|
+
it "should handle a ID only search" do
|
9
|
+
savon.expects(:search).with(:message => {
|
10
|
+
'searchRecord' => {
|
11
|
+
'@xsi:type' => 'listRel:CustomerSearchAdvanced',
|
12
|
+
'@savedSearchId' => 500,
|
13
|
+
:content! => { "listRel:criteria" => {} }
|
14
|
+
},
|
15
|
+
}).returns(File.read('spec/support/fixtures/search/saved_search_customer.xml'))
|
16
|
+
|
17
|
+
result = NetSuite::Records::Customer.search(saved: 500)
|
18
|
+
result.results.size.should == 1
|
19
|
+
result.results.first.email.should == 'aemail@gmail.com'
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should handle a ID search with basic params" do
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should handle a search with joined params" do
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should handle a search with joined params containing custom field search" do
|
31
|
+
savon.expects(:search).with(:message => {
|
32
|
+
'searchRecord' => {
|
33
|
+
'@xsi:type' => 'listRel:CustomerSearchAdvanced',
|
34
|
+
'@savedSearchId' => 500,
|
35
|
+
:content! => {
|
36
|
+
"listRel:criteria" => {
|
37
|
+
"listRel:basic" => {
|
38
|
+
"platformCommon:entityId" => {
|
39
|
+
"platformCore:searchValue" => "New Keywords"
|
40
|
+
},
|
41
|
+
|
42
|
+
:attributes! => {
|
43
|
+
"platformCommon:entityId" => { "operator" => "hasKeywords" },
|
44
|
+
"platformCommon:stage" => { "operator" => "anyOf" }
|
45
|
+
},
|
46
|
+
|
47
|
+
"platformCommon:stage" => { "platformCore:searchValue" => ["_lead", "_customer"] },
|
48
|
+
"platformCommon:customFieldList" => {
|
49
|
+
"platformCore:customField" => [
|
50
|
+
{
|
51
|
+
"platformCore:searchValue" => [{}, {}],
|
52
|
+
:attributes! => {
|
53
|
+
"platformCore:searchValue" => {
|
54
|
+
"internalId" => [4, 11]
|
55
|
+
}
|
56
|
+
}
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"platformCore:searchValue" => [{}],
|
60
|
+
:attributes! => {
|
61
|
+
"platformCore:searchValue" => { "internalId" => [88825] }
|
62
|
+
}
|
63
|
+
}
|
64
|
+
],
|
65
|
+
|
66
|
+
:attributes! => {
|
67
|
+
"platformCore:customField" => {
|
68
|
+
"internalId" => ["custentity_customerandcontacttypelist", "custentity_relatedthing"],
|
69
|
+
"operator" => ["anyOf", "anyOf"],
|
70
|
+
"xsi:type" => ["platformCore:SearchMultiSelectCustomField", "platformCore:SearchMultiSelectCustomField"]
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
76
|
+
}
|
77
|
+
},
|
78
|
+
}).returns(File.read('spec/support/fixtures/search/saved_search_joined_custom_customer.xml'))
|
79
|
+
|
80
|
+
search = NetSuite::Records::Customer.search({
|
81
|
+
saved: 500,
|
82
|
+
basic: [
|
83
|
+
{
|
84
|
+
field: 'entityId',
|
85
|
+
value: 'New Keywords',
|
86
|
+
operator: 'hasKeywords'
|
87
|
+
},
|
88
|
+
{
|
89
|
+
field: 'stage',
|
90
|
+
operator: 'anyOf',
|
91
|
+
type: 'SearchMultiSelectCustomField',
|
92
|
+
value: [
|
93
|
+
'_lead',
|
94
|
+
'_customer'
|
95
|
+
]
|
96
|
+
},
|
97
|
+
{
|
98
|
+
field: 'customFieldList',
|
99
|
+
value: [
|
100
|
+
{
|
101
|
+
field: 'custentity_customerandcontacttypelist',
|
102
|
+
operator: 'anyOf',
|
103
|
+
# type is needed for multiselect fields
|
104
|
+
type: 'SearchMultiSelectCustomField',
|
105
|
+
value: [
|
106
|
+
NetSuite::Records::CustomRecordRef.new(:internal_id => 4),
|
107
|
+
NetSuite::Records::CustomRecordRef.new(:internal_id => 11),
|
108
|
+
]
|
109
|
+
},
|
110
|
+
{
|
111
|
+
field: 'custentity_relatedthing',
|
112
|
+
# is in the GUI is the equivilent of anyOf with a single element array
|
113
|
+
operator: 'anyOf',
|
114
|
+
type: 'SearchMultiSelectCustomField',
|
115
|
+
value: [
|
116
|
+
NetSuite::Records::Customer.new(:internal_id => 88825)
|
117
|
+
]
|
118
|
+
}
|
119
|
+
]
|
120
|
+
}
|
121
|
+
]
|
122
|
+
})
|
123
|
+
|
124
|
+
search.results.size.should == 2
|
125
|
+
search.results.first.alt_name.should == 'A Awesome Name'
|
126
|
+
search.results.last.email.should == 'alessawesome@gmail.com'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "advanced search" do
|
131
|
+
it "should handle search column definitions" do
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should handle joined search results" do
|
136
|
+
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context "basic search" do
|
141
|
+
it "should handle searching basic fields" do
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should handle searching with joined fields" do
|
146
|
+
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -11,14 +11,12 @@ describe NetSuite::Actions::Update do
|
|
11
11
|
before do
|
12
12
|
savon.expects(:update).with(:message => {
|
13
13
|
'platformMsgs:record' => {
|
14
|
-
|
15
|
-
|
14
|
+
:content! => {
|
15
|
+
'listRel:entityId' => 'Shutter Fly',
|
16
|
+
'listRel:companyName' => 'Shutter Fly, Inc.',
|
17
|
+
},
|
18
|
+
'@xsi:type' => 'listRel:Customer'
|
16
19
|
},
|
17
|
-
:attributes! => {
|
18
|
-
'platformMsgs:record' => {
|
19
|
-
'xsi:type' => 'listRel:Customer'
|
20
|
-
}
|
21
|
-
}
|
22
20
|
}).returns(File.read('spec/support/fixtures/update/update_customer.xml'))
|
23
21
|
end
|
24
22
|
|
@@ -40,13 +38,11 @@ describe NetSuite::Actions::Update do
|
|
40
38
|
before do
|
41
39
|
savon.expects(:update).with(:message => {
|
42
40
|
'platformMsgs:record' => {
|
43
|
-
|
41
|
+
:content! => {
|
42
|
+
'tranSales:source' => 'Google',
|
43
|
+
},
|
44
|
+
'@xsi:type' => 'tranSales:Invoice'
|
44
45
|
},
|
45
|
-
:attributes! => {
|
46
|
-
'platformMsgs:record' => {
|
47
|
-
'xsi:type' => 'tranSales:Invoice'
|
48
|
-
}
|
49
|
-
}
|
50
46
|
}).returns(File.read('spec/support/fixtures/update/update_invoice.xml'))
|
51
47
|
end
|
52
48
|
|
@@ -66,13 +66,7 @@ describe NetSuite::Configuration do
|
|
66
66
|
'platformCore:email' => 'user@example.com',
|
67
67
|
'platformCore:password' => 'myPassword',
|
68
68
|
'platformCore:account' => '1234',
|
69
|
-
'platformCore:role' => {},
|
70
|
-
:attributes! => {
|
71
|
-
'platformCore:role' => {
|
72
|
-
:internalId => '3',
|
73
|
-
:type => 'role'
|
74
|
-
}
|
75
|
-
}
|
69
|
+
'platformCore:role' => { :@type => 'role', :@internalId => '3' },
|
76
70
|
}
|
77
71
|
})
|
78
72
|
end
|
@@ -145,7 +139,7 @@ describe NetSuite::Configuration do
|
|
145
139
|
describe '#role' do
|
146
140
|
context 'when no role is defined' do
|
147
141
|
it 'defaults to "3"' do
|
148
|
-
config.role.
|
142
|
+
config.role.should == "3"
|
149
143
|
end
|
150
144
|
end
|
151
145
|
end
|
@@ -153,7 +147,7 @@ describe NetSuite::Configuration do
|
|
153
147
|
describe '#role=' do
|
154
148
|
it 'sets the role according to the input value' do
|
155
149
|
config.role = "6"
|
156
|
-
config.role.
|
150
|
+
config.role.should == "6"
|
157
151
|
end
|
158
152
|
end
|
159
153
|
|
@@ -10,23 +10,37 @@ describe NetSuite::Records::CustomFieldList do
|
|
10
10
|
describe '#to_record' do
|
11
11
|
before do
|
12
12
|
list.custom_fields << NetSuite::Records::CustomField.new(
|
13
|
-
:internal_id => '
|
13
|
+
:internal_id => 'custentity_registeredonline',
|
14
14
|
:type => 'BooleanCustomFieldRef',
|
15
15
|
:value => false
|
16
16
|
)
|
17
|
+
list.custom_fields << NetSuite::Records::CustomField.new(
|
18
|
+
:internal_id => 'custbody_salesclassification',
|
19
|
+
:type => 'SelectCustomFieldRef',
|
20
|
+
:value => NetSuite::Records::CustomRecordRef.new(:internal_id => 13, :name => "The Name")
|
21
|
+
)
|
17
22
|
end
|
18
23
|
|
19
24
|
it 'can represent itself as a SOAP record' do
|
20
25
|
record = [
|
21
26
|
{
|
22
|
-
"platformCore:customField" => {
|
23
|
-
|
24
|
-
"
|
27
|
+
"platformCore:customField" => {
|
28
|
+
"@internalId" => "custentity_registeredonline",
|
29
|
+
"@xsi:type" => "BooleanCustomFieldRef",
|
30
|
+
:content! => { "platformCore:value" => false }
|
31
|
+
}
|
32
|
+
},
|
33
|
+
{
|
34
|
+
"platformCore:customField" => {
|
35
|
+
'@internalId' => 'custbody_salesclassification',
|
36
|
+
'@xsi:type' => 'BooleanCustomFieldRef',
|
37
|
+
:content! => { "platformCore:value" => true }
|
25
38
|
}
|
26
39
|
}
|
27
40
|
]
|
28
|
-
|
41
|
+
|
29
42
|
list.to_record.should eql(record)
|
43
|
+
list.to_record.length.should == 2
|
30
44
|
end
|
31
45
|
end
|
32
46
|
|
@@ -13,9 +13,9 @@ describe NetSuite::Records::Customer do
|
|
13
13
|
:deposit_balance, :download_list, :email, :email_preference, :email_transactions, :end_date, :entity_id,
|
14
14
|
:estimated_budget, :fax, :fax_transactions, :first_name, :first_visit, :give_access, :global_subscription_status,
|
15
15
|
:group_pricing_list, :home_phone, :image, :is_budget_approved, :is_inactive, :is_person, :item_pricing_list, :keywords,
|
16
|
-
:language, :
|
16
|
+
:language, :last_modified_date, :last_name, :last_page_visited, :last_visit, :lead_source, :middle_name, :mobile_phone,
|
17
17
|
:opening_balance, :opening_balance_account, :opening_balance_date, :overdue_balance, :parent, :partners_list,
|
18
|
-
:password, :
|
18
|
+
:password, :password2, :phone, :phonetic_name, :pref_cc_processor, :price_level, :print_on_check_as,
|
19
19
|
:print_transactions, :referrer, :reminder_days, :representing_subsidiary, :require_pwd_change, :resale_number,
|
20
20
|
:sales_group, :sales_readiness, :sales_rep, :sales_team_list, :salutation, :send_email, :ship_complete, :shipping_item,
|
21
21
|
:stage, :start_date, :subscriptions_list, :subsidiary, :sync_partner_teams, :tax_exempt, :tax_item, :taxable, :terms,
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NetSuite::Records::PhoneCall do
|
4
|
+
let(:phone_call) { NetSuite::Records::PhoneCall.new }
|
5
|
+
|
6
|
+
it "has the right fields" do
|
7
|
+
[:title, :message, :phone, :status, :priority, :start_date, :end_date, :completed_date, :timed_event, :access_level].each do |f|
|
8
|
+
phone_call.should have_field(f)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'has the right record refs' do
|
13
|
+
[:assigned, :owner, :company, :contact].each do |rr|
|
14
|
+
phone_call.should have_record_ref(rr)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'to_record' do
|
19
|
+
it 'should be verified with our params' do
|
20
|
+
fail 'Not Verified.'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NetSuite::Records::SupportCase do
|
4
|
+
let(:support_case) { NetSuite::Records::SupportCase.new }
|
5
|
+
|
6
|
+
it 'has all the right fields' do
|
7
|
+
[
|
8
|
+
:end_date, :incoming_message, :outgoing_message, :search_solution, :email_form,
|
9
|
+
:internal_only, :title, :case_number, :start_date, :email, :phone, :inbound_email,
|
10
|
+
:is_inactive, :help_desk
|
11
|
+
].each do |field|
|
12
|
+
support_case.should have_field(field)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'has the right record_refs' do
|
17
|
+
[
|
18
|
+
:custom_form, :company, :contact, :issue, :status, :priority, :origin, :category, :assigned
|
19
|
+
].each do |record_ref|
|
20
|
+
support_case.should have_record_ref(record_ref)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#custom_field_list' do
|
25
|
+
it 'can be set from attributes' do
|
26
|
+
attributes = {
|
27
|
+
:custom_field => {
|
28
|
+
:value => 10,
|
29
|
+
:internal_id => 'custfield_something'
|
30
|
+
}
|
31
|
+
}
|
32
|
+
support_case.custom_field_list = attributes
|
33
|
+
support_case.custom_field_list.should be_kind_of(NetSuite::Records::CustomFieldList)
|
34
|
+
support_case.custom_field_list.custom_fields.length.should eql(1)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'can be set from a CustomFieldList object' do
|
38
|
+
custom_field_list = NetSuite::Records::CustomFieldList.new
|
39
|
+
support_case.custom_field_list = custom_field_list
|
40
|
+
support_case.custom_field_list.should eql(custom_field_list)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.get' do
|
45
|
+
context 'when the response is successful' do
|
46
|
+
let(:response) { NetSuite::Response.new(:success => true, :body => { :title => 'Case title' }) }
|
47
|
+
|
48
|
+
it 'returns a SupportCase instance populated with the data from the response object' do
|
49
|
+
NetSuite::Actions::Get.should_receive(:call).with(NetSuite::Records::SupportCase, :external_id => 1).and_return(response)
|
50
|
+
support_case = NetSuite::Records::SupportCase.get(:external_id => 1)
|
51
|
+
support_case.should be_kind_of(NetSuite::Records::SupportCase)
|
52
|
+
support_case.title.should == 'Case title'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when the response is unsuccessful' do
|
57
|
+
let(:response) { NetSuite::Response.new(:success => false, :body => {}) }
|
58
|
+
|
59
|
+
it 'raises a RecordNotFound exception' do
|
60
|
+
NetSuite::Actions::Get.should_receive(:call).with(NetSuite::Records::SupportCase, :external_id => 1).and_return(response)
|
61
|
+
lambda {
|
62
|
+
NetSuite::Records::SupportCase.get(:external_id => 1)
|
63
|
+
}.should raise_error(NetSuite::RecordNotFound,
|
64
|
+
/NetSuite::Records::SupportCase with OPTIONS=(.*) could not be found/)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#add' do
|
70
|
+
let(:support_case) { NetSuite::Records::SupportCase.new(:title => 'Case title') }
|
71
|
+
|
72
|
+
context 'when the response is successful' do
|
73
|
+
let(:response) { NetSuite::Response.new(:success => true, :body => { :internal_id => '1' }) }
|
74
|
+
|
75
|
+
it 'returns true' do
|
76
|
+
NetSuite::Actions::Add.should_receive(:call).
|
77
|
+
with(support_case).
|
78
|
+
and_return(response)
|
79
|
+
support_case.add.should be_true
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when the response is unsuccessful' do
|
84
|
+
let(:response) { NetSuite::Response.new(:success => false, :body => {}) }
|
85
|
+
|
86
|
+
it 'returns false' do
|
87
|
+
NetSuite::Actions::Add.should_receive(:call).
|
88
|
+
with(support_case).
|
89
|
+
and_return(response)
|
90
|
+
support_case.add.should be_false
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe '#delete' do
|
96
|
+
context 'when the response is successful' do
|
97
|
+
let(:response) { NetSuite::Response.new(:success => true, :body => { :internal_id => '1' }) }
|
98
|
+
|
99
|
+
it 'returns true' do
|
100
|
+
NetSuite::Actions::Delete.should_receive(:call).
|
101
|
+
with(support_case).
|
102
|
+
and_return(response)
|
103
|
+
support_case.delete.should be_true
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'when the response is unsuccessful' do
|
108
|
+
let(:response) { NetSuite::Response.new(:success => false, :body => {}) }
|
109
|
+
|
110
|
+
it 'returns false' do
|
111
|
+
NetSuite::Actions::Delete.should_receive(:call).
|
112
|
+
with(support_case).
|
113
|
+
and_return(response)
|
114
|
+
support_case.delete.should be_false
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe '.update' do
|
120
|
+
context 'when the response is successful' do
|
121
|
+
let(:response) { NetSuite::Response.new(:success => true, :body => { :title => 'Case title' }) }
|
122
|
+
|
123
|
+
it 'returns true' do
|
124
|
+
NetSuite::Actions::Update.should_receive(:call).with(NetSuite::Records::SupportCase, :external_id => 1, :title => 'Case title').and_return(response)
|
125
|
+
support_case = NetSuite::Records::SupportCase.new(:external_id => 1)
|
126
|
+
support_case.update(:title => 'Case title').should be_true
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'when the response is unsuccessful' do
|
131
|
+
let(:response) { NetSuite::Response.new(:success => false, :body => {}) }
|
132
|
+
|
133
|
+
it 'raises a RecordNotFound exception' do
|
134
|
+
NetSuite::Actions::Update.should_receive(:call).with(NetSuite::Records::SupportCase, :internal_id => 1, :title => 'Case title').and_return(response)
|
135
|
+
support_case = NetSuite::Records::SupportCase.new(:internal_id => 1)
|
136
|
+
support_case.update(:title => 'Case title').should be_false
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe '#to_record' do
|
142
|
+
let(:support_case) { NetSuite::Records::SupportCase.new(:title => 'Case title') }
|
143
|
+
|
144
|
+
it 'returns a hash of attributes that can be used in a SOAP request' do
|
145
|
+
support_case.to_record.should eql({
|
146
|
+
'listSupport:title' => 'Case title'
|
147
|
+
})
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe '#record_type' do
|
152
|
+
it 'returns a string type for the record to be used in a SOAP request' do
|
153
|
+
support_case.record_type.should eql('listSupport:SupportCase')
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|