netsuite 0.8.3 → 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/README.md +3 -2
  4. data/circle.yml +3 -2
  5. data/lib/netsuite.rb +17 -0
  6. data/lib/netsuite/actions/login.rb +11 -0
  7. data/lib/netsuite/actions/update.rb +6 -2
  8. data/lib/netsuite/errors.rb +1 -0
  9. data/lib/netsuite/records/assembly_build.rb +4 -1
  10. data/lib/netsuite/records/assembly_item.rb +1 -0
  11. data/lib/netsuite/records/assembly_unbuild.rb +3 -0
  12. data/lib/netsuite/records/bin_number.rb +18 -0
  13. data/lib/netsuite/records/bin_number_list.rb +1 -20
  14. data/lib/netsuite/records/classification.rb +1 -1
  15. data/lib/netsuite/records/custom_field_list.rb +10 -2
  16. data/lib/netsuite/records/custom_record.rb +2 -2
  17. data/lib/netsuite/records/custom_record_ref.rb +1 -0
  18. data/lib/netsuite/records/customer.rb +3 -3
  19. data/lib/netsuite/records/customer_deposit.rb +5 -2
  20. data/lib/netsuite/records/customer_sales_team.rb +24 -0
  21. data/lib/netsuite/records/customer_sales_team_list.rb +9 -0
  22. data/lib/netsuite/records/customer_status.rb +29 -0
  23. data/lib/netsuite/records/customer_subscription.rb +18 -0
  24. data/lib/netsuite/records/customer_subscriptions_list.rb +10 -0
  25. data/lib/netsuite/records/entity_custom_field.rb +53 -0
  26. data/lib/netsuite/records/non_inventory_resale_item.rb +2 -2
  27. data/lib/netsuite/records/price.rb +17 -0
  28. data/lib/netsuite/records/price_list.rb +9 -0
  29. data/lib/netsuite/records/pricing.rb +20 -0
  30. data/lib/netsuite/records/pricing_matrix.rb +2 -2
  31. data/lib/netsuite/records/promotions.rb +26 -0
  32. data/lib/netsuite/records/promotions_list.rb +9 -0
  33. data/lib/netsuite/records/sales_order.rb +1 -0
  34. data/lib/netsuite/records/sales_role.rb +26 -0
  35. data/lib/netsuite/records/sales_tax_item.rb +3 -1
  36. data/lib/netsuite/records/serialized_assembly_item.rb +239 -0
  37. data/lib/netsuite/records/service_sale_item.rb +1 -1
  38. data/lib/netsuite/records/tax_group.rb +2 -2
  39. data/lib/netsuite/records/transaction_body_custom_field.rb +61 -0
  40. data/lib/netsuite/records/transaction_column_custom_field.rb +59 -0
  41. data/lib/netsuite/records/vendor_credit.rb +2 -0
  42. data/lib/netsuite/records/work_order.rb +8 -0
  43. data/lib/netsuite/support/country.rb +27 -15
  44. data/lib/netsuite/utilities.rb +45 -20
  45. data/lib/netsuite/version.rb +1 -1
  46. data/spec/netsuite/actions/login_spec.rb +23 -0
  47. data/spec/netsuite/actions/update_spec.rb +42 -0
  48. data/spec/netsuite/records/address_spec.rb +10 -0
  49. data/spec/netsuite/records/basic_record_spec.rb +6 -1
  50. data/spec/netsuite/records/bin_number_spec.rb +23 -0
  51. data/spec/netsuite/records/custom_field_list_spec.rb +33 -0
  52. data/spec/netsuite/records/customer_sales_team_list_spec.rb +41 -0
  53. data/spec/netsuite/records/customer_spec.rb +22 -1
  54. data/spec/netsuite/records/customer_subscription_spec.rb +41 -0
  55. data/spec/netsuite/records/customer_subscriptions_list_spec.rb +19 -0
  56. data/spec/netsuite/records/entity_custom_field_spec.rb +34 -0
  57. data/spec/netsuite/records/pricing_matrix_spec.rb +15 -13
  58. data/spec/netsuite/records/transaction_body_custom_field_spec.rb +32 -0
  59. data/spec/netsuite/records/transaction_column_custom_field_spec.rb +32 -0
  60. data/spec/netsuite/records/vendor_credit_spec.rb +29 -0
  61. data/spec/netsuite/utilities_spec.rb +15 -3
  62. data/spec/spec_helper.rb +5 -4
  63. metadata +34 -2
