Class: NSConnector::Resource

Inherits:
Object
  • Object
show all
Extended by:
Attaching, ChunkedSearching, Transforming
Includes:
FieldStore
Defined in:
lib/ns_connector/resource.rb

Overview

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

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ChunkedSearching

grab_chunk, normal_search_by_chunks, search_by_chunks, threaded_search_by_chunks

Methods included from FieldStore

#create_store_accessors!

Constructor Details

#initialize(upstream_store = nil, in_netsuite = false) ⇒ Resource

Returns a new instance of Resource.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 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

Class Attribute Details

.fieldsObject (readonly)

Returns the value of attribute fields.



184
185
186
# File 'lib/ns_connector/resource.rb', line 184

def fields
  @fields
end

.sublistsObject (readonly)

Returns the value of attribute sublists.



185
186
187
# File 'lib/ns_connector/resource.rb', line 185

def sublists
  @sublists
end

.type_idObject (readonly)

Provides accessibility to class instance variables



183
184
185
# File 'lib/ns_connector/resource.rb', line 183

def type_id
  @type_id
end

Instance Attribute Details

#storeObject

Returns the value of attribute store.



23
24
25
# File 'lib/ns_connector/resource.rb', line 23

def store
  @store
end

Class Method Details

.advanced_search(filters) ⇒ Object

Perform a flexible search. It is assumed you kind of know what you’re doing here and create a filter (a SuiteScript nlobjSearchFilter)

Example

Resource.advanced_search([ [‘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



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# 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

.allObject

Retrieve all records, will most likely become a chunked search due to size



226
227
228
# File 'lib/ns_connector/resource.rb', line 226

def all
	advanced_search([])
end

.delete!(id) ⇒ Object

Delete a single ID from NetSuite

Returns

Nothing useful

Raises

Relevant exceptions on failure



191
192
193
194
195
196
197
# 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

.find(id) ⇒ Object

Retrieve a single resource from NetSuite with id



200
201
202
203
204
205
206
207
208
209
210
# 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

.find_by(field, value) ⇒ Object

Return a single resource, by searching for the given field.

Returns

A single record

Raises

NSConnector::Errors::NotFound when nothing found



215
216
217
218
219
220
221
222
# 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

.raw_search(columns, filters) ⇒ Object

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.


296
297
298
299
300
301
302
303
304
305
306
# 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

.search_by(field, value) ⇒ Object

Perform a search by field, with value matching exactly



231
232
233
# File 'lib/ns_connector/resource.rb', line 231

def search_by field, value
	advanced_search([[field, nil, 'is', value]])
end

Instance Method Details

#attach!(klass, ids, attributes = nil) ⇒ Object

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. => -5

Example

contact.attach!(Customer, [1198], => 1)

Raises:

  • (::ArgumentError)


88
89
90
91
# 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

#check_id10t_errors!Object

Just so I don’t forget to define certain things.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# 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!Object

Delete ourself from NetSuite

Returns
true

If object deleted

false

If object was not deleted as it never existed



167
168
169
170
171
172
173
174
175
176
177
178
179
# 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!(klass, ids) ⇒ Object

Detach ids on target klass to this record

Arguments
klass

Target class to detach from, i.e. Contact

ids

Array of ids to detach

Raises:

  • (::ArgumentError)


97
98
99
100
# 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

#fieldsObject

List of all fields for class



72
73
74
# File 'lib/ns_connector/resource.rb', line 72

def fields
	self.class.fields
end

#in_netsuite?Boolean

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.

Returns:

  • (Boolean)


121
122
123
# File 'lib/ns_connector/resource.rb', line 121

def in_netsuite?
	@in_netsuite
end

#inspectObject

Format an object like: ‘#<NSConnector::PseudoResource:1>’



113
114
115
# File 'lib/ns_connector/resource.rb', line 113

def inspect
	"#<NSConnector::#{self.class}:#{id.inspect}>"
end

#save!Object

Save ourself to NetSuite.

Raises

NSConnector::Errors various errors if something explodes

Returns

true



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# 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

#sublistsObject

List of all sublists for class



77
78
79
# File 'lib/ns_connector/resource.rb', line 77

def sublists
	self.class.sublists
end

#transform!(klass, &block) ⇒ Object

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.


108
109
110
# File 'lib/ns_connector/resource.rb', line 108

def transform!(klass, &block)
	self.class.transform!(klass, id, &block)
end

#type_idObject

Retrieve class’s internal id, e.g. ‘contact’ for a Contact Resource



67
68
69
# File 'lib/ns_connector/resource.rb', line 67

def type_id
	self.class.type_id
end