class NSConnector::Resource
This is a 'meta' class that all our useful NetSuite classes inherit from, overriding what they may need to. For example:
class Contact < Resource # The NetSuite internal id for the object. @type_id = 'contact' end
Attributes
Provides accessibility to class instance variables
Public Class Methods
Perform a flexible search. It is assumed you kind of know what you're doing here and create a filter (a SuiteScript nlobjSearchFilter)
- Example
-
['type_id', nil, 'greaterthan', 1000], ['email', nil, 'contains', '@'], [...]
])
- Arguments
filters
-
An array of netsuite 'filters' see:
Filters
- Filters
-
A filter is simply an array that is sent as arguments to the netsuite function
nlobjSearchFilter
It often takes the form of:
[field, join record type or nil, operator, value]
i.e:
['internalid', nil, 'is', customer_id]
- Returns
-
An array of
Resources
# File lib/ns_connector/resource.rb, line 259 def advanced_search filters unless filters.is_a? Array raise ::ArgumentError, 'Expected an Array of filters' end return NSConnector::Restlet.execute!( :action => 'search', :type_id => type_id, :fields => fields, :data => {:filters => filters} ).map do |upstream_store| self.new(upstream_store, true) end rescue NSConnector::Errors::BeginChunking # Result set is too large, we have to ask for # it in offsets. Note that if the result set # changes between requests say, at the # beginning, we are going to get odd behaviour. # Better than nothing, though. # # For this function, see: # ns_connector/chunked_searching.rb return search_by_chunks(filters) end
Retrieve all records, will most likely become a chunked search due to size
# File lib/ns_connector/resource.rb, line 226 def all advanced_search([]) end
Delete a single ID from NetSuite
- Returns
-
Nothing useful
- Raises
-
Relevant exceptions on failure
# File lib/ns_connector/resource.rb, line 191 def delete! id NSConnector::Restlet.execute!( :action => 'delete', :type_id => type_id, :data => {'id' => Integer(id)} ) end
Retrieve a single resource from NetSuite with id
# File lib/ns_connector/resource.rb, line 200 def find id self.new( NSConnector::Restlet.execute!( :action => 'retrieve', :type_id => type_id, :fields => fields, :data => {'id' => Integer(id)} ), true ) end
Return a single resource, by searching for the given field.
- Returns
-
A single record
- Raises
-
NSConnector::Errors::NotFound when nothing found
# File lib/ns_connector/resource.rb, line 215 def find_by(field, value) results = search_by(field, value) unless results.empty? then return results.first else raise NSConnector::Errors::NotFound end end
# File lib/ns_connector/resource.rb, line 25 def initialize upstream_store=nil, in_netsuite=false upstream_store.stringify_keys! if upstream_store @store = (upstream_store || {}) @sublist_store = {} # This is set so that we can tell wether we need to create an # entirely new netstuite object, or we are modifying an # existing one. @in_netsuite = in_netsuite check_id10t_errors! create_store_accessors! create_sublist_accessors! end
Quicker and more flexible than a normal search as it doesn't return whole objects, just the search columns specified as an array of arrays.
- Arguments
- columns
-
Array of requested colums, e.g.:
[['role'], ['entityId', 'customer']]
- filters
-
Array of filters, same as advanced_search, e.g.:
[['entityId', 'customer', 'is', '296']]
- Returns
-
Array of result columns, in an array. So an array
of arrays.
# File lib/ns_connector/resource.rb, line 296 def raw_search columns, filters return NSConnector::Restlet.execute!( :action => 'raw_search', :type_id => type_id, :fields => fields, :data => { :columns => columns, :filters => filters } ) end
Perform a search by field, with value matching exactly
# File lib/ns_connector/resource.rb, line 231 def search_by field, value advanced_search([[field, nil, 'is', value]]) end
Public Instance Methods
Attach ids on target klass to this record
- Arguments
- klass
-
Target class to attach to, e.g. Contact
- ids
-
Array of ids to attach
- attributes
-
Optional attributes for attach, e.g. {:role => -5}
- Example
-
contact.attach!(Customer, [1198], {:role => 1})
# File lib/ns_connector/resource.rb, line 88 def attach!(klass, ids, attributes=nil) raise ::ArgumentError, 'Need an id to attach!' unless id self.class.attach!(klass, id, ids, attributes) end
Just so I don't forget to define certain things.
# File lib/ns_connector/resource.rb, line 42 def check_id10t_errors! unless fields then raise ::ArgumentError, "Inherited class #{self.class} needs to "\ "define @fields class instance variable" end # Type doesn't matter unless fields.include? 'id' or fields.include? :id raise ::ArgumentError, "Inherited class #{self.class} must define "\ "an 'id' field" end unless type_id then raise ::ArgumentError, "Inherited class #{self.class} needs to "\ "define @type_id class instance variable" end unless sublists then raise ::ArgumentError, "Inherited class #{self.class} needs to "\ "define @sublists class instance variable" end end
Delete ourself from NetSuite
- Returns
- true
-
If object deleted
- false
-
If object was not deleted as it never existed
# File lib/ns_connector/resource.rb, line 167 def delete! return false unless in_netsuite? fail 'Sanity check: resource should have an ID' unless id self.class.delete!(id) # We set our :id to nil as we don't have one anymore and it # allows us to call save on our newly deleted record, in case # we wanted to undelete or something crazy like that. @store[:id] = nil @in_netsuite = false return true end
Detach ids on target klass to this record
- Arguments
- klass
-
Target class to detach from, i.e. Contact
- ids
-
Array of ids to detach
# File lib/ns_connector/resource.rb, line 97 def detach!(klass, ids) raise ::ArgumentError, 'Need an id to detach!' unless id self.class.detach!(klass, id, ids) end
List of all fields for class
# File lib/ns_connector/resource.rb, line 72 def fields self.class.fields end
Is this resource already in NetSuite?
- Returns
- true
-
if this resource has been retrieved from netsuite,
- false
-
if it is a new resource being created for the first time.
# File lib/ns_connector/resource.rb, line 121 def in_netsuite? @in_netsuite end
Format an object like: '#<NSConnector::PseudoResource:1>'
# File lib/ns_connector/resource.rb, line 113 def inspect "#<NSConnector::#{self.class}:#{id.inspect}>" end
Save ourself to NetSuite.
- Raises
-
NSConnector::Errors
various errors if something explodes - Returns
-
true
# File lib/ns_connector/resource.rb, line 129 def save! # Convert all of our sublist objects to hashes sublist_data = Hash[@sublist_store.map {|sublist_id, objects| [sublist_id, objects.map {|object| object.to_hash }] }] @store = NSConnector::Restlet.execute!( :action => in_netsuite? ? 'update' : 'create', :type_id => type_id, :fields => fields, :data => @store, :sublists => sublist_data, ) # If we got this far, we're probably in NetSuite @in_netsuite = true # Now we save our sublist(s) @sublist_store.each do |sublist_id, sublist_items| # Overwriting the current item @sublist_store[sublist_id] = NSConnector::SubList.save!( sublist_items, self, sublist_id, sublists[sublist_id] ) end return true end
List of all sublists for class
# File lib/ns_connector/resource.rb, line 77 def sublists self.class.sublists end
Transform this instance into target klass
- Arguments
- klass
-
Target class, e.g. CustomerPayment
- &block
-
optional block, will recieve an instance of target klass
to perform optional modifications to the object before it is saved in NetSuite, like setting payment details.
# File lib/ns_connector/resource.rb, line 108 def transform!(klass, &block) self.class.transform!(klass, id, &block) end
Retrieve class's internal id, e.g. 'contact' for a Contact Resource
# File lib/ns_connector/resource.rb, line 67 def type_id self.class.type_id end
Private Instance Methods
Given a sublist of {:addressbook => ['fields']} we want a method addressbook that looks up the sublist if we have an ID, otherwise returns the empty array.
And finally we need a method to create new sublist objects that is generic and not too crazy. So we have new_addressbook that returns a SubList object that can be stored and later turned into a hash to send to NetSuite.
# File lib/ns_connector/resource.rb, line 318 def create_sublist_accessors! sublists.each do |sublist_name, fields| self.class.class_eval do define_method sublist_name do # We are an object in netsuite, # we might just have sublist # items already. So we check. @sublist_store[sublist_name] ||= \ NSConnector::SubList.fetch( self, sublist_name, fields ) if in_netsuite? @sublist_store[sublist_name] ||= [] end define_method("#{sublist_name}=") do |value| @sublist_store[sublist_name] = value end define_method( "new_#{sublist_name}_item" ) do |upstream_store = nil| NSConnector::SubListItem.new( sublist_name, fields, self, upstream_store ) end end end end