@@ -1,3 +1,3 @@
1
1
  module NetSuite
2
- VERSION = '0.8.3'
2
+ VERSION = '0.8.4'
3
3
  end
@@ -41,4 +41,27 @@ describe NetSuite::Actions::Login do
41
41
  role: 234
42
42
  }) }.to raise_error(Savon::SOAPFault)
43
43
  end
44
+
45
+ it 'handles a login call when token based auth is in place' do
46
+ NetSuite.configure do
47
+ consumer_key '123'
48
+ consumer_secret '123'
49
+ token_id '123'
50
+ token_secret '123'
51
+
52
+ api_version '2017_2'
53
+ end
54
+
55
+ message = {"platformMsgs:passport"=>{"platformCore:email"=>"email", "platformCore:password"=>"password", "platformCore:account"=>"1234", "platformCore:role"=>234}}
56
+ savon.expects(:login).with(:message => message).returns(File.read('spec/support/fixtures/login/success.xml'))
57
+
58
+ result = NetSuite::Actions::Login.call({
59
+ email: 'email',
60
+ password: 'password',
61
+ role: 234
62
+ })
63
+
64
+ expect(result.success?).to eq(true)
65
+ expect(result.body[:user_id]).to_not be_nil
66
+ end
44
67
  end
@@ -19,6 +19,48 @@ describe NetSuite::Actions::Update do
19
19
  }
20
20
  end
21
21
 
22
+ describe 'updating the external ID' do
23
+ let(:response) { NetSuite::Response.new(:success => true, :body => { :internal_id => '1' }) }
24
+
25
+ # https://github.com/NetSweet/netsuite/pull/416
26
+ # if the external ID is set, and the external ID field is ommitted on an update, the external ID field does not change
27
+ # if the external_id field is set to nil, it should not be passed to netsuite
28
+ # passing an empty string to the external ID field does not remove it
29
+
30
+ it 'does not pass the external ID to an update call if not modified or included in update options' do
31
+ expect(NetSuite::Actions::Update).to receive(:call).
32
+ with([customer.class, {}], {}).
33
+ and_return(response)
34
+
35
+ expect(customer.update).to be_truthy
36
+ end
37
+
38
+ it 'should update the external ID when the attribute on the record is set' do
39
+ expect(NetSuite::Actions::Update).to receive(:call).
40
+ with([customer.class, {external_id: 'foo'}], {}).
41
+ and_return(response)
42
+
43
+ customer.external_id = 'foo'
44
+ expect(customer.update).to be_truthy
45
+ end
46
+
47
+ it 'should update the external ID to nil when the attribute on the record is set' do
48
+ expect(NetSuite::Actions::Update).to receive(:call).
49
+ with([customer.class, {external_id: nil}], {}).
50
+ and_return(response)
51
+
52
+ expect(customer.update(external_id: nil)).to be_truthy
53
+ end
54
+
55
+ it 'should update the external ID to the options value not the attribute value' do
56
+ expect(NetSuite::Actions::Update).to receive(:call).
57
+ with([customer.class, {external_id: 'bar'}], {}).
58
+ and_return(response)
59
+
60
+ customer.external_id = 'foo'
61
+ expect(customer.update(external_id: 'bar')).to be_truthy
62
+ end
63
+ end
22
64
 
23
65
  context 'when successful' do
24
66
 
@@ -134,6 +134,16 @@ describe NetSuite::Records::Address do
134
134
  expect(addressbook.country.to_record).to eql ""
135
135
  expect(addressbook.to_record["platformCommon:country"]).to eql ""
136
136
  end
137
+
138
+ it 'changes the netsuite identifier based on the current API version' do
139
+ NetSuite::Configuration.api_version = '2015_1'
140
+ addressbook = NetSuite::Records::Address.new country: "GB"
141
+ expect(addressbook.to_record["platformCommon:country"]).to eql "_unitedKingdomGB"
142
+ NetSuite::Configuration.api_version = '2018_1'
143
+
144
+ addressbook = NetSuite::Records::Address.new country: "GB"
145
+ expect(addressbook.to_record["platformCommon:country"]).to eql "_unitedKingdom"
146
+ end
137
147
  end
138
148
 
139
149
  end
@@ -57,7 +57,12 @@ describe 'basic records' do
57
57
  NetSuite::Records::LotNumberedAssemblyItem,
