activenetsuite 0.1.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.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/.rspec +1 -0
  4. data/CHANGELOG +0 -0
  5. data/Gemfile +4 -0
  6. data/Gemfile.lock +51 -0
  7. data/History.txt +3 -0
  8. data/Manifest.txt +60 -0
  9. data/README.rdoc +14 -0
  10. data/Rakefile +14 -0
  11. data/activenetsuite.gemspec +30 -0
  12. data/lib/activenetsuite.rb +30 -0
  13. data/lib/activenetsuite/accounting/account.rb +11 -0
  14. data/lib/activenetsuite/accounting/non_inventory_sale_item.rb +10 -0
  15. data/lib/activenetsuite/core/custom_field_list.rb +7 -0
  16. data/lib/activenetsuite/core/custom_field_ref.rb +8 -0
  17. data/lib/activenetsuite/core/deleted_record.rb +10 -0
  18. data/lib/activenetsuite/core/get_deleted_result.rb +13 -0
  19. data/lib/activenetsuite/core/record.rb +254 -0
  20. data/lib/activenetsuite/core/record_ref.rb +35 -0
  21. data/lib/activenetsuite/core/search_record.rb +97 -0
  22. data/lib/activenetsuite/core/search_result.rb +12 -0
  23. data/lib/activenetsuite/core/status.rb +50 -0
  24. data/lib/activenetsuite/helpers/client.rb +135 -0
  25. data/lib/activenetsuite/helpers/error.rb +7 -0
  26. data/lib/activenetsuite/helpers/method_inflector.rb +78 -0
  27. data/lib/activenetsuite/helpers/response_methods.rb +21 -0
  28. data/lib/activenetsuite/helpers/search_response_methods.rb +62 -0
  29. data/lib/activenetsuite/messages/add_response.rb +8 -0
  30. data/lib/activenetsuite/messages/delete_list_response.rb +19 -0
  31. data/lib/activenetsuite/messages/delete_response.rb +8 -0
  32. data/lib/activenetsuite/messages/get_deleted_response.rb +23 -0
  33. data/lib/activenetsuite/messages/get_deleted_result.rb +21 -0
  34. data/lib/activenetsuite/messages/get_response.rb +13 -0
  35. data/lib/activenetsuite/messages/read_response.rb +7 -0
  36. data/lib/activenetsuite/messages/search_more_with_id_response.rb +8 -0
  37. data/lib/activenetsuite/messages/search_response.rb +8 -0
  38. data/lib/activenetsuite/messages/update_response.rb +8 -0
  39. data/lib/activenetsuite/messages/write_response.rb +16 -0
  40. data/lib/activenetsuite/relationships/partner.rb +18 -0
  41. data/lib/activenetsuite/relationships/vendor.rb +14 -0
  42. data/lib/activenetsuite/sales/cash_refund.rb +12 -0
  43. data/lib/activenetsuite/sales/cash_sale.rb +12 -0
  44. data/lib/activenetsuite/soap/NetSuiteServiceClient.rb +978 -0
  45. data/lib/activenetsuite/soap/default.rb +68163 -0
  46. data/lib/activenetsuite/soap/defaultDriver.rb +419 -0
  47. data/lib/activenetsuite/soap/defaultMappingRegistry.rb +62549 -0
  48. data/lib/activenetsuite/version.rb +3 -0
  49. data/spec/lib/activenetsuite/accounting/non_inventory_sale_item_spec.rb +9 -0
  50. data/spec/lib/activenetsuite/core/record_ref_spec.rb +56 -0
  51. data/spec/lib/activenetsuite/core/record_spec.rb +298 -0
  52. data/spec/lib/activenetsuite/core/search_record_spec.rb +50 -0
  53. data/spec/lib/activenetsuite/core/search_result_spec.rb +26 -0
  54. data/spec/lib/activenetsuite/helpers/client_spec.rb +115 -0
  55. data/spec/lib/activenetsuite/helpers/method_inflector_spec.rb +85 -0
  56. data/spec/lib/activenetsuite/helpers/search_response_methods_spec.rb +50 -0
  57. data/spec/lib/activenetsuite/messages/search_response_spec.rb +5 -0
  58. data/spec/lib/activenetsuite/relationships/partner_spec.rb +22 -0
  59. data/spec/lib/activenetsuite/relationships/vendor_spec.rb +14 -0
  60. data/spec/lib/activenetsuite/sales/cash_refund_spec.rb +10 -0
  61. data/spec/lib/activenetsuite/sales/cash_sale_spec.rb +10 -0
  62. data/spec/spec_helper.rb +17 -0
  63. metadata +138 -0
