alula-ruby 0.50.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +14 -0
  3. data/.env.example +8 -0
  4. data/.github/workflows/gem-push.yml +45 -0
  5. data/.gitignore +23 -0
  6. data/.rspec +3 -0
  7. data/.travis.yml +7 -0
  8. data/Dockerfile +6 -0
  9. data/Gemfile +12 -0
  10. data/Guardfile +42 -0
  11. data/README.md +423 -0
  12. data/Rakefile +6 -0
  13. data/VERSION.md +84 -0
  14. data/alula-docker-compose.yml +80 -0
  15. data/alula.gemspec +38 -0
  16. data/bin/console +15 -0
  17. data/bin/docparse +36 -0
  18. data/bin/genresource +79 -0
  19. data/bin/setup +8 -0
  20. data/bin/testauth +24 -0
  21. data/bin/testprep +9 -0
  22. data/data/docs/Alula_API_Documentation_2021-04-06.html +16240 -0
  23. data/docker-compose.yml +11 -0
  24. data/lib/alula/alula_response.rb +20 -0
  25. data/lib/alula/api_operations/delete.rb +52 -0
  26. data/lib/alula/api_operations/list.rb +45 -0
  27. data/lib/alula/api_operations/request.rb +44 -0
  28. data/lib/alula/api_operations/save.rb +81 -0
  29. data/lib/alula/api_resource.rb +196 -0
  30. data/lib/alula/client.rb +142 -0
  31. data/lib/alula/errors.rb +169 -0
  32. data/lib/alula/filter_builder.rb +271 -0
  33. data/lib/alula/helpers/device_attribute_translations.rb +68 -0
  34. data/lib/alula/list_object.rb +64 -0
  35. data/lib/alula/meta.rb +16 -0
  36. data/lib/alula/monkey_patches.rb +24 -0
  37. data/lib/alula/oauth.rb +118 -0
  38. data/lib/alula/pagination.rb +25 -0
  39. data/lib/alula/procedures/dealer_device_stats_proc.rb +16 -0
  40. data/lib/alula/procedures/dealer_restore_proc.rb +25 -0
  41. data/lib/alula/procedures/dealer_suspend_proc.rb +25 -0
  42. data/lib/alula/procedures/device_assign_proc.rb +23 -0
  43. data/lib/alula/procedures/device_cellular_history_proc.rb +33 -0
  44. data/lib/alula/procedures/device_rateplan_get_proc.rb +21 -0
  45. data/lib/alula/procedures/device_register_proc.rb +31 -0
  46. data/lib/alula/procedures/device_signal_add_proc.rb +42 -0
  47. data/lib/alula/procedures/device_signal_delivered_proc.rb +31 -0
  48. data/lib/alula/procedures/device_signal_update_proc.rb +32 -0
  49. data/lib/alula/procedures/device_unassign_proc.rb +16 -0
  50. data/lib/alula/procedures/device_unregister_proc.rb +21 -0
  51. data/lib/alula/procedures/upload_touchpad_branding_proc.rb +24 -0
  52. data/lib/alula/procedures/user_plansvideo_price_get.rb +21 -0
  53. data/lib/alula/procedures/user_transfer_accept.rb +19 -0
  54. data/lib/alula/procedures/user_transfer_authorize.rb +18 -0
  55. data/lib/alula/procedures/user_transfer_cancel.rb +18 -0
  56. data/lib/alula/procedures/user_transfer_deny.rb +19 -0
  57. data/lib/alula/procedures/user_transfer_reject.rb +19 -0
  58. data/lib/alula/procedures/user_transfer_request.rb +19 -0
  59. data/lib/alula/query_interface.rb +142 -0
  60. data/lib/alula/rate_limit.rb +11 -0
  61. data/lib/alula/relationship_attributes.rb +107 -0
  62. data/lib/alula/resource_attributes.rb +206 -0
  63. data/lib/alula/resources/admin_user.rb +207 -0
  64. data/lib/alula/resources/billing_program.rb +41 -0
  65. data/lib/alula/resources/dealer.rb +218 -0
  66. data/lib/alula/resources/dealer_account_transfer.rb +172 -0
  67. data/lib/alula/resources/dealer_address.rb +89 -0
  68. data/lib/alula/resources/dealer_branding.rb +226 -0
  69. data/lib/alula/resources/dealer_program.rb +75 -0
  70. data/lib/alula/resources/dealer_suspension_log.rb +49 -0
  71. data/lib/alula/resources/device.rb +716 -0
  72. data/lib/alula/resources/device_cellular_status.rb +134 -0
  73. data/lib/alula/resources/device_charge.rb +70 -0
  74. data/lib/alula/resources/device_event_log.rb +167 -0
  75. data/lib/alula/resources/device_program.rb +54 -0
  76. data/lib/alula/resources/event_trigger.rb +75 -0
  77. data/lib/alula/resources/event_webhook.rb +47 -0
  78. data/lib/alula/resources/feature_bysubject.rb +74 -0
  79. data/lib/alula/resources/feature_plan.rb +57 -0
  80. data/lib/alula/resources/feature_planvideo.rb +54 -0
  81. data/lib/alula/resources/feature_price.rb +46 -0
  82. data/lib/alula/resources/receiver_connection.rb +95 -0
  83. data/lib/alula/resources/receiver_group.rb +74 -0
  84. data/lib/alula/resources/revision.rb +91 -0
  85. data/lib/alula/resources/self.rb +61 -0
  86. data/lib/alula/resources/station.rb +130 -0
  87. data/lib/alula/resources/token_exchange.rb +34 -0
  88. data/lib/alula/resources/user.rb +229 -0
  89. data/lib/alula/resources/user_address.rb +121 -0
  90. data/lib/alula/resources/user_phone.rb +116 -0
  91. data/lib/alula/resources/user_preferences.rb +57 -0
  92. data/lib/alula/resources/user_pushtoken.rb +75 -0
  93. data/lib/alula/resources/user_videoprofile.rb +38 -0
  94. data/lib/alula/rest_resource.rb +17 -0
  95. data/lib/alula/rpc_resource.rb +40 -0
  96. data/lib/alula/rpc_response.rb +14 -0
  97. data/lib/alula/singleton_rest_resource.rb +26 -0
  98. data/lib/alula/util.rb +107 -0
  99. data/lib/alula/version.rb +5 -0
  100. data/lib/alula.rb +135 -0
  101. data/lib/parser.rb +199 -0
  102. 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