58
58
  NetSuite::Records::InboundShipment,
59
59
  NetSuite::Records::InterCompanyJournalEntry,
60
- NetSuite::Records::BinTransfer
60
+ NetSuite::Records::BinTransfer,
61
+ NetSuite::Records::SerializedAssemblyItem,
62
+ NetSuite::Records::CustomerStatus,
63
+ NetSuite::Records::TransactionBodyCustomField,
64
+ NetSuite::Records::TransactionColumnCustomField,
65
+ NetSuite::Records::EntityCustomField
61
66
  ]
62
67
  }
63
68
 
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe NetSuite::Records::BinNumber do
4
+ it "has all the right fields" do
5
+ bin_number = described_class.new
6
+
7
+ [:preferred_bin, :location].each do |field|
8
+ expect(bin_number).to have_field(field)
9
+ end
10
+ end
11
+
12
+ it "has all the right record refs" do
13
+ bin_number = described_class.new
14
+
15
+ expect(bin_number).to have_record_ref(:bin_number)
16
+ end
17
+
18
+ it "has the right namespace" do
19
+ bin_number = described_class.new
20
+
21
+ expect(bin_number.record_namespace).to eq('listAcct')
22
+ end
23
+ end
@@ -180,6 +180,20 @@ describe NetSuite::Records::CustomFieldList do
180
180
  script_id: "custbody_salesclassification",
181
181
  type: "platformCore:StringCustomFieldRef",
182
182
  value: "foobar"
183
+ },
184
+ {
185
+ script_id: 'custbody_multipleselectfield',
186
+ type: "platformCore:MultiSelectCustomFieldRef",
187
+ value: [
188
+ {
189
+ internal_id: 405,
190
+ type_id: 157
191
+ },
192
+ {
193
+ internal_id: 419,
194
+ type_id: 157
195
+ }
196
+ ]
183
197
  }
184
198
  ]
185
199
  }
@@ -200,9 +214,28 @@ describe NetSuite::Records::CustomFieldList do
200
214
  "@xsi:type" => "platformCore:StringCustomFieldRef",
201
215
  "platformCore:value" => "foobar",
202
216
  },
217
+ {
218
+ '@scriptId' => 'custbody_multipleselectfield',
219
+ '@xsi:type' => 'platformCore:MultiSelectCustomFieldRef',
220
+ 'platformCore:value' => [
221
+ {
222
+ :@internalId => 405,
223
+ :@typeId => "157"
224
+ },
225
+ {
226
+ :@internalId => 419,
227
+ :@typeId => "157"
228
+ }
229
+ ]
230
+ }
203
231
  ]
204
232
  }
205
233
 
234
+ # field accessors are tested elsewhere, but let's run tests here to check various field types
235
+ expect(list).to respond_to(:custbody_multipleselectfield)
236
+ expect(list).to respond_to(:custbody_salesclassification)
237
+ expect(list).to respond_to(:custentity_registeredonline)
238
+
206
239
  expect(list.to_record).to eql(record)
207
240
  expect(list.to_record.length).to eq(1)
208
241
  end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe NetSuite::Records::CustomerSalesTeamList do
4
+ let(:list) { NetSuite::Records::CustomerSalesTeamList.new }
5
+
6
+ it 'has an customer_sales_team attribute' do
7
+ expect(list.sales_team).to be_kind_of(Array)
8
+ end
9
+
10
+ describe '#to_record' do
11
+ it 'can represent itself as a SOAP record' do
12
+ list.replace_all = true
13
+
14
+ record = {
15
+ 'listRel:salesTeam' => [],
16
+ 'listRel:replaceAll' => true
17
+ }
18
+ expect(list.to_record).to eql(record)
19
+ end
20
+ end
21
+
22
+ describe "#replace_all" do
23
+ it "can be changed via accessor" do
24
+ list.replace_all = false
25
+
26
+ expect(list.replace_all).to eql(false)
27
+ end
28
+
29
+ it "coerces to a boolean" do
30
+ list.replace_all = "goober"
31
+
32
+ record = {
33
+ 'listRel:salesTeam' => [],
34
+ 'listRel:replaceAll' => true
35
+ }
36
+
37
+ expect(list.to_record).to eql(record)
38
+ end
39
+ end
40
+
41
+ end
@@ -17,7 +17,7 @@ describe NetSuite::Records::Customer do
17
17
  :opening_balance, :opening_balance_account, :opening_balance_date, :overdue_balance,