@@ -0,0 +1,35 @@
1
+ module ActiveNetsuite
2
+
3
+ class RecordRef < BaseRef
4
+ alias_method :internal_id, :xmlattr_internalId
5
+ alias_method :internal_id=, :xmlattr_internalId=
6
+ alias_method :external_id, :xmlattr_externalId
7
+ alias_method :external_id=, :xmlattr_externalId=
8
+ alias_method :type, :xmlattr_type
9
+ alias_method :type=, :xmlattr_type=
10
+
11
+ def ==(other)
12
+ self.type == other.type &&
13
+ self.internal_id == other.internal_id &&
14
+ self.external_id == other.external_id
15
+ end
16
+
17
+ def record
18
+ rec = record_class.new
19
+ rec.internal_id = internal_id
20
+ rec.external_id = external_id
21
+ rec
22
+ end
23
+
24
+ def delete
25
+ Record.delete([self])
26
+ end
27
+
28
+ private
29
+
30
+ def record_class
31
+ ('::ActiveNetsuite::' + type.camelize).constantize
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,97 @@
1
+ module ActiveNetsuite
2
+
3
+ class SearchRecord
4
+ extend Forwardable
5
+ include Enumerable
6
+
7
+ attr_accessor :record_class
8
+
9
+ def_delegators :response, :page_index, :page_size, :search_id, :total_pages,
10
+ :total_records, :has_more?, :next
11
+
12
+ def each
13
+ response.each do |result|
14
+ yield result if block_given?
15
+ end
16
+ end
17
+
18
+ def where(*args)
19
+ dup.send(:add, *args)
20
+ end
21
+
22
+ def find_by(*args)
23
+ where(*args).first
24
+ end
25
+
26
+ def to_a
27
+ response.to_a
28
+ end
29
+
30
+ def inactive
31
+ dup.send(:add, isInactive: true)
32
+ end
33
+
34
+ def active
35
+ dup.send(:add, isInactive: false)
36
+ end
37
+
38
+ def response
39
+ @response ||= client.search(self)
40
+ end
41
+
42
+ private
43
+
44
+ attr_reader :method, :value, :op
45
+
46
+ def client
47
+ Record.client
48
+ end
49
+
50
+ def add(*args)
51
+ if args.first.is_a?(Hash)
52
+ @method, @value = args.first.flatten
53
+ @op = :is
54
+ end
55
+ if args.size == 3
56
+ @method, @op, @value = args
57
+ end
58
+
59
+ method = record_class.inflected_method(@method)
60
+ send("#{method}=", search_class.new)
61
+ unless value == true || value == false
62
+ send(method).xmlattr_operator = search_operator
63
+ end
64
+ send(method).searchValue = value
65
+
66
+ self
67
+ end
68
+
69
+ def search_class
70
+ case value
71
+ when String
72
+ SearchStringField
73
+ when Fixnum
74
+ SearchLongField
75
+ when TrueClass, FalseClass
76
+ SearchBooleanField
77
+ when Date, DateTime
78
+ SearchDateField
79
+ else
80
+ raise ArgumentError, "Can't find search class for #{value.inspect}"
81
+ end
82
+ end
83
+
84
+ def search_operator
85
+ operator_constant_name = op.to_s.camelize
86
+ operator_class_name = search_class.to_s + "Operator"
87
+ "#{operator_class_name}::#{operator_constant_name}".constantize
88
+ end
89
+
90
+ def record_class
91
+ @record_class
92
+ #"::#{self.class.to_s.gsub(/SearchBasic$/, '')}".constantize
93
+ end
94
+ end
95
+
96
+ end
97
+
@@ -0,0 +1,12 @@
1
+ module ActiveNetsuite
2
+
3
+ class SearchResult
4
+ include MethodInflector
5
+
6
+ def has_more?
7
+ page_index < total_pages
8
+ end
9
+ end
10
+
11
+ end
12
+
@@ -0,0 +1,50 @@
1
+ module ActiveNetsuite
2
+
3
+ class Status
4
+ DUP_ITEM = 'DUP_ITEM'
5
+ DUP_RCRD = 'DUP_RCRD'
6
+ DUP_ENTITY = 'DUP_ENTITY'
7
+ DUP_VENDOR_NAME = 'DUP_VENDOR_NAME'
8
+ RCRD_TYPE_REQD = 'RCRD_TYPE_REQD'
9
+ USER_ERROR = 'USER_ERROR'
10
+ MAX_RCRDS_EXCEEDED = 'MAX_RCRDS_EXCEEDED'
11
+ INVALID_INTERNALID = 'INVALID_INTERNALID'
12
+ INVALID_FLD_VALUE = 'INVALID_FLD_VALUE'
13
+
14
+ def success?
15
+ xmlattr_isSuccess
16
+ end
17
+
18
+ def failure?
19
+ !success?
20
+ end
21
+
22
+ def code
23
+ status_detail.code if status_detail
24
+ end
25
+
26
+ def message
27
+ status_detail.message if status_detail
28
+ end
29
+
30
+ constants.each do |constant|
31
+ name = (constant.to_s.underscore + '?').to_sym
32
+ value = const_get(constant)
33
+ next unless value.is_a?(String)
34
+ define_method name do
35
+ code == value
36
+ end
37
+ end
38
+
39
+ def duplicate?
40
+ dup_item? || dup_rcrd? || dup_entity? || dup_vendor_name?
41
+ end
42
+
43
+ private
44
+
45
+ def status_detail
46
+ statusDetail[0] if statusDetail
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,135 @@
1
+ require 'logger'
2
+ require 'net/http'
3
+ require 'net/https'
4
+ require 'soap/header/simplehandler'
5
+
6
+ module ActiveNetsuite
7
+
8
+ class Client
9
+ attr_reader :driver
10
+
11
+ class ActiveNetsuiteHeader < SOAP::Header::SimpleHandler
12
+ def initialize(prefs = {})
13
+ @prefs = self.class::DefaultPrefs.merge(prefs)
14
+ super(XSD::QName.new(nil, self.class::Name))
15
+ end
16
+
17
+ def on_simple_outbound
18
+ @prefs
19
+ end
20
+ end
21
+
22
+ class SearchPreferencesHeaderHandler < ActiveNetsuiteHeader
23
+ Name = 'searchPreferences'
24
+ DefaultPrefs = {:bodyFieldsOnly => false, :pageSize => 25}
25
+ end
26
+
27
+ class PreferencesHeaderHandler < ActiveNetsuiteHeader
28
+ Name = 'preferences'
29
+ DefaultPrefs = {:warningAsError => false, :ignoreReadOnlyFields => true}
30
+ end
31
+
32
+ class PassportHeaderHandler < ActiveNetsuiteHeader
33
+ Name = 'passport'
34
+ DefaultPrefs = {:account => '', :email => '', :password => ''}
35
+ end
36
+
37
+ def logger
38
+ @logger ||= Logger.new(STDOUT)
39
+ end
40
+
41
+ def initialize(config = {})
42
+ @driver = ActiveNetsuitePortType.new(config[:endpoint_url] ||
43
+ ActiveNetsuitePortType::DefaultEndpointUrl)
44
+
45
+ if config[:role]
46
+ role = {:xmlattr_internalId => config[:role]}
47
+ end
48
+
49
+ @driver.headerhandler.add(PassportHeaderHandler.new(
50
+ email: config[:email],
51
+ password: config[:password],
52
+ account: config[:account_id],
53
+ role: role
54
+ ))
55
+ @driver.headerhandler.add(PreferencesHeaderHandler.new)
56
+ @driver.headerhandler.add(SearchPreferencesHeaderHandler.new)
57
+ end
58
+
59
+ def debug=(debug)
60
+ @driver.wiredump_dev = ($stderr if debug)
61
+ end
62
+
63
+ # Low level commands
64
+ def get(ref)
65
+ @driver.get(GetRequest.new(ref))
66
+ end
67
+
68
+ def get_all(refs)
69
+ @driver.getList(GetListRequest.new(refs))
70
+ end
71
+
72
+ def get_all_records(record_type)
73
+ ref = GetAllRecord.new
74
+ ref.xmlattr_recordType = record_type
75
+ get_all(ref)
76
+ end
77
+
78
+ def get_all(ref)
79
+ @driver.getAll(GetAllRequest.new(ref))
80
+ end
81
+
82
+ def add(record)
83
+ @driver.add(AddRequest.new(record))
84
+ end
85
+
86
+ def add_list(list)
87
+ @driver.addList(AddListRequest.new(list))
88
+ end
89
+
90
+ def update(record)
91
+ @driver.update(UpdateRequest.new(record))
92
+ end
93
+
94
+ def update_list(recs)
95
+ @driver.updateList(UpdateListRequest.new(recs))
96
+ end
97
+
98
+ def upsert(record)
99
+ @driver.upsert(UpsertRequest.new(record))
100
+ end
101
+
102
+ def upsert_list(refs)
103
+ @driver.upsertList(UpsertListRequest.new(refs))
104
+ end
105
+
106
+ def delete(ref)
107
+ @driver.delete(DeleteRequest.new(ref))
108
+ end
109
+
110
+ def delete_list(refs)
111
+ @driver.deleteList(DeleteListRequest.new(refs))
112
+ end
113
+
114
+ def search(search_record)
115
+ @driver.search(SearchRequest.new(search_record))
116
+ end
117
+
118
+ def search_next(search_response, page_index = search.page_index + 1)
119
+ @driver.searchMoreWithId(
120
+ searchId: search_response.search_id,
121
+ pageIndex: page_index
122
+ )
123
+ end
124
+
125
+ def search_all(search_record)
126
+ search(search_record) +
127
+ (@res.searchResult.totalPages-1).times.map { |page_index| search_next }
128
+ end
129
+
130
+ def get_deleted(get_deleted_filter)
131
+ @driver.getDeleted(GetDeletedRequest.new(get_deleted_filter))
132
+ end
133
+ end
134
+
135
+ end
@@ -0,0 +1,7 @@
1
+ module ActiveNetsuite
2
+
3
+ class NotFoundError < StandardError
4
+ end
5
+
6
+ end
7
+
@@ -0,0 +1,78 @@
1
+ module ActiveNetsuite
2
+
3
+ module MethodInflector
4
+ def method_missing(method, *args, &block)
5
+ if self.class.inflected_method_valid?(method)
6
+ send self.class.inflected_method(method), *args, &block
7
+ else
8
+ super
9
+ end
10
+ end
11
+
12
+ def self.included(base)
13
+ base.extend(ClassMethods)
14
+ end
15
+
16
+ module ClassMethods
17
+ def inflected_method(method)
18
+ @method = method
19
+
20
+ case
21
+ when xmlattr_method?
22
+ convert_xmlattr_method
23
+ when special_method?
24
+ convert_special_method
25
+ else
26
+ convert_regular_method
27
+ end
28
+ remove_instance_variable(:@method)
29
+ end
30
+
31
+ def inflected_method_valid?(method)
32
+ instance_methods(false).include?(inflected_method(method))
33
+ end
34
+
35
+ private
36
+
37
+ def convert_regular_method
38
+ @method = 'is_' + @method.to_s[0..-2] if @method.to_s.end_with?('?')
39
+ @method = @method.to_s.camelize(:lower).to_sym
40
+ end
41
+
42
+ def convert_xmlattr_method
43
+ @method = ('xmlattr_' + @method.to_s.camelize(:lower)).to_sym
44
+ end
45
+
46
+ def convert_special_method
47
+ @method = special_methods_map[@method]
48
+ end
49
+
50
+ def special_methods_map
51
+ {
52
+ custom_fields: :customFieldList
53
+ }
54
+ end
55
+
56
+ def special_method?
57
+ special_methods_map.keys.include?(@method)
58
+ end
59
+
60
+ def xmlattr_method?
61
+ xmlattr_methods.include?(@method)
62
+ end
63
+
64
+ def xmlattr_methods
65
+ xmlattr_getters + xmlattr_setters
66
+ end
67
+
68
+ def xmlattr_getters
69
+ %i(internal_id external_id script_id)
70
+ end
71
+
72
+ def xmlattr_setters
73
+ xmlattr_getters.map { |getter| (getter.to_s + '=').to_sym }
74
+ end
75
+ end
76
+ end
77
+
78
+ end
@@ -0,0 +1,21 @@
1
+ module ActiveNetsuite
2
+
3
+ module ResponseMethods
4
+ extend Forwardable
5
+
6
+ def res
7
+ writeResponse
8
+ end
9
+
10
+ def_delegators :res, :status, :ref
11
+
12
+ def_delegators :status,
13
+ :success?, :failure?, :code, :message, :dup_item?, :dup_rcrd?,
14
+ :dup_entity?, :dup_vendor_name?, :rcrd_type_reqd?, :user_error?,
15
+ :duplicate?
16
+
17
+ def_delegators :ref, :internal_id, :external_id, :type
18
+ end
19
+
20
+ end
21
+