alula-ruby 0.50.1
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.
- checksums.yaml +7 -0
- data/.circleci/config.yml +14 -0
- data/.env.example +8 -0
- data/.github/workflows/gem-push.yml +45 -0
- data/.gitignore +23 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/Dockerfile +6 -0
- data/Gemfile +12 -0
- data/Guardfile +42 -0
- data/README.md +423 -0
- data/Rakefile +6 -0
- data/VERSION.md +84 -0
- data/alula-docker-compose.yml +80 -0
- data/alula.gemspec +38 -0
- data/bin/console +15 -0
- data/bin/docparse +36 -0
- data/bin/genresource +79 -0
- data/bin/setup +8 -0
- data/bin/testauth +24 -0
- data/bin/testprep +9 -0
- data/data/docs/Alula_API_Documentation_2021-04-06.html +16240 -0
- data/docker-compose.yml +11 -0
- data/lib/alula/alula_response.rb +20 -0
- data/lib/alula/api_operations/delete.rb +52 -0
- data/lib/alula/api_operations/list.rb +45 -0
- data/lib/alula/api_operations/request.rb +44 -0
- data/lib/alula/api_operations/save.rb +81 -0
- data/lib/alula/api_resource.rb +196 -0
- data/lib/alula/client.rb +142 -0
- data/lib/alula/errors.rb +169 -0
- data/lib/alula/filter_builder.rb +271 -0
- data/lib/alula/helpers/device_attribute_translations.rb +68 -0
- data/lib/alula/list_object.rb +64 -0
- data/lib/alula/meta.rb +16 -0
- data/lib/alula/monkey_patches.rb +24 -0
- data/lib/alula/oauth.rb +118 -0
- data/lib/alula/pagination.rb +25 -0
- data/lib/alula/procedures/dealer_device_stats_proc.rb +16 -0
- data/lib/alula/procedures/dealer_restore_proc.rb +25 -0
- data/lib/alula/procedures/dealer_suspend_proc.rb +25 -0
- data/lib/alula/procedures/device_assign_proc.rb +23 -0
- data/lib/alula/procedures/device_cellular_history_proc.rb +33 -0
- data/lib/alula/procedures/device_rateplan_get_proc.rb +21 -0
- data/lib/alula/procedures/device_register_proc.rb +31 -0
- data/lib/alula/procedures/device_signal_add_proc.rb +42 -0
- data/lib/alula/procedures/device_signal_delivered_proc.rb +31 -0
- data/lib/alula/procedures/device_signal_update_proc.rb +32 -0
- data/lib/alula/procedures/device_unassign_proc.rb +16 -0
- data/lib/alula/procedures/device_unregister_proc.rb +21 -0
- data/lib/alula/procedures/upload_touchpad_branding_proc.rb +24 -0
- data/lib/alula/procedures/user_plansvideo_price_get.rb +21 -0
- data/lib/alula/procedures/user_transfer_accept.rb +19 -0
- data/lib/alula/procedures/user_transfer_authorize.rb +18 -0
- data/lib/alula/procedures/user_transfer_cancel.rb +18 -0
- data/lib/alula/procedures/user_transfer_deny.rb +19 -0
- data/lib/alula/procedures/user_transfer_reject.rb +19 -0
- data/lib/alula/procedures/user_transfer_request.rb +19 -0
- data/lib/alula/query_interface.rb +142 -0
- data/lib/alula/rate_limit.rb +11 -0
- data/lib/alula/relationship_attributes.rb +107 -0
- data/lib/alula/resource_attributes.rb +206 -0
- data/lib/alula/resources/admin_user.rb +207 -0
- data/lib/alula/resources/billing_program.rb +41 -0
- data/lib/alula/resources/dealer.rb +218 -0
- data/lib/alula/resources/dealer_account_transfer.rb +172 -0
- data/lib/alula/resources/dealer_address.rb +89 -0
- data/lib/alula/resources/dealer_branding.rb +226 -0
- data/lib/alula/resources/dealer_program.rb +75 -0
- data/lib/alula/resources/dealer_suspension_log.rb +49 -0
- data/lib/alula/resources/device.rb +716 -0
- data/lib/alula/resources/device_cellular_status.rb +134 -0
- data/lib/alula/resources/device_charge.rb +70 -0
- data/lib/alula/resources/device_event_log.rb +167 -0
- data/lib/alula/resources/device_program.rb +54 -0
- data/lib/alula/resources/event_trigger.rb +75 -0
- data/lib/alula/resources/event_webhook.rb +47 -0
- data/lib/alula/resources/feature_bysubject.rb +74 -0
- data/lib/alula/resources/feature_plan.rb +57 -0
- data/lib/alula/resources/feature_planvideo.rb +54 -0
- data/lib/alula/resources/feature_price.rb +46 -0
- data/lib/alula/resources/receiver_connection.rb +95 -0
- data/lib/alula/resources/receiver_group.rb +74 -0
- data/lib/alula/resources/revision.rb +91 -0
- data/lib/alula/resources/self.rb +61 -0
- data/lib/alula/resources/station.rb +130 -0
- data/lib/alula/resources/token_exchange.rb +34 -0
- data/lib/alula/resources/user.rb +229 -0
- data/lib/alula/resources/user_address.rb +121 -0
- data/lib/alula/resources/user_phone.rb +116 -0
- data/lib/alula/resources/user_preferences.rb +57 -0
- data/lib/alula/resources/user_pushtoken.rb +75 -0
- data/lib/alula/resources/user_videoprofile.rb +38 -0
- data/lib/alula/rest_resource.rb +17 -0
- data/lib/alula/rpc_resource.rb +40 -0
- data/lib/alula/rpc_response.rb +14 -0
- data/lib/alula/singleton_rest_resource.rb +26 -0
- data/lib/alula/util.rb +107 -0
- data/lib/alula/version.rb +5 -0
- data/lib/alula.rb +135 -0
- data/lib/parser.rb +199 -0
- metadata +282 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
module Alula
|
|
2
|
+
class QueryInterface
|
|
3
|
+
extend Forwardable
|
|
4
|
+
|
|
5
|
+
def initialize(model_class)
|
|
6
|
+
@model_class = model_class
|
|
7
|
+
@filter_builder = Alula::FilterBuilder.new(model_class, self)
|
|
8
|
+
@filter = {}
|
|
9
|
+
@page = {}
|
|
10
|
+
@custom_options = {}
|
|
11
|
+
@includes = {}
|
|
12
|
+
@opts = {}
|
|
13
|
+
@sorts = {}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def filter(filter_hash)
|
|
17
|
+
@filter = Util.deep_merge @filter, filter_hash
|
|
18
|
+
self
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def filter_builder(&block)
|
|
22
|
+
if block_given?
|
|
23
|
+
yield @filter_builder
|
|
24
|
+
@filter = Util.deep_merge(@filter, @filter_builder.as_json)
|
|
25
|
+
self
|
|
26
|
+
else
|
|
27
|
+
@filter_builder
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def_delegators :filter_builder, :where, :and, :not, :ne, :or, :between, :not_between,
|
|
32
|
+
:builder, :gt, :gte, :lt, :lte, :like, :not_like, :in,
|
|
33
|
+
:not_in, :sort
|
|
34
|
+
|
|
35
|
+
def offset(offset)
|
|
36
|
+
@page = Util.deep_merge(@page, {
|
|
37
|
+
page: {
|
|
38
|
+
number: offset,
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
self
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def limit(limit)
|
|
45
|
+
@page = Util.deep_merge(@page, {
|
|
46
|
+
page: {
|
|
47
|
+
size: limit
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
self
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def custom_options(**options)
|
|
54
|
+
@custom_options = Util.deep_merge(@custom_options, {
|
|
55
|
+
customOptions: options
|
|
56
|
+
})
|
|
57
|
+
self
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def include_relationships
|
|
61
|
+
custom_options(omitRelationships: false)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def includes(*relationships)
|
|
65
|
+
relationships = @model_class.get_relationships.keys if relationships == [:all]
|
|
66
|
+
|
|
67
|
+
validated_relationships = relationships.map do |relationship|
|
|
68
|
+
@model_class.check_relationship!(relationship)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
@includes = Util.deep_merge(@includes, {
|
|
72
|
+
include: validated_relationships.compact.map { |r| Util.camelize(r) }.join(',')
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
self
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def query_sort(options)
|
|
79
|
+
cleaned_sorts = options.each_pair.each_with_object([]) do |(key, value), collector|
|
|
80
|
+
collector << "#{value == :desc ? '-' : ''}#{key}"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
@sorts = Util.deep_merge(@sorts, {
|
|
84
|
+
sort: cleaned_sorts.join(',')
|
|
85
|
+
})
|
|
86
|
+
self
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def as_json
|
|
90
|
+
JSON.parse(to_json)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def to_json
|
|
94
|
+
JSON.generate(built_query_options)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def list(opts = {})
|
|
98
|
+
@model_class.list(built_query_options, @opts.merge(opts))
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def list_all(opts = {})
|
|
102
|
+
# We have defaults we want to use, but if the caller wants to change, we support it
|
|
103
|
+
size = @page.to_h.dig(:page, :size) || 250
|
|
104
|
+
number = @page.to_h.dig(:page, :number) || 1
|
|
105
|
+
|
|
106
|
+
return to_enum(:list_all, opts) unless block_given?
|
|
107
|
+
|
|
108
|
+
page = self.page(number: number, size: size).list(opts)
|
|
109
|
+
return page unless page.is_a? Alula::ListObject
|
|
110
|
+
|
|
111
|
+
loop do
|
|
112
|
+
yield page
|
|
113
|
+
break unless page.meta.page.has_next?
|
|
114
|
+
|
|
115
|
+
page = self.page(number: number += 1, size: size).list(opts)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def retrieve(id)
|
|
120
|
+
@model_class.retrieve(id, built_query_options)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def page(number: 1, size: 10)
|
|
124
|
+
@page = Util.deep_merge(@page, {
|
|
125
|
+
page: {
|
|
126
|
+
number: number,
|
|
127
|
+
size: size
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
self
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def built_query_options
|
|
134
|
+
built = Util.deep_merge({}, @page)
|
|
135
|
+
built = Util.deep_merge(built, @includes)
|
|
136
|
+
built = Util.deep_merge(built, @sorts)
|
|
137
|
+
built = Util.deep_merge(built, @custom_options)
|
|
138
|
+
|
|
139
|
+
Util.deep_merge(built, @filter)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Alula
|
|
2
|
+
class RateLimit
|
|
3
|
+
attr_accessor :request_limit, :requests_remaining, :reset_in
|
|
4
|
+
|
|
5
|
+
def initialize(headers)
|
|
6
|
+
self.request_limit = headers["x-rate-limit-limit"].to_i
|
|
7
|
+
self.requests_remaining = headers["x-rate-limit-remaining"].to_i
|
|
8
|
+
self.reset_in = headers["x-rate-limit-reset"].to_i
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
module Alula
|
|
2
|
+
module RelationshipAttributes
|
|
3
|
+
def self.extended(base)
|
|
4
|
+
base.class_eval do
|
|
5
|
+
@relationships = {}
|
|
6
|
+
end
|
|
7
|
+
base.include(InstanceMethods)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# TODO: Walk the relationships and define methods to allow an instance to
|
|
11
|
+
# request a relationship with dot notation... Dealer.fetch(id).devices, etc
|
|
12
|
+
def relationship(name, **opts)
|
|
13
|
+
@relationships ||= {}
|
|
14
|
+
@relationships[name] = opts.merge(name: name)
|
|
15
|
+
|
|
16
|
+
# Define a getter for our relationship name
|
|
17
|
+
instance_eval do
|
|
18
|
+
define_method(name) do
|
|
19
|
+
@related_models[name]
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
if opts[:cardinality] == 'To-one'
|
|
24
|
+
instance_eval do
|
|
25
|
+
define_method("#{name}=") do |new_model|
|
|
26
|
+
@related_models[name] = new_model
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
elsif opts[:cardinality] == 'To-many'
|
|
30
|
+
instance_eval do
|
|
31
|
+
define_method("#{name}<<") do |new_model|
|
|
32
|
+
@related_models[name] ||= ListObject.new(self.class)
|
|
33
|
+
@related_models[name] << new_model
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
@relationships
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def get_relationships
|
|
42
|
+
@relationships
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def get_relationship(name)
|
|
46
|
+
identifier = name.is_a?(Symbol) ? :name : :type
|
|
47
|
+
relationship = get_relationships.find { |_key, opts| opts[identifier] == name }
|
|
48
|
+
raise "Unknown relationship #{identifier} #{name} for class #{self}" unless relationship
|
|
49
|
+
relationship.last
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def relationship_exists?(possible_r)
|
|
53
|
+
get_relationships.keys.include?(possible_r.to_sym)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def check_relationship!(possible_r)
|
|
57
|
+
cleaned_relationship = Util.underscore(possible_r).to_sym
|
|
58
|
+
|
|
59
|
+
unless self.relationship_exists?(cleaned_relationship)
|
|
60
|
+
error = "Invalid relationship #{cleaned_relationship} for class #{self}. "\
|
|
61
|
+
"Please use one of #{get_relationships.keys.join(', ')}"
|
|
62
|
+
raise Alula::InvalidRelationshipError.new(error)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
cleaned_relationship
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
module InstanceMethods
|
|
69
|
+
def get_relationships
|
|
70
|
+
self.class.get_relationships
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def get_relationship(name)
|
|
74
|
+
self.class.get_relationship(name)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def add_model_to_relationship(model)
|
|
78
|
+
relation = get_relationship(model.get_type)
|
|
79
|
+
unless relation
|
|
80
|
+
raise "Unknown model relationship #{model.get_type} for model #{self.class}"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
if relation[:cardinality] == 'To-one'
|
|
84
|
+
self.send("#{relation[:name]}=", model)
|
|
85
|
+
|
|
86
|
+
elsif relation[:cardinality] == 'To-many'
|
|
87
|
+
if self.send(relation[:name]).nil?
|
|
88
|
+
list = Alula::ListObject.new(model.class)
|
|
89
|
+
list << model
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
self.send("#{relation[:name]}<<", model)
|
|
93
|
+
else
|
|
94
|
+
raise "Unknown relationship cardinality for relationship #{relation.inspect}"
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def relationship_exists?(relationship)
|
|
99
|
+
self.class.relationship_exists?(relationship)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def check_relationship!(relationship)
|
|
103
|
+
self.class.check_relationship!(relationship)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# A mixin pulled into ImportedResources with which to define resource methods
|
|
2
|
+
module Alula
|
|
3
|
+
module ResourceAttributes
|
|
4
|
+
def self.extended(base)
|
|
5
|
+
base.class_eval do
|
|
6
|
+
@resource_path = nil
|
|
7
|
+
@type = nil
|
|
8
|
+
@http_methods = []
|
|
9
|
+
@fields = {}
|
|
10
|
+
end
|
|
11
|
+
base.include(InstanceMethods)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# Class methods for defining how fields and types work
|
|
17
|
+
# NOTE: We're not using real getters and setters here. I want the method signature
|
|
18
|
+
# to match how most other Ruby class configuration is done, and that is with
|
|
19
|
+
# simple methods that take params.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def resource_path(name)
|
|
23
|
+
@resource_path = name
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def get_resource_path(id = nil)
|
|
27
|
+
return "#{@resource_path}/#{id}" if id
|
|
28
|
+
@resource_path
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def type(type)
|
|
32
|
+
@type = type
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def get_type
|
|
36
|
+
@type
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def http_methods(methods)
|
|
40
|
+
@http_methods = methods
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def get_http_methods
|
|
44
|
+
@http_methods
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
#
|
|
48
|
+
# Memoizes field names and options
|
|
49
|
+
def field(field_name, **opts)
|
|
50
|
+
@fields ||= {}
|
|
51
|
+
@fields[field_name] = opts
|
|
52
|
+
|
|
53
|
+
self.instance_eval do
|
|
54
|
+
jsonKey = Util.camelize(field_name)
|
|
55
|
+
|
|
56
|
+
# Reader method for attribute
|
|
57
|
+
define_method(field_name) do
|
|
58
|
+
value = @values[jsonKey]
|
|
59
|
+
|
|
60
|
+
if opts[:type] == :date && ![nil, ''].include?(value)
|
|
61
|
+
begin
|
|
62
|
+
DateTime.parse(value)
|
|
63
|
+
rescue ArgumentError
|
|
64
|
+
value
|
|
65
|
+
end
|
|
66
|
+
elsif opts[:type] == :boolean
|
|
67
|
+
[true, 'true', 1, '1'].include? value
|
|
68
|
+
elsif opts[:symbolize] == true
|
|
69
|
+
# API sends a camelCase string; provide symbol to Client
|
|
70
|
+
value ? Util.underscore(value).to_sym : nil
|
|
71
|
+
elsif opts[:hex_convert_required] == true
|
|
72
|
+
Util.convert_hex_crc?(self.program_id) ? value.to_s(16) : value
|
|
73
|
+
else
|
|
74
|
+
value
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Setter method
|
|
79
|
+
define_method("#{field_name}=") do |new_value|
|
|
80
|
+
#
|
|
81
|
+
# Coerce 'blank like' fields into a defined blank value
|
|
82
|
+
# This helps HTML form submissions. A blank text field comes through as an
|
|
83
|
+
# empty string, instead of a nil as the API validates for.
|
|
84
|
+
new_value = nil if new_value == ''
|
|
85
|
+
|
|
86
|
+
if opts[:symbolize] == true
|
|
87
|
+
# Client provides a symbol; send camelCase string to API
|
|
88
|
+
new_value = Util.camelize(new_value.to_s)
|
|
89
|
+
elsif opts[:type] == :boolean
|
|
90
|
+
new_value = [true, 'true', 1, '1'].include? new_value
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
#
|
|
94
|
+
# Mark the attribute as dirty if the new value is different
|
|
95
|
+
@dirty_attributes << field_name if @values[jsonKey] != new_value
|
|
96
|
+
|
|
97
|
+
#
|
|
98
|
+
# Assign the new value (always assigned even if a duplicate)
|
|
99
|
+
@values[jsonKey] = new_value
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def get_fields
|
|
107
|
+
@fields
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def read_only_attributes(record_persisted = false)
|
|
111
|
+
get_fields.each_pair.each_with_object([]) do |(field_name, opts), collector|
|
|
112
|
+
collector << field_name if !field_patchable?(opts, record_persisted)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def date_fields
|
|
117
|
+
get_fields.each_pair.each_with_object([]) do |(field_name, opts), collector|
|
|
118
|
+
collector << field_name if opts[:type].to_sym == :date
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def filterable_fields
|
|
123
|
+
get_fields.each_pair.each_with_object([]) do |(field_name, opts), collector|
|
|
124
|
+
collector << field_name if opts[:filterable] == true
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def sortable_fields
|
|
129
|
+
get_fields.each_pair.each_with_object([]) do |(field_name, opts), collector|
|
|
130
|
+
collector << field_name if opts[:sortable] == true
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def field_names
|
|
135
|
+
get_fields.keys
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def param_key
|
|
139
|
+
self.name.gsub('::', '_').downcase
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
private
|
|
143
|
+
|
|
144
|
+
def metaclass
|
|
145
|
+
class << self
|
|
146
|
+
self
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def field_patchable?(opts, record_persisted)
|
|
151
|
+
user_role = Alula::Client.role
|
|
152
|
+
|
|
153
|
+
# different permission arrays are used for updates vs creates
|
|
154
|
+
perm_key = record_persisted == true ? :patchable_by : :creatable_by
|
|
155
|
+
|
|
156
|
+
return true if opts[perm_key].include? :all
|
|
157
|
+
|
|
158
|
+
opts[perm_key].include? user_role
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
#
|
|
162
|
+
# Extensions to allow instances to get at their class config, either raw or
|
|
163
|
+
# reduced to a useable format for a specific task.
|
|
164
|
+
module InstanceMethods
|
|
165
|
+
# Instance method extensions
|
|
166
|
+
def resource_path
|
|
167
|
+
self.class.resource_path
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def type(arg)
|
|
171
|
+
self.class.type(arg)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def get_type
|
|
175
|
+
self.class.get_type
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def fields
|
|
179
|
+
self.class.fields
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def field_names
|
|
183
|
+
self.class.field_names
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def persisted?
|
|
187
|
+
!self.id.nil?
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def read_only_attributes
|
|
191
|
+
self.class.read_only_attributes(persisted?)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
#
|
|
195
|
+
# Return the names of each field configured as a date type
|
|
196
|
+
def date_fields
|
|
197
|
+
self.class.date_fields
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def to_key
|
|
201
|
+
key = respond_to?(:id) && id
|
|
202
|
+
key ? [key] : nil
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
module Alula
|
|
2
|
+
class AdminUser < Alula::User
|
|
3
|
+
extend Alula::ResourceAttributes
|
|
4
|
+
extend Alula::RelationshipAttributes
|
|
5
|
+
extend Alula::ApiOperations::Request
|
|
6
|
+
extend Alula::ApiOperations::List
|
|
7
|
+
extend Alula::ApiOperations::Save
|
|
8
|
+
|
|
9
|
+
resource_path 'admins/users'
|
|
10
|
+
type 'admins-users'
|
|
11
|
+
|
|
12
|
+
relationship :devices, type: 'devices', cardinality: 'To-many'
|
|
13
|
+
relationship :dealer, type: 'dealers', cardinality: 'To-one'
|
|
14
|
+
relationship :phone, type: 'users-phones', cardinality: 'To-one'
|
|
15
|
+
relationship :address, type: 'users-addresses', cardinality: 'To-one'
|
|
16
|
+
relationship :pushtokens, type: 'users-pushtokens', cardinality: 'To-many'
|
|
17
|
+
relationship :preferences, type: 'users-preferences', cardinality: 'To-one'
|
|
18
|
+
relationship :videoprofiles, type: 'users-videoprofiles', cardinality: 'To-many'
|
|
19
|
+
|
|
20
|
+
# Resource Fields
|
|
21
|
+
# Not all params are used at the moment. See Alula::ResourceAttributes for details
|
|
22
|
+
# on how params are parsed,
|
|
23
|
+
field :id,
|
|
24
|
+
type: :string,
|
|
25
|
+
sortable: false,
|
|
26
|
+
filterable: false,
|
|
27
|
+
creatable_by: [],
|
|
28
|
+
patchable_by: []
|
|
29
|
+
|
|
30
|
+
field :username,
|
|
31
|
+
type: :string,
|
|
32
|
+
sortable: true,
|
|
33
|
+
filterable: true,
|
|
34
|
+
creatable_by: [:system, :station, :dealer, :technician, :user],
|
|
35
|
+
patchable_by: [:system, :station, :dealer, :technician, :user, :sub_user]
|
|
36
|
+
|
|
37
|
+
field :password,
|
|
38
|
+
type: :string,
|
|
39
|
+
sortable: false,
|
|
40
|
+
filterable: false,
|
|
41
|
+
creatable_by: [:system, :station, :dealer, :technician, :user],
|
|
42
|
+
patchable_by: []
|
|
43
|
+
|
|
44
|
+
field :u_type,
|
|
45
|
+
type: :string,
|
|
46
|
+
sortable: false,
|
|
47
|
+
filterable: true,
|
|
48
|
+
creatable_by: [:system, :station, :dealer, :technician, :user],
|
|
49
|
+
patchable_by: []
|
|
50
|
+
|
|
51
|
+
field :user_type,
|
|
52
|
+
type: :string,
|
|
53
|
+
sortable: false,
|
|
54
|
+
filterable: true,
|
|
55
|
+
creatable_by: [:system, :station, :dealer, :technician, :user],
|
|
56
|
+
patchable_by: [],
|
|
57
|
+
symbolize: true
|
|
58
|
+
|
|
59
|
+
field :u_level,
|
|
60
|
+
type: :string,
|
|
61
|
+
sortable: false,
|
|
62
|
+
filterable: false,
|
|
63
|
+
creatable_by: [],
|
|
64
|
+
patchable_by: []
|
|
65
|
+
|
|
66
|
+
field :parent_id,
|
|
67
|
+
type: :string,
|
|
68
|
+
sortable: false,
|
|
69
|
+
filterable: true,
|
|
70
|
+
creatable_by: [:system, :station, :dealer, :technician, :user],
|
|
71
|
+
patchable_by: []
|
|
72
|
+
|
|
73
|
+
field :dealer_id,
|
|
74
|
+
type: :string,
|
|
75
|
+
sortable: false,
|
|
76
|
+
filterable: true,
|
|
77
|
+
creatable_by: [:system, :station, :dealer, :technician, :user],
|
|
78
|
+
patchable_by: []
|
|
79
|
+
|
|
80
|
+
field :station_id,
|
|
81
|
+
type: :string,
|
|
82
|
+
sortable: false,
|
|
83
|
+
filterable: true,
|
|
84
|
+
creatable_by: [],
|
|
85
|
+
patchable_by: []
|
|
86
|
+
|
|
87
|
+
field :last_login,
|
|
88
|
+
type: :string,
|
|
89
|
+
sortable: false,
|
|
90
|
+
filterable: false,
|
|
91
|
+
creatable_by: [],
|
|
92
|
+
patchable_by: []
|
|
93
|
+
|
|
94
|
+
field :date_entered,
|
|
95
|
+
type: :date,
|
|
96
|
+
sortable: true,
|
|
97
|
+
filterable: true,
|
|
98
|
+
creatable_by: [],
|
|
99
|
+
patchable_by: []
|
|
100
|
+
|
|
101
|
+
field :date_modified,
|
|
102
|
+
type: :date,
|
|
103
|
+
sortable: true,
|
|
104
|
+
filterable: true,
|
|
105
|
+
creatable_by: [],
|
|
106
|
+
patchable_by: []
|
|
107
|
+
|
|
108
|
+
field :entered_by,
|
|
109
|
+
type: :string,
|
|
110
|
+
sortable: false,
|
|
111
|
+
filterable: false,
|
|
112
|
+
creatable_by: [],
|
|
113
|
+
patchable_by: []
|
|
114
|
+
|
|
115
|
+
field :modified_by,
|
|
116
|
+
type: :string,
|
|
117
|
+
sortable: false,
|
|
118
|
+
filterable: false,
|
|
119
|
+
creatable_by: [],
|
|
120
|
+
patchable_by: []
|
|
121
|
+
|
|
122
|
+
field :pwch,
|
|
123
|
+
type: :string,
|
|
124
|
+
sortable: false,
|
|
125
|
+
filterable: false,
|
|
126
|
+
creatable_by: [],
|
|
127
|
+
patchable_by: []
|
|
128
|
+
|
|
129
|
+
field :features_selected,
|
|
130
|
+
type: :object,
|
|
131
|
+
sortable: false,
|
|
132
|
+
filterable: false,
|
|
133
|
+
creatable_by: [:system, :station, :dealer, :technician],
|
|
134
|
+
patchable_by: [:system, :station, :dealer, :technician]
|
|
135
|
+
|
|
136
|
+
field :eula,
|
|
137
|
+
type: :string,
|
|
138
|
+
sortable: false,
|
|
139
|
+
filterable: false,
|
|
140
|
+
creatable_by: [],
|
|
141
|
+
patchable_by: [:system, :station, :dealer, :technician, :user, :sub_user]
|
|
142
|
+
|
|
143
|
+
field :def_mod,
|
|
144
|
+
type: :string,
|
|
145
|
+
sortable: false,
|
|
146
|
+
filterable: false,
|
|
147
|
+
creatable_by: [],
|
|
148
|
+
patchable_by: []
|
|
149
|
+
|
|
150
|
+
field :rg_activated,
|
|
151
|
+
type: :string,
|
|
152
|
+
sortable: false,
|
|
153
|
+
filterable: false,
|
|
154
|
+
creatable_by: [],
|
|
155
|
+
patchable_by: []
|
|
156
|
+
|
|
157
|
+
field :company_name,
|
|
158
|
+
type: :string,
|
|
159
|
+
sortable: false,
|
|
160
|
+
filterable: false,
|
|
161
|
+
creatable_by: [],
|
|
162
|
+
patchable_by: []
|
|
163
|
+
|
|
164
|
+
field :name_first,
|
|
165
|
+
type: :string,
|
|
166
|
+
sortable: true,
|
|
167
|
+
filterable: true,
|
|
168
|
+
creatable_by: [:system, :station, :dealer, :technician, :user],
|
|
169
|
+
patchable_by: [:system, :station, :dealer, :technician, :user, :sub_user]
|
|
170
|
+
|
|
171
|
+
field :name_last,
|
|
172
|
+
type: :string,
|
|
173
|
+
sortable: true,
|
|
174
|
+
filterable: true,
|
|
175
|
+
creatable_by: [:system, :station, :dealer, :technician, :user],
|
|
176
|
+
patchable_by: [:system, :station, :dealer, :technician, :user, :sub_user]
|
|
177
|
+
|
|
178
|
+
field :email,
|
|
179
|
+
type: :string,
|
|
180
|
+
sortable: true,
|
|
181
|
+
filterable: true,
|
|
182
|
+
creatable_by: [:system, :station, :dealer, :technician, :user],
|
|
183
|
+
patchable_by: [:system, :station, :dealer, :technician, :user, :sub_user]
|
|
184
|
+
|
|
185
|
+
field :time_offset,
|
|
186
|
+
type: :string,
|
|
187
|
+
sortable: false,
|
|
188
|
+
filterable: false,
|
|
189
|
+
creatable_by: [],
|
|
190
|
+
patchable_by: []
|
|
191
|
+
|
|
192
|
+
field :timezone,
|
|
193
|
+
type: :string,
|
|
194
|
+
sortable: false,
|
|
195
|
+
filterable: false,
|
|
196
|
+
creatable_by: [:system, :station, :dealer, :technician, :user],
|
|
197
|
+
patchable_by: [:system, :station, :dealer, :technician, :user, :sub_user]
|
|
198
|
+
|
|
199
|
+
field :hidden,
|
|
200
|
+
type: :boolean,
|
|
201
|
+
sortable: true,
|
|
202
|
+
filterable: true,
|
|
203
|
+
creatable_by: [:system],
|
|
204
|
+
patchable_by: [:system]
|
|
205
|
+
|
|
206
|
+
end
|
|
207
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Alula
|
|
2
|
+
class BillingProgram < Alula::RestResource
|
|
3
|
+
extend Alula::ResourceAttributes
|
|
4
|
+
extend Alula::ApiOperations::Request
|
|
5
|
+
extend Alula::ApiOperations::List
|
|
6
|
+
|
|
7
|
+
resource_path 'billing/programs'
|
|
8
|
+
type 'billing-program'
|
|
9
|
+
|
|
10
|
+
# Resource Fields
|
|
11
|
+
# Not all params are used at the moment. See Alula::ResourceAttributes for details
|
|
12
|
+
# on how params are parsed,
|
|
13
|
+
field :id,
|
|
14
|
+
type: :string,
|
|
15
|
+
sortable: false,
|
|
16
|
+
filterable: false,
|
|
17
|
+
creatable_by: [],
|
|
18
|
+
patchable_by: []
|
|
19
|
+
|
|
20
|
+
field :name,
|
|
21
|
+
type: :string,
|
|
22
|
+
sortable: false,
|
|
23
|
+
filterable: false,
|
|
24
|
+
creatable_by: [],
|
|
25
|
+
patchable_by: []
|
|
26
|
+
|
|
27
|
+
field :description,
|
|
28
|
+
type: :string,
|
|
29
|
+
sortable: false,
|
|
30
|
+
filterable: false,
|
|
31
|
+
creatable_by: [],
|
|
32
|
+
patchable_by: []
|
|
33
|
+
|
|
34
|
+
field :params_schema,
|
|
35
|
+
type: :object,
|
|
36
|
+
sortable: false,
|
|
37
|
+
filterable: false,
|
|
38
|
+
creatable_by: [],
|
|
39
|
+
patchable_by: []
|
|
40
|
+
end
|
|
41
|
+
end
|