18
18
  :password, :password2, :phone, :phonetic_name, :pref_cc_processor,:print_on_check_as,
19
19
  :print_transactions, :referrer, :reminder_days, :representing_subsidiary, :require_pwd_change, :resale_number,
20
- :sales_group, :sales_readiness, :sales_team_list, :salutation, :send_email, :ship_complete,
20
+ :sales_group, :sales_readiness, :salutation, :send_email, :ship_complete,
21
21
  :stage, :start_date, :sync_partner_teams, :tax_exempt, :taxable,
22
22
  :third_party_acct, :third_party_country, :third_party_zipcode, :title, :unbilled_orders, :url,
23
23
  :vat_reg_number, :visits, :web_lead
@@ -85,6 +85,27 @@ describe NetSuite::Records::Customer do
85
85
  end
86
86
  end
87
87
 
88
+ describe '#subscriptions_list' do
89
+ it 'can be set from attributes' do
90
+ customer.subscriptions_list = {
91
+ subscriptions: [
92
+ {
93
+ :subscribed => true
94
+ }
95
+ ]
96
+ }
97
+ expect(customer.subscriptions_list).to be_kind_of(NetSuite::Records::CustomerSubscriptionsList)
98
+ expect(customer.subscriptions_list.subscriptions.length).to eql(1)
99
+ end
100
+
101
+ it 'can be set from a CustomerSubscriptionsList object' do
102
+ customer_subscriptions_list = NetSuite::Records::CustomerSubscriptionsList.new
103
+ customer.subscriptions_list = customer_subscriptions_list
104
+ expect(customer.subscriptions_list).to eql(customer_subscriptions_list)
105
+ end
106
+ end
107
+
108
+
88
109
  describe '.get' do
89
110
  context 'when the response is successful' do
90
111
  let(:response) { NetSuite::Response.new(:success => true, :body => { :is_person => true }) }
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe NetSuite::Records::CustomerSubscription do
4
+
5
+ before do
6
+ NetSuite::Configuration.api_version = '2014_2'
7
+ end
8
+
9
+ let(:attributes) do
10
+ {
11
+ :subscription => {
12
+ :subscribed => true,
13
+ :subscription => NetSuite::Records::RecordRef.new(internal_id: '123123', name: 'My Sub'),
14
+ :last_modified_date => DateTime.new(2018, 1, 1, 0, 0, 0)
15
+ }
16
+ }
17
+ end
18
+
19
+ let(:list) { NetSuite::Records::CustomerSubscription.new(attributes) }
20
+
21
+ it 'has all the right fields' do
22
+ [
23
+ :subscribed, :last_modified_date
24
+ ].each do |field|
25
+ expect(list).to have_field(field)
26
+ end
27
+
28
+ expect(list.subscription).to_not be_nil
29
+ end
30
+
31
+ describe '#initialize' do
32
+ context 'when taking in a hash of attributes' do
33
+ it 'sets the attributes for the object given the attributes hash' do
34
+ expect(list.subscription.subscribed).to eql(true)
35
+ expect(list.subscription.subscription.internal_id).to eql('123123')
36
+ expect(list.subscription.subscription.name).to eql('My Sub')
37
+ expect(list.subscription.last_modified_date).to_not be_nil
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe NetSuite::Records::CustomerSubscriptionsList do
4
+ let(:list) { NetSuite::Records::CustomerSubscriptionsList.new }
5
+
6
+ it 'has a subscriptions attribute' do
7
+ expect(list.subscriptions).to be_kind_of(Array)
8
+ end
9
+
10
+ describe '#to_record' do
11
+ it 'can represent itself as a SOAP record' do
12
+
13
+ record = {
14
+ 'listRel:subscriptions' => []
15
+ }
16
+ expect(list.to_record).to eql(record)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,34 @@
1
+ require "spec_helper"
2
+
3
+ describe NetSuite::Records::EntityCustomField do
4
+ describe ".get" do
5
+ context "success" do
6
+ let(:internal_id) { 1 }
7
+ let(:response) do
8
+ NetSuite::Response.new(
9
+ success: true,
10
+ body: {
11
+ access_level: "_edit",
12
+ field_type: "_integerNumber",
13
+ label: "Salesforce Customer ID",
14
+ show_in_list: true,
15
+ }
16
+ )
17
+ end
18
+
19
+ it "returns a EntityCustomField instance with populated fields" do
20
+ expect(NetSuite::Actions::Get)
21
+ .to receive(:call)
22
+ .with([NetSuite::Records::EntityCustomField, internal_id: internal_id], {})
23
+ .and_return(response)
24
+
25
+ record = NetSuite::Records::EntityCustomField.get(internal_id: internal_id)
26
+
27
+ expect(record.access_level).to eql("_edit")
28
+ expect(record.field_type).to eql("_integerNumber")
29
+ expect(record.label).to eql("Salesforce Customer ID")
30
+ expect(record.show_in_list).to eq(true)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -5,21 +5,23 @@ describe NetSuite::Records::PricingMatrix do
5
5
  it "behaves appropriately if it gets a hash as attributes[:pricing]" do
6
6
  # this is what savon returns if there is only one pricing strategy matrix
7
7
  # for the item:
8
- matrix = {
9
- :pricing=> {
10
- :currency=>"US Dollar",
11
- :priceLevel=>"Base Price",
12
- :priceList=>[
13
- {:price=>{:value=>12.0, :quantity=>0.0}},
14
- {:price=>{:value=>10.0, :quantity=>10.0}},
15
- {:price=>{:value=>9.0, :quantity=>100.0}},
16
- {:price=>{:value=>7.0, :quantity=>5000.0}}
17
- ]
8
+ matrix = [
9
+ {
10
+ currency: { internal_id: 1 },
11
+ price_level: { internal_id: 1 },
12
+ price_list: {
13
+ price: [
14
+ {
15
+ value: 25.0,
16
+ quantity: 0
17
+ }
18
+ ]
19
+ }
18
20
  }
19
- }
21
+ ]
20
22
 
21
- subject = NetSuite::Records::PricingMatrix.new({pricing: matrix})
22
- expect(subject.prices[0].pricing).to eq(matrix[:pricing])
23
+ subject = described_class.new({pricing: matrix})
24
+ expect(subject.pricing[0]).to be_kind_of(NetSuite::Records::Pricing)
23
25
  end
24
26
  end
25
27
  end
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+
3
+ describe NetSuite::Records::TransactionBodyCustomField do
4
+ describe ".get" do
5
+ context "success" do
6
+ let(:internal_id) { 1 }
7
+ let(:response) do
8
+ NetSuite::Response.new(
9
+ success: true,
10
+ body: {
11
+ access_level: "_edit",
12
+ field_type: "_freeFormText",
13
+ label: "Billing System Subdomain",
14
+ }
15
+ )
16
+ end
17
+
18
+ it "returns a TransactionColumnCustomField instance with populated fields" do
19
+ expect(NetSuite::Actions::Get)
20
+ .to receive(:call)
21
+ .with([NetSuite::Records::TransactionBodyCustomField, internal_id: internal_id], {})
22
+ .and_return(response)
23
+
24
+ record = NetSuite::Records::TransactionBodyCustomField.get(internal_id: internal_id)
25
+
26
+ expect(record.access_level).to eql("_edit")
27
+ expect(record.field_type).to eql("_freeFormText")
28
+ expect(record.label).to eql("Billing System Subdomain")
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+
3
+ describe NetSuite::Records::TransactionColumnCustomField do
4
+ describe ".get" do
5
+ context "success" do
6
+ let(:internal_id) { 1 }
7
+ let(:response) do
8
+ NetSuite::Response.new(
9
+ success: true,
10
+ body: {
11
+ access_level: "_none",
12
+ field_type: "_decimalNumber",
13
+ label: "Billing System Tax",
14
+ }
15
+ )
16
+ end
17
+
18
+ it "returns a TransactionColumnCustomField instance with populated fields" do
19
+ expect(NetSuite::Actions::Get)
20
+ .to receive(:call)
21
+ .with([NetSuite::Records::TransactionColumnCustomField, internal_id: internal_id], {})
22
+ .and_return(response)
23
+
24
+ record = NetSuite::Records::TransactionColumnCustomField.get(internal_id: internal_id)
25
+
26
+ expect(record.access_level).to eql("_none")
27
+ expect(record.field_type).to eql("_decimalNumber")
28
+ expect(record.label).to eql("Billing System Tax")
29
+ end
30
+ end
31
+ end
32
+ end