lockstep_rails 0.3.22 → 0.3.26
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/concepts/lockstep/api_record.rb +198 -168
- data/app/concepts/lockstep/exceptions.rb +4 -3
- data/app/concepts/lockstep/query.rb +6 -2
- data/app/models/lockstep/report_ar_aging_header.rb +7 -0
- data/app/models/lockstep/report_cashflow.rb +7 -0
- data/app/models/lockstep/report_daily_sales_outstanding.rb +6 -0
- data/app/models/lockstep/report_risk_rate.rb +7 -0
- data/app/models/lockstep/vendor_summary.rb +6 -0
- data/app/models/lockstep/webhook.rb +5 -0
- data/app/platform_api/schema/invoice.rb +54 -53
- data/app/platform_api/schema/vendor_summary.rb +78 -0
- data/app/platform_api/schema/webhook.rb +11 -11
- data/lib/lockstep_rails/version.rb +1 -1
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e131b1c5966a23df01c75f0c00ba3de1431930d2f834c1ce0a0ee451d349791a
|
4
|
+
data.tar.gz: 7b671b5424eb5873d5bc1b3f654e62c78db6a0268ec25794c62d2592a4d91423
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc421846e47207c7373cd2b109b5b29d8d969099cc112e4b42c12013ddb1695064c1f67fe5ad5388812d6f85ca4a60f0bc34e1a0893d5660c5fd563508252032
|
7
|
+
data.tar.gz: 7d3187d4ef5b9e6f37571d0ce825265f63589a8f65674467f08f96fc31cfe419b1dad59cad8f1d187dccb582659f5bcdcbe9a0c24c925fb06253ce3a6c2755d4
|
@@ -1,15 +1,16 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'active_model'
|
4
|
+
require 'erb'
|
5
|
+
require 'dry-types'
|
6
|
+
require 'json'
|
7
|
+
require 'active_support/hash_with_indifferent_access'
|
8
|
+
require 'lockstep/query'
|
9
|
+
require 'lockstep/query_methods'
|
10
|
+
require 'lockstep/error'
|
11
|
+
require 'lockstep/exceptions'
|
12
|
+
require 'lockstep/relation_array'
|
13
|
+
require 'pry'
|
13
14
|
|
14
15
|
module Lockstep
|
15
16
|
class ApiRecord
|
@@ -42,7 +43,7 @@ module Lockstep
|
|
42
43
|
# @params [Hash], [Boolean] a `Hash` of attributes and a `Boolean` that should be false only if the object already exists
|
43
44
|
# @return [Lockstep::ApiRecord] an object that subclasses `Parseresource::Base`
|
44
45
|
def initialize(attributes = {}, new = true)
|
45
|
-
#attributes = HashWithIndifferentAccess.new(attributes)
|
46
|
+
# attributes = HashWithIndifferentAccess.new(attributes)
|
46
47
|
|
47
48
|
if new
|
48
49
|
@unsaved_attributes = attributes
|
@@ -85,7 +86,7 @@ module Lockstep
|
|
85
86
|
fname = fname.to_sym
|
86
87
|
class_eval do
|
87
88
|
define_method(fname) do
|
88
|
-
val = get_attribute(
|
89
|
+
val = get_attribute(fname.to_s)
|
89
90
|
|
90
91
|
# If enum, substitute with the enum key
|
91
92
|
if val.present? && (enum = enum_config[fname]).present?
|
@@ -95,10 +96,10 @@ module Lockstep
|
|
95
96
|
val
|
96
97
|
end
|
97
98
|
end
|
98
|
-
unless
|
99
|
+
unless respond_to? "#{fname}="
|
99
100
|
class_eval do
|
100
101
|
define_method("#{fname}=") do |val|
|
101
|
-
set_attribute(
|
102
|
+
set_attribute(fname.to_s, val)
|
102
103
|
|
103
104
|
val
|
104
105
|
end
|
@@ -125,7 +126,7 @@ module Lockstep
|
|
125
126
|
def self.belongs_to(parent, config = {})
|
126
127
|
config = config.with_indifferent_access
|
127
128
|
class_name = config[:class_name]
|
128
|
-
raise "Class name cannot be empty in #{parent}: #{
|
129
|
+
raise "Class name cannot be empty in #{parent}: #{name}" if class_name.blank?
|
129
130
|
|
130
131
|
included = config[:included] || false
|
131
132
|
primary_key = config[:primary_key]
|
@@ -139,7 +140,7 @@ module Lockstep
|
|
139
140
|
belongs_to_relations[parent] = {
|
140
141
|
name: parent, class_name: class_name,
|
141
142
|
included: included, primary_key: primary_key, foreign_key: foreign_key,
|
142
|
-
loader: loader, polymorphic: polymorphic
|
143
|
+
loader: loader, polymorphic: polymorphic
|
143
144
|
}
|
144
145
|
|
145
146
|
# define_method("build_#{parent}") do |attributes_hash|
|
@@ -156,7 +157,7 @@ module Lockstep
|
|
156
157
|
def self.has_many(parent, config = {})
|
157
158
|
config = config.with_indifferent_access
|
158
159
|
class_name = config[:class_name]
|
159
|
-
raise "Class name cannot be empty in #{parent}: #{
|
160
|
+
raise "Class name cannot be empty in #{parent}: #{name}" if class_name.blank?
|
160
161
|
|
161
162
|
included = config[:included] || false
|
162
163
|
primary_key = config[:primary_key]
|
@@ -164,13 +165,13 @@ module Lockstep
|
|
164
165
|
polymorphic = config[:polymorphic]
|
165
166
|
loader = config[:loader]
|
166
167
|
|
167
|
-
primary_key ||=
|
168
|
-
foreign_key ||=
|
168
|
+
primary_key ||= id_ref
|
169
|
+
foreign_key ||= id_ref
|
169
170
|
field(parent)
|
170
171
|
has_many_relations[parent] = {
|
171
172
|
name: parent, class_name: class_name, included: included,
|
172
173
|
primary_key: primary_key, foreign_key: foreign_key, polymorphic: polymorphic,
|
173
|
-
loader: loader
|
174
|
+
loader: loader
|
174
175
|
}
|
175
176
|
end
|
176
177
|
|
@@ -182,46 +183,48 @@ module Lockstep
|
|
182
183
|
schema.belongs_to_relations.each do |relation, config|
|
183
184
|
params = {}
|
184
185
|
config.except(:name).each { |k, v| params[k.to_sym] = v }
|
185
|
-
|
186
|
+
belongs_to(relation, params)
|
186
187
|
end
|
187
188
|
|
188
189
|
schema.has_many_relations.each do |relation, config|
|
189
190
|
params = {}
|
190
191
|
config.except(:name).each { |k, v| params[k.to_sym] = v }
|
191
|
-
|
192
|
+
has_many(relation, params)
|
192
193
|
end
|
193
194
|
end
|
194
195
|
|
195
196
|
def to_pointer
|
196
197
|
klass_name = self.class.model_name.to_s
|
197
|
-
{
|
198
|
+
{ '__type' => 'Pointer', 'className' => klass_name.to_s, id_ref => id }
|
198
199
|
end
|
199
200
|
|
200
201
|
def self.to_date_object(date)
|
201
202
|
date = date.to_time if date.respond_to?(:to_time)
|
202
|
-
|
203
|
+
if date && (date.is_a?(Date) || date.is_a?(DateTime) || date.is_a?(Time))
|
204
|
+
date.getutc.iso8601(fraction_digits = 3)
|
205
|
+
end
|
203
206
|
end
|
204
207
|
|
205
208
|
# Creates setter methods for model fields
|
206
|
-
def create_setters!(k,
|
207
|
-
unless
|
209
|
+
def create_setters!(k, _v)
|
210
|
+
unless respond_to? "#{k}="
|
208
211
|
self.class.send(:define_method, "#{k}=") do |val|
|
209
|
-
set_attribute(
|
212
|
+
set_attribute(k.to_s, val)
|
210
213
|
|
211
214
|
val
|
212
215
|
end
|
213
216
|
end
|
214
217
|
end
|
215
218
|
|
216
|
-
def method_missing(method, *
|
217
|
-
raise StandardError
|
219
|
+
def method_missing(method, *_args)
|
220
|
+
raise StandardError, "#{method} has not been defined for #{self.class.name}"
|
218
221
|
# super
|
219
222
|
end
|
220
223
|
|
221
224
|
def self.method_missing(method_name, *args)
|
222
225
|
method_name = method_name.to_s
|
223
|
-
if method_name.start_with?(
|
224
|
-
attrib = method_name.gsub(/^find_by_/,
|
226
|
+
if method_name.start_with?('find_by_')
|
227
|
+
attrib = method_name.gsub(/^find_by_/, '')
|
225
228
|
finder_name = "find_all_by_#{attrib}"
|
226
229
|
|
227
230
|
define_singleton_method(finder_name) do |target_value|
|
@@ -229,8 +232,8 @@ module Lockstep
|
|
229
232
|
end
|
230
233
|
|
231
234
|
send(finder_name, args[0])
|
232
|
-
elsif method_name.start_with?(
|
233
|
-
attrib = method_name.gsub(/^find_all_by_/,
|
235
|
+
elsif method_name.start_with?('find_all_by_')
|
236
|
+
attrib = method_name.gsub(/^find_all_by_/, '')
|
234
237
|
finder_name = "find_all_by_#{attrib}"
|
235
238
|
|
236
239
|
define_singleton_method(finder_name) do |target_value|
|
@@ -244,10 +247,10 @@ module Lockstep
|
|
244
247
|
end
|
245
248
|
|
246
249
|
# Creates getter methods for model fields
|
247
|
-
def create_getters!(k,
|
248
|
-
unless
|
249
|
-
self.class.send(:define_method,
|
250
|
-
get_attribute(
|
250
|
+
def create_getters!(k, _v)
|
251
|
+
unless respond_to? k.to_s
|
252
|
+
self.class.send(:define_method, k.to_s) do
|
253
|
+
get_attribute(k.to_s)
|
251
254
|
end
|
252
255
|
end
|
253
256
|
end
|
@@ -283,19 +286,19 @@ module Lockstep
|
|
283
286
|
# end
|
284
287
|
# end
|
285
288
|
|
286
|
-
|
287
|
-
|
289
|
+
class << self
|
290
|
+
attr_writer :id_ref
|
288
291
|
end
|
289
292
|
|
290
293
|
def self.id_ref
|
291
|
-
raise StandardError
|
294
|
+
raise StandardError, "id_ref has not been defined for #{name}" if @id_ref.blank?
|
292
295
|
|
293
296
|
@id_ref
|
294
297
|
end
|
295
298
|
|
296
299
|
# Alias for id_ref. Used by polymorphic association
|
297
300
|
def self.primary_key
|
298
|
-
|
301
|
+
id_ref
|
299
302
|
end
|
300
303
|
|
301
304
|
def id_ref
|
@@ -308,8 +311,8 @@ module Lockstep
|
|
308
311
|
@model_name_uri
|
309
312
|
end
|
310
313
|
|
311
|
-
|
312
|
-
|
314
|
+
class << self
|
315
|
+
attr_reader :model_name_uri
|
313
316
|
end
|
314
317
|
|
315
318
|
def self.config
|
@@ -318,13 +321,16 @@ module Lockstep
|
|
318
321
|
|
319
322
|
# Gets the current class's Lockstep.io base_uri
|
320
323
|
def self.model_base_uri
|
321
|
-
|
322
|
-
|
324
|
+
if name.starts_with?('Schema::')
|
325
|
+
raise StandardError,
|
326
|
+
'Cannot establish connection for auto-generated Schema. Create a new model if you want to retrieve data from Lockstep Platform'
|
327
|
+
end
|
328
|
+
raise StandardError, "URL Path is not defined for #{name}" if model_name_uri.blank?
|
323
329
|
|
324
330
|
base_url = config[:base_url]
|
325
|
-
base_url +=
|
331
|
+
base_url += '/' unless base_url.ends_with?('/')
|
326
332
|
base_url += model_name_uri
|
327
|
-
base_url +=
|
333
|
+
base_url += '/' unless base_url.ends_with?('/')
|
328
334
|
base_url
|
329
335
|
end
|
330
336
|
|
@@ -339,19 +345,19 @@ module Lockstep
|
|
339
345
|
def self.resource
|
340
346
|
# load_settings
|
341
347
|
|
342
|
-
#refactor to settings['app_id'] etc
|
348
|
+
# refactor to settings['app_id'] etc
|
343
349
|
# app_id = @@settings['app_id']
|
344
350
|
# master_key = @@settings['master_key']
|
345
351
|
# RestClient::Resource.new(self.model_base_uri, app_id, master_key)
|
346
|
-
Lockstep::Client.new(
|
352
|
+
Lockstep::Client.new(model_base_uri)
|
347
353
|
end
|
348
354
|
|
349
|
-
|
350
|
-
|
355
|
+
class << self
|
356
|
+
attr_writer :query_path
|
351
357
|
end
|
352
358
|
|
353
359
|
def self.query_path
|
354
|
-
@query_path ||
|
360
|
+
@query_path || 'query'
|
355
361
|
end
|
356
362
|
|
357
363
|
# Batch requests
|
@@ -396,6 +402,7 @@ module Lockstep
|
|
396
402
|
def self.merge_all_attributes(objects, response)
|
397
403
|
objects.each_with_index do |item, index|
|
398
404
|
next unless response[index]
|
405
|
+
|
399
406
|
new_attributes = response[index].transform_keys { |key| key.underscore }
|
400
407
|
item.merge_attributes(new_attributes)
|
401
408
|
end
|
@@ -417,7 +424,7 @@ module Lockstep
|
|
417
424
|
# end
|
418
425
|
|
419
426
|
def self.bulk_import(new_objects, slice_size = 20)
|
420
|
-
return
|
427
|
+
return [] if new_objects.blank?
|
421
428
|
|
422
429
|
# Batch saves seem to fail if they're too big. We'll slice it up into multiple posts if they are.
|
423
430
|
new_objects.each_slice(slice_size) do |objects|
|
@@ -425,46 +432,41 @@ module Lockstep
|
|
425
432
|
batch_json = []
|
426
433
|
|
427
434
|
objects.each do |item|
|
428
|
-
|
435
|
+
unless item.new?
|
436
|
+
raise StandardError,
|
437
|
+
'Bulk Import cannot only create records at the moment. It cannot update records'
|
438
|
+
end
|
429
439
|
|
430
440
|
batch_json << item.attributes_for_saving.transform_keys { |key| key.camelize(:lower) }
|
431
441
|
end
|
432
442
|
|
433
|
-
resp =
|
434
|
-
# TODO attach errors if resp code is 400
|
435
|
-
|
436
|
-
if resp.code.to_s == "400"
|
443
|
+
resp = resource.post('', body: batch_json)
|
444
|
+
# TODO: attach errors if resp code is 400
|
445
|
+
if resp.code != '200'
|
437
446
|
# Error format in JSON
|
438
447
|
# "errors": {
|
439
448
|
# "[0].EmailAddress": [
|
440
449
|
# "The EmailAddress field is not a valid e-mail address."
|
441
450
|
# ]
|
442
451
|
# }
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
position = splits.first[1..(splits.first.size - 2)].to_i
|
450
|
-
messages.each do |message|
|
451
|
-
new_objects[position].errors.add attribute, ": #{message}"
|
452
|
-
end
|
452
|
+
if resp.code == '401'
|
453
|
+
raise Lockstep::Exceptions::UnauthorizedError, 'Unauthorized: Check your App ID & Master Key'
|
454
|
+
elsif resp.code == '400'
|
455
|
+
raise Lockstep::Exceptions::BadRequestError, JSON.parse(resp.body)
|
456
|
+
elsif resp.code == '404'
|
457
|
+
raise Lockstep::Exceptions::RecordNotFound, 'Resource not found in the Platfrom'
|
453
458
|
end
|
454
|
-
return false
|
455
|
-
elsif resp.code.to_s != "200"
|
456
|
-
return false
|
457
459
|
end
|
458
460
|
|
459
461
|
response = JSON.parse(resp.body)
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
462
|
+
next unless response && response.is_a?(Array) && response.length == objects.length
|
463
|
+
|
464
|
+
# return response.map { |item|
|
465
|
+
# Lockstep::Contact.new(item.transform_keys { |key| key.underscore }, false)
|
466
|
+
# }
|
467
|
+
merge_all_attributes(objects, response)
|
466
468
|
end
|
467
|
-
|
469
|
+
new_objects
|
468
470
|
end
|
469
471
|
|
470
472
|
# def self.load_settings
|
@@ -516,8 +518,10 @@ module Lockstep
|
|
516
518
|
# @return [Lockstep::ApiRecord] an object that subclasses Lockstep::ApiRecord.
|
517
519
|
def self.find(id)
|
518
520
|
raise Lockstep::Exceptions::RecordNotFound, "Couldn't find #{name} without an ID" if id.blank?
|
519
|
-
|
521
|
+
|
522
|
+
record = where(id_ref => id).first
|
520
523
|
raise Lockstep::Exceptions::RecordNotFound, "Couldn't find #{name} with id: #{id}" if record.blank?
|
524
|
+
|
521
525
|
record
|
522
526
|
end
|
523
527
|
|
@@ -525,13 +529,13 @@ module Lockstep
|
|
525
529
|
#
|
526
530
|
def self.find_by(*args)
|
527
531
|
raise Lockstep::Exceptions::RecordNotFound, "Couldn't find an object without arguments" if args.blank?
|
532
|
+
|
528
533
|
key, value = args.first.first
|
529
534
|
unless valid_attribute?(key, raise_exception: true)
|
530
|
-
raise StandardError
|
535
|
+
raise StandardError, "Attribute '#{key}' has not been defined for #{name}"
|
531
536
|
end
|
532
537
|
|
533
|
-
|
534
|
-
record
|
538
|
+
where(key => value).first
|
535
539
|
end
|
536
540
|
|
537
541
|
# Find a Lockstep::ApiRecord object by chaining #where method calls.
|
@@ -576,19 +580,17 @@ module Lockstep
|
|
576
580
|
# Valid only if the record is not an API record.
|
577
581
|
# Default scopes build queries using ApiRecord to avoid conflicts. In this case, the query results in an
|
578
582
|
# exception as the fields wouldn't have been defined in the ApiRecord
|
579
|
-
return true if
|
583
|
+
return true if name == 'Lockstep::ApiRecord'
|
580
584
|
|
581
585
|
attr = key.to_s
|
582
586
|
Lockstep::Query::PREDICATES.keys.each do |predicate|
|
583
587
|
if attr.end_with?(predicate)
|
584
|
-
attr = attr.gsub(predicate,
|
588
|
+
attr = attr.gsub(predicate, '')
|
585
589
|
break
|
586
590
|
end
|
587
591
|
end
|
588
592
|
valid = schema.has_key?(attr)
|
589
|
-
if raise_exception && !valid
|
590
|
-
raise StandardError.new("Attribute '#{attr}' has not been defined for #{self.name}")
|
591
|
-
end
|
593
|
+
raise StandardError, "Attribute '#{attr}' has not been defined for #{name}" if raise_exception && !valid
|
592
594
|
|
593
595
|
valid
|
594
596
|
end
|
@@ -613,19 +615,19 @@ module Lockstep
|
|
613
615
|
# create RESTful resource for the specific Parse object
|
614
616
|
# sends requests to [base_uri]/[classname]/[objectId]
|
615
617
|
def instance_resource
|
616
|
-
self.class.resource[
|
618
|
+
self.class.resource[id.to_s]
|
617
619
|
end
|
618
620
|
|
619
621
|
def pointerize(hash)
|
620
622
|
new_hash = {}
|
621
623
|
hash.each do |k, v|
|
622
|
-
if v.respond_to?(:to_pointer)
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
624
|
+
new_hash[k] = if v.respond_to?(:to_pointer)
|
625
|
+
v.to_pointer
|
626
|
+
elsif v.is_a?(Date) || v.is_a?(Time) || v.is_a?(DateTime)
|
627
|
+
self.class.to_date_object(v)
|
628
|
+
else
|
629
|
+
v
|
630
|
+
end
|
629
631
|
end
|
630
632
|
new_hash
|
631
633
|
end
|
@@ -642,13 +644,13 @@ module Lockstep
|
|
642
644
|
else
|
643
645
|
false
|
644
646
|
end
|
645
|
-
rescue
|
647
|
+
rescue StandardError
|
646
648
|
false
|
647
649
|
end
|
648
650
|
|
649
651
|
def create
|
650
652
|
attrs = attributes_for_saving.transform_keys { |key| key.camelize(:lower) }
|
651
|
-
resp =
|
653
|
+
resp = resource.post('', body: [attrs])
|
652
654
|
result = post_result(resp)
|
653
655
|
end
|
654
656
|
|
@@ -659,7 +661,7 @@ module Lockstep
|
|
659
661
|
# put_attrs = attributes_for_saving.to_json
|
660
662
|
|
661
663
|
attrs = attributes_for_saving.transform_keys { |key| key.camelize(:lower) }
|
662
|
-
resp =
|
664
|
+
resp = resource.patch(id, body: attrs)
|
663
665
|
result = post_result(resp)
|
664
666
|
end
|
665
667
|
|
@@ -681,40 +683,40 @@ module Lockstep
|
|
681
683
|
# the object nor the relations it contains. Make another request here.
|
682
684
|
# TODO: @@has_many_relations structure has been changed from array to hash, need to evaluate the impact here
|
683
685
|
if has_many_relations.keys.map { |relation| relation.to_s.to_sym }
|
684
|
-
#
|
686
|
+
# TODO: make this a little smarter by checking if there are any Pointer objects in the objects attributes.
|
685
687
|
# @attributes = self.class.to_s.constantize.where(:objectId => @attributes[self.id_ref]).first.attributes
|
686
|
-
@attributes = self.class.to_s.constantize.where(
|
688
|
+
@attributes = self.class.to_s.constantize.where(id_ref => @attributes[id_ref]).first.attributes
|
687
689
|
end
|
688
690
|
end
|
689
691
|
|
690
692
|
def post_result(resp)
|
691
|
-
if resp.code.to_s ==
|
693
|
+
if resp.code.to_s == '200' || resp.code.to_s == '201'
|
692
694
|
body = JSON.parse(resp.body)
|
693
695
|
# Create method always responds with an array, whereas update responds with the object
|
694
696
|
body = body.first if body.is_a?(Array)
|
695
697
|
|
696
698
|
merge_attributes(body)
|
697
699
|
|
698
|
-
|
699
|
-
elsif resp.code.to_s ==
|
700
|
+
true
|
701
|
+
elsif resp.code.to_s == '400'
|
700
702
|
error_response = JSON.parse(resp.body)
|
701
|
-
errors = error_response[
|
703
|
+
errors = error_response['errors']
|
702
704
|
errors.each do |key, messages|
|
703
|
-
attribute = key.split(
|
705
|
+
attribute = key.split('.').last&.underscore
|
704
706
|
messages.each do |message|
|
705
707
|
self.errors.add attribute, ": #{message}"
|
706
708
|
end
|
707
709
|
end
|
708
710
|
else
|
709
711
|
error_response = JSON.parse(resp.body)
|
710
|
-
if error_response[
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
712
|
+
pe = if error_response['error']
|
713
|
+
LockstepError.new(error_response['code'], error_response['error'])
|
714
|
+
else
|
715
|
+
LockstepError.new(resp.code.to_s)
|
716
|
+
end
|
715
717
|
self.errors.add(pe.code.to_s.to_sym, pe.msg)
|
716
|
-
|
717
|
-
|
718
|
+
error_instances << pe
|
719
|
+
false
|
718
720
|
end
|
719
721
|
end
|
720
722
|
|
@@ -724,9 +726,9 @@ module Lockstep
|
|
724
726
|
|
725
727
|
put_attrs = relations_for_saving(put_attrs)
|
726
728
|
|
727
|
-
put_attrs.delete(
|
728
|
-
put_attrs.delete(
|
729
|
-
put_attrs.delete(
|
729
|
+
put_attrs.delete(id_ref)
|
730
|
+
put_attrs.delete('created')
|
731
|
+
put_attrs.delete('modified')
|
730
732
|
put_attrs
|
731
733
|
end
|
732
734
|
|
@@ -734,25 +736,28 @@ module Lockstep
|
|
734
736
|
all_add_item_queries = {}
|
735
737
|
all_remove_item_queries = {}
|
736
738
|
@unsaved_attributes.each_pair do |key, value|
|
737
|
-
next
|
739
|
+
next unless value.is_a? Array
|
738
740
|
|
739
741
|
# Go through the array in unsaved and check if they are in array in attributes (saved stuff)
|
740
742
|
add_item_ops = []
|
741
743
|
@unsaved_attributes[key].each do |item|
|
742
744
|
found_item_in_saved = false
|
743
745
|
@attributes[key].each do |item_in_saved|
|
744
|
-
if !!(defined? item.attributes) && item.attributes[
|
746
|
+
if !!(defined? item.attributes) && item.attributes[id_ref] == item_in_saved.attributes[id_ref]
|
745
747
|
found_item_in_saved = true
|
746
748
|
end
|
747
749
|
end
|
748
750
|
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
751
|
+
next unless !found_item_in_saved && !!(defined? item.id)
|
752
|
+
|
753
|
+
# need to send additem operation to parse
|
754
|
+
put_attrs.delete(key) # arrays should not be sent along with REST to parse api
|
755
|
+
add_item_ops << { '__type' => 'Pointer', 'className' => item.class.to_s, id_ref => item.id }
|
756
|
+
end
|
757
|
+
unless add_item_ops.empty?
|
758
|
+
all_add_item_queries.merge!({ key => { '__op' => 'Add',
|
759
|
+
'objects' => add_item_ops } })
|
754
760
|
end
|
755
|
-
all_add_item_queries.merge!({ key => { "__op" => "Add", "objects" => add_item_ops } }) if !add_item_ops.empty?
|
756
761
|
|
757
762
|
# Go through saved and if it isn't in unsaved perform a removeitem operation
|
758
763
|
remove_item_ops = []
|
@@ -760,28 +765,31 @@ module Lockstep
|
|
760
765
|
@attributes[key].each do |item|
|
761
766
|
found_item_in_unsaved = false
|
762
767
|
@unsaved_attributes[key].each do |item_in_unsaved|
|
763
|
-
if !!(defined? item.attributes) && item.attributes[
|
768
|
+
if !!(defined? item.attributes) && item.attributes[id_ref] == item_in_unsaved.attributes[id_ref]
|
764
769
|
found_item_in_unsaved = true
|
765
770
|
end
|
766
771
|
end
|
767
772
|
|
768
773
|
if !found_item_in_unsaved && !!(defined? item.id)
|
769
774
|
# need to send removeitem operation to parse
|
770
|
-
remove_item_ops << {
|
775
|
+
remove_item_ops << { '__type' => 'Pointer', 'className' => item.class.to_s, id_ref => item.id }
|
771
776
|
end
|
772
777
|
end
|
773
778
|
end
|
774
|
-
|
779
|
+
unless remove_item_ops.empty?
|
780
|
+
all_remove_item_queries.merge!({ key => { '__op' => 'Remove',
|
781
|
+
'objects' => remove_item_ops } })
|
782
|
+
end
|
775
783
|
end
|
776
784
|
|
777
|
-
# TODO figure out a more elegant way to get this working. the remove_item merge overwrites the add.
|
785
|
+
# TODO: figure out a more elegant way to get this working. the remove_item merge overwrites the add.
|
778
786
|
# Use a seperate query to add objects to the relation.
|
779
|
-
#if !all_add_item_queries.empty?
|
787
|
+
# if !all_add_item_queries.empty?
|
780
788
|
# #result = self.instance_resource.put(all_add_item_queries.to_json, {:content_type => "application/json"}) do |resp, req, res, &block|
|
781
789
|
# # return puts(resp, req, res, false, &block)
|
782
790
|
# #end
|
783
791
|
# puts result
|
784
|
-
#end
|
792
|
+
# end
|
785
793
|
|
786
794
|
put_attrs.merge!(all_add_item_queries) unless all_add_item_queries.empty?
|
787
795
|
put_attrs.merge!(all_remove_item_queries) unless all_remove_item_queries.empty?
|
@@ -789,17 +797,17 @@ module Lockstep
|
|
789
797
|
end
|
790
798
|
|
791
799
|
def update_attributes(attributes = {})
|
792
|
-
|
800
|
+
update(attributes)
|
793
801
|
end
|
794
802
|
|
795
803
|
def update_attribute(key, value)
|
796
|
-
send(key.to_s +
|
804
|
+
send(key.to_s + '=', value)
|
797
805
|
update
|
798
806
|
end
|
799
807
|
|
800
808
|
def destroy
|
801
|
-
resp =
|
802
|
-
if resp.code.to_s ==
|
809
|
+
resp = resource.delete(id)
|
810
|
+
if resp.code.to_s == '200'
|
803
811
|
@attributes = {}
|
804
812
|
@unsaved_attributes = {}
|
805
813
|
return true
|
@@ -812,7 +820,7 @@ module Lockstep
|
|
812
820
|
|
813
821
|
fresh_object = self.class.find(id)
|
814
822
|
@attributes = {}
|
815
|
-
@attributes.update(fresh_object.instance_variable_get(
|
823
|
+
@attributes.update(fresh_object.instance_variable_get('@attributes'))
|
816
824
|
@unsaved_attributes = {}
|
817
825
|
|
818
826
|
self
|
@@ -845,27 +853,30 @@ module Lockstep
|
|
845
853
|
attrs = @unsaved_attributes[k.to_s] ? @unsaved_attributes : @attributes
|
846
854
|
case attrs[k]
|
847
855
|
when Hash
|
848
|
-
klass_name = attrs[k][
|
849
|
-
klass_name =
|
850
|
-
case attrs[k][
|
851
|
-
when
|
852
|
-
result = klass_name.to_s.constantize.find(attrs[k][
|
853
|
-
when
|
856
|
+
klass_name = attrs[k]['className']
|
857
|
+
klass_name = 'User' if klass_name == '_User'
|
858
|
+
case attrs[k]['__type']
|
859
|
+
when 'Pointer'
|
860
|
+
result = klass_name.to_s.constantize.find(attrs[k][id_ref])
|
861
|
+
when 'Object'
|
854
862
|
result = klass_name.to_s.constantize.new(attrs[k], false)
|
855
|
-
when
|
856
|
-
result = DateTime.parse(attrs[k][
|
857
|
-
when
|
858
|
-
result = attrs[k][
|
859
|
-
when
|
860
|
-
objects_related_to_self = klass_name.constantize.where(
|
863
|
+
when 'Date'
|
864
|
+
result = DateTime.parse(attrs[k]['iso']).in_time_zone
|
865
|
+
when 'File'
|
866
|
+
result = attrs[k]['url']
|
867
|
+
when 'Relation'
|
868
|
+
objects_related_to_self = klass_name.constantize.where('$relatedTo' => {
|
869
|
+
'object' => { '__type' => 'Pointer',
|
870
|
+
'className' => self.class.to_s, id_ref => id }, 'key' => k
|
871
|
+
}).all
|
861
872
|
attrs[k] = Lockstep::RelationArray.new self, objects_related_to_self, k, klass_name
|
862
873
|
@unsaved_attributes[k] = Lockstep::RelationArray.new self, objects_related_to_self, k, klass_name
|
863
874
|
result = @unsaved_attributes[k]
|
864
875
|
end
|
865
876
|
else
|
866
|
-
# TODO changed from @@has_many_relations to @@has_many_relations.keys as we have changed the has_many_relations
|
877
|
+
# TODO: changed from @@has_many_relations to @@has_many_relations.keys as we have changed the has_many_relations
|
867
878
|
# from array to hash to capture more data points. Not sure of the impact of this.
|
868
|
-
#relation will assign itself if an array, this will add to unsave_attributes
|
879
|
+
# relation will assign itself if an array, this will add to unsave_attributes
|
869
880
|
if has_many_relations.keys.index(k.to_s)
|
870
881
|
if attrs[k].nil?
|
871
882
|
# result = nil
|
@@ -883,7 +894,7 @@ module Lockstep
|
|
883
894
|
result = @unsaved_attributes[k]
|
884
895
|
end
|
885
896
|
else
|
886
|
-
result = attrs[
|
897
|
+
result = attrs[k.to_s]
|
887
898
|
end
|
888
899
|
end
|
889
900
|
result
|
@@ -938,24 +949,28 @@ module Lockstep
|
|
938
949
|
end
|
939
950
|
|
940
951
|
def primary_key
|
941
|
-
|
952
|
+
id_ref
|
942
953
|
end
|
943
954
|
|
944
955
|
# aliasing for idiomatic Ruby
|
945
956
|
def id
|
946
|
-
get_attribute(
|
957
|
+
get_attribute(id_ref)
|
958
|
+
rescue StandardError
|
959
|
+
nil
|
947
960
|
end
|
948
961
|
|
949
962
|
def objectId
|
950
|
-
get_attribute(
|
963
|
+
get_attribute(id_ref)
|
964
|
+
rescue StandardError
|
965
|
+
nil
|
951
966
|
end
|
952
967
|
|
953
968
|
def created_at
|
954
|
-
get_attribute(
|
969
|
+
get_attribute('created')
|
955
970
|
end
|
956
971
|
|
957
972
|
def updated_at
|
958
|
-
get_attribute(
|
973
|
+
get_attribute('modified')
|
959
974
|
end
|
960
975
|
|
961
976
|
def self.included(base)
|
@@ -965,10 +980,10 @@ module Lockstep
|
|
965
980
|
module ClassMethods
|
966
981
|
end
|
967
982
|
|
968
|
-
#if we are comparing objects, use id if they are both Lockstep::ApiRecord objects
|
969
|
-
def ==(
|
970
|
-
if
|
971
|
-
|
983
|
+
# if we are comparing objects, use id if they are both Lockstep::ApiRecord objects
|
984
|
+
def ==(other)
|
985
|
+
if other.class <= Lockstep::ApiRecord
|
986
|
+
id == other.id
|
972
987
|
else
|
973
988
|
super
|
974
989
|
end
|
@@ -989,12 +1004,14 @@ module Lockstep
|
|
989
1004
|
val = relation_config[:loader].call(self)
|
990
1005
|
else
|
991
1006
|
return val unless relation_config[:foreign_key].present? and relation_config[:primary_key].present?
|
1007
|
+
|
992
1008
|
relation_klass = relation_config[:class_name].constantize
|
993
1009
|
return val unless relation_klass.model_name_uri.present?
|
994
1010
|
|
995
|
-
query = { relation_config[:foreign_key] =>
|
1011
|
+
query = { relation_config[:foreign_key] => send(relation_config[:primary_key]) }
|
996
1012
|
if relation_config[:polymorphic]
|
997
|
-
polymorphic_config = Lockstep::RelationArray.has_many_polymorphic_attributes(self,
|
1013
|
+
polymorphic_config = Lockstep::RelationArray.has_many_polymorphic_attributes(self,
|
1014
|
+
relation_config[:polymorphic])
|
998
1015
|
query.merge!(polymorphic_config)
|
999
1016
|
end
|
1000
1017
|
related_objects = relation_klass.send(:where, query).execute
|
@@ -1005,7 +1022,8 @@ module Lockstep
|
|
1005
1022
|
if relation_config[:loader].present?
|
1006
1023
|
val = relation_config[:loader].call(self)
|
1007
1024
|
else
|
1008
|
-
val = relation_config[:class_name].constantize.send(:find_by,
|
1025
|
+
val = relation_config[:class_name].constantize.send(:find_by,
|
1026
|
+
relation_config[:primary_key] => send(relation_config[:foreign_key]))
|
1009
1027
|
end
|
1010
1028
|
end
|
1011
1029
|
|
@@ -1060,7 +1078,7 @@ module Lockstep
|
|
1060
1078
|
elsif values.is_a?(Hash)
|
1061
1079
|
value_map = values.with_indifferent_access
|
1062
1080
|
else
|
1063
|
-
raise StandardError
|
1081
|
+
raise StandardError, "Invalid values for enum #{attribute}"
|
1064
1082
|
end
|
1065
1083
|
|
1066
1084
|
# Convert values to string if the value is symbol
|
@@ -1089,9 +1107,21 @@ module Lockstep
|
|
1089
1107
|
value = get_attribute(attribute)
|
1090
1108
|
next if value.nil?
|
1091
1109
|
|
1092
|
-
unless values_map.values.include?(value)
|
1093
|
-
|
1094
|
-
|
1110
|
+
errors.add attribute, 'has an invalid value' unless values_map.values.include?(value)
|
1111
|
+
end
|
1112
|
+
end
|
1113
|
+
|
1114
|
+
def self.single_record!
|
1115
|
+
define_singleton_method :record do
|
1116
|
+
resp = resource.get('')
|
1117
|
+
|
1118
|
+
return [] if %w(404).include?(resp.code.to_s)
|
1119
|
+
# TODO handle non 200 response code. Throwing an exception for now
|
1120
|
+
raise StandardError.new("#{resp.code} error while fetching: #{resp.body}") unless %w(201 200).include?(resp.code.to_s)
|
1121
|
+
|
1122
|
+
result = JSON.parse(resp.body)
|
1123
|
+
r = result.transform_keys { |key| key.underscore }
|
1124
|
+
model_name.to_s.constantize.new(r, false)
|
1095
1125
|
end
|
1096
1126
|
end
|
1097
1127
|
|
@@ -1111,7 +1141,7 @@ module Lockstep
|
|
1111
1141
|
as_json(options).to_json
|
1112
1142
|
end
|
1113
1143
|
|
1114
|
-
def as_json(
|
1144
|
+
def as_json(_options = {})
|
1115
1145
|
@attributes.merge(@unsaved_attributes).as_json
|
1116
1146
|
end
|
1117
1147
|
end
|
@@ -225,11 +225,15 @@ class Lockstep::Query
|
|
225
225
|
# TODO handle non 200 response code. Throwing an exception for now
|
226
226
|
raise StandardError.new("#{resp.code} error while fetching: #{resp.body}") unless %w(201 200).include?(resp.code.to_s)
|
227
227
|
|
228
|
+
parsed_response = JSON.parse(resp.body)
|
229
|
+
|
228
230
|
if criteria[:count]
|
229
|
-
|
231
|
+
raise StandardError.new("Count is not supported for #{@klass}") if parsed_response.is_a?(Array)
|
232
|
+
|
233
|
+
results = parsed_response["totalCount"]
|
230
234
|
return results.to_i
|
231
235
|
else
|
232
|
-
results =
|
236
|
+
results = parsed_response.is_a?(Array) ? parsed_response : parsed_response["records"]
|
233
237
|
results = results[0..(criteria[:limit] - 1)] if criteria[:limit]
|
234
238
|
get_relation_objects results.map { |r|
|
235
239
|
# Convert camelcase to snake-case
|
@@ -1,21 +1,21 @@
|
|
1
1
|
class Schema::Invoice < Lockstep::ApiRecord
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
# The GroupKey uniquely identifies a single Lockstep Platform account. All records for this
|
9
|
-
# account will share the same GroupKey value. GroupKey values cannot be changed once created.
|
10
|
-
#
|
3
|
+
# ApiRecord will crash unless `id_ref` is defined
|
4
|
+
def self.id_ref
|
5
|
+
nil
|
6
|
+
end
|
7
|
+
|
8
|
+
# The GroupKey uniquely identifies a single Lockstep Platform account. All records for this
|
9
|
+
# account will share the same GroupKey value. GroupKey values cannot be changed once created.
|
10
|
+
#
|
11
11
|
# For more information, see [Accounts and GroupKeys](https://developer.lockstep.io/docs/accounts-and-groupkeys).
|
12
12
|
# @type: string
|
13
13
|
# @format: uuid
|
14
14
|
field :group_key
|
15
15
|
|
16
|
-
# The unique ID of this record, automatically assigned by Lockstep when this record is
|
17
|
-
# added to the Lockstep platform.
|
18
|
-
#
|
16
|
+
# The unique ID of this record, automatically assigned by Lockstep when this record is
|
17
|
+
# added to the Lockstep platform.
|
18
|
+
#
|
19
19
|
# For the ID of this record in its originating financial system, see `ErpKey`.
|
20
20
|
# @type: string
|
21
21
|
# @format: uuid
|
@@ -31,23 +31,23 @@ class Schema::Invoice < Lockstep::ApiRecord
|
|
31
31
|
# @format: uuid
|
32
32
|
field :customer_id
|
33
33
|
|
34
|
-
# The unique ID of this record as it was known in its originating financial system.
|
35
|
-
#
|
36
|
-
# If this company record was imported from a financial system, it will have the value `ErpKey`
|
37
|
-
# set to the original primary key number of the record as it was known in the originating financial
|
38
|
-
# system. If this record was not imported, this value will be `null`.
|
39
|
-
#
|
34
|
+
# The unique ID of this record as it was known in its originating financial system.
|
35
|
+
#
|
36
|
+
# If this company record was imported from a financial system, it will have the value `ErpKey`
|
37
|
+
# set to the original primary key number of the record as it was known in the originating financial
|
38
|
+
# system. If this record was not imported, this value will be `null`.
|
39
|
+
#
|
40
40
|
# For more information, see [Identity Columns](https://developer.lockstep.io/docs/identity-columns).
|
41
41
|
# @type: string
|
42
42
|
field :erp_key
|
43
43
|
|
44
|
-
# The "Purchase Order Code" is a code that is sometimes used by companies to refer to the original PO
|
45
|
-
# that was sent that caused this invoice to be written. If a customer sends a purchase order to a vendor,
|
44
|
+
# The "Purchase Order Code" is a code that is sometimes used by companies to refer to the original PO
|
45
|
+
# that was sent that caused this invoice to be written. If a customer sends a purchase order to a vendor,
|
46
46
|
# the vendor can then create an invoice and refer back to the originating purchase order using this field.
|
47
47
|
# @type: string
|
48
48
|
field :purchase_order_code
|
49
49
|
|
50
|
-
# An additional reference code that is sometimes used to identify this invoice.
|
50
|
+
# An additional reference code that is sometimes used to identify this invoice.
|
51
51
|
# The meaning of this field is specific to the ERP or accounting system used by the user.
|
52
52
|
# @type: string
|
53
53
|
field :reference_code
|
@@ -60,24 +60,24 @@ class Schema::Invoice < Lockstep::ApiRecord
|
|
60
60
|
# @type: string
|
61
61
|
field :salesperson_name
|
62
62
|
|
63
|
-
# A code identifying the type of this invoice.
|
64
|
-
#
|
65
|
-
# Recognized Invoice types are:
|
66
|
-
# * `Invoice` - Represents an invoice sent by Company to the Customer
|
67
|
-
# * `AP Invoice` - Represents an invoice sent by Customer to the Company
|
63
|
+
# A code identifying the type of this invoice.
|
64
|
+
#
|
65
|
+
# Recognized Invoice types are:
|
66
|
+
# * `Invoice` - Represents an invoice sent by Company to the Customer
|
67
|
+
# * `AP Invoice` - Represents an invoice sent by Customer to the Company
|
68
68
|
# * `Credit Memo` - Represents a credit memo generated by Customer given to Company
|
69
69
|
# @type: string
|
70
70
|
field :invoice_type_code
|
71
71
|
|
72
|
-
# A code identifying the status of this invoice.
|
73
|
-
#
|
74
|
-
# Recognized Invoice status codes are:
|
75
|
-
# * `Open` - Represents an invoice that is considered open and needs more work to complete
|
72
|
+
# A code identifying the status of this invoice.
|
73
|
+
#
|
74
|
+
# Recognized Invoice status codes are:
|
75
|
+
# * `Open` - Represents an invoice that is considered open and needs more work to complete
|
76
76
|
# * `Closed` - Represents an invoice that is considered closed and resolved
|
77
77
|
# @type: string
|
78
78
|
field :invoice_status_code
|
79
79
|
|
80
|
-
# A code identifying the terms given to the purchaser. This field is imported directly from the originating
|
80
|
+
# A code identifying the terms given to the purchaser. This field is imported directly from the originating
|
81
81
|
# financial system and does not follow a specified format.
|
82
82
|
# @type: string
|
83
83
|
field :terms_code
|
@@ -125,7 +125,7 @@ class Schema::Invoice < Lockstep::ApiRecord
|
|
125
125
|
# @format: date
|
126
126
|
field :posted_date
|
127
127
|
|
128
|
-
# The date when the invoice was closed and finalized after completion of all payments and delivery of all products and
|
128
|
+
# The date when the invoice was closed and finalized after completion of all payments and delivery of all products and
|
129
129
|
# services.
|
130
130
|
# @type: string
|
131
131
|
# @format: date
|
@@ -176,9 +176,9 @@ class Schema::Invoice < Lockstep::ApiRecord
|
|
176
176
|
# @format: uuid
|
177
177
|
field :modified_user_id
|
178
178
|
|
179
|
-
# The AppEnrollmentId of the application that imported this record. For accounts
|
180
|
-
# with more than one financial system connected, this field identifies the originating
|
181
|
-
# financial system that produced this record. This value is null if this record
|
179
|
+
# The AppEnrollmentId of the application that imported this record. For accounts
|
180
|
+
# with more than one financial system connected, this field identifies the originating
|
181
|
+
# financial system that produced this record. This value is null if this record
|
182
182
|
# was not loaded from an external ERP or financial system.
|
183
183
|
# @type: string
|
184
184
|
# @format: uuid
|
@@ -196,31 +196,32 @@ class Schema::Invoice < Lockstep::ApiRecord
|
|
196
196
|
# @type: boolean
|
197
197
|
field :exclude_from_aging
|
198
198
|
|
199
|
-
# The Company associated to this invoice.
|
199
|
+
# The Company associated to this invoice.
|
200
200
|
# To retrieve this item, specify `Company` in the "Include" parameter for your query.
|
201
201
|
field :company
|
202
202
|
|
203
|
-
# The Customer associated to the invoice customer
|
203
|
+
# The Customer associated to the invoice customer
|
204
204
|
# To retrieve this item, specify `Customer` in the "Include" parameter for your query.
|
205
205
|
field :customer
|
206
206
|
|
207
|
-
# The Contact associated to the invoice customer
|
207
|
+
# The Contact associated to the invoice customer
|
208
208
|
# To retrieve this item, specify `Customer` in the "Include" parameter for your query.
|
209
209
|
field :customer_primary_contact
|
210
210
|
|
211
|
-
belongs_to :company, {
|
212
|
-
belongs_to :account, {
|
213
|
-
belongs_to :customer, {
|
214
|
-
belongs_to :connection, {
|
215
|
-
belongs_to :created_user, {
|
216
|
-
belongs_to :modified_user, {
|
217
|
-
|
218
|
-
has_many :addresses, {
|
219
|
-
has_many :lines, {
|
220
|
-
has_many :payments, {
|
221
|
-
has_many :notes, {
|
222
|
-
has_many :attachments, {
|
223
|
-
has_many :credit_memos, {
|
224
|
-
has_many :custom_field_values, {
|
225
|
-
has_many :custom_field_definitions, {
|
226
|
-
|
211
|
+
belongs_to :company, {:class_name=>"Lockstep::Account", :primary_key=>:company_id, :foreign_key=>"company_id"}
|
212
|
+
belongs_to :account, {:class_name=>"Lockstep::Account", :primary_key=>:company_id, :foreign_key=>"company_id"}
|
213
|
+
belongs_to :customer, {:class_name=>"Lockstep::Connection", :primary_key=>:company_id, :foreign_key=>"customer_id"}
|
214
|
+
belongs_to :connection, {:class_name=>"Lockstep::Connection", :primary_key=>:company_id, :foreign_key=>"customer_id"}
|
215
|
+
belongs_to :created_user, {:class_name=>"Lockstep::User", :primary_key=>:user_id, :foreign_key=>"created_user_id"}
|
216
|
+
belongs_to :modified_user, {:class_name=>"Lockstep::User", :primary_key=>:user_id, :foreign_key=>"modified_user_id"}
|
217
|
+
|
218
|
+
has_many :addresses, {:class_name=>"Schema::InvoiceAddress", :included=>true}
|
219
|
+
has_many :lines, {:class_name=>"Schema::InvoiceLine", :included=>true}
|
220
|
+
has_many :payments, {:class_name=>"Schema::InvoicePaymentDetail", :included=>true}
|
221
|
+
has_many :notes, {:class_name=>"Lockstep::Note", :included=>true, :foreign_key=>:object_key, :polymorphic=>{:table_key=>"Invoice"}}
|
222
|
+
has_many :attachments, {:class_name=>"Schema::Attachment", :included=>true}
|
223
|
+
has_many :credit_memos, {:class_name=>"Schema::CreditMemoInvoice", :included=>true}
|
224
|
+
has_many :custom_field_values, {:class_name=>"Schema::CustomFieldValue", :included=>true}
|
225
|
+
has_many :custom_field_definitions, {:class_name=>"Schema::CustomFieldDefinition", :included=>true}
|
226
|
+
|
227
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
class Schema::VendorSummary < Lockstep::ApiRecord
|
2
|
+
|
3
|
+
# ApiRecord will crash unless `id_ref` is defined
|
4
|
+
def self.id_ref
|
5
|
+
nil
|
6
|
+
end
|
7
|
+
|
8
|
+
# The GroupKey uniquely identifies a single Lockstep Platform account. All records for this
|
9
|
+
# account will share the same GroupKey value. GroupKey values cannot be changed once created.
|
10
|
+
#
|
11
|
+
# For more information, see [Accounts and GroupKeys](https://developer.lockstep.io/docs/accounts-and-groupkeys).
|
12
|
+
# @type: string
|
13
|
+
# @format: uuid
|
14
|
+
field :group_key
|
15
|
+
|
16
|
+
# The unique ID of this company.
|
17
|
+
# @type: string
|
18
|
+
# @format: uuid
|
19
|
+
field :vendor_id
|
20
|
+
|
21
|
+
# The name of the company.
|
22
|
+
# @type: string
|
23
|
+
field :vendor_name
|
24
|
+
|
25
|
+
# The app enrollment ID this Vendor is associated with
|
26
|
+
# @type: string
|
27
|
+
# @format: uuid
|
28
|
+
field :app_enrollment_id
|
29
|
+
|
30
|
+
# The name of this Vendor's primary contact
|
31
|
+
# @type: string
|
32
|
+
field :primary_contact_name
|
33
|
+
|
34
|
+
# This Vendor's primary contact id
|
35
|
+
# @type: string
|
36
|
+
# @format: uuid
|
37
|
+
field :primary_contact_id
|
38
|
+
|
39
|
+
# The amount paid to this Vendor in the last 30 days
|
40
|
+
# @type: double
|
41
|
+
field :amount_paid_last30
|
42
|
+
|
43
|
+
# The outstanding advance pay balance with this Vendor
|
44
|
+
# @type: number
|
45
|
+
# @format: double
|
46
|
+
field :advance_pay_outstanding
|
47
|
+
|
48
|
+
# The amount billed from this Vendor in the last 30 days
|
49
|
+
# @type: number
|
50
|
+
# @format: double
|
51
|
+
field :amount_billed_last30
|
52
|
+
|
53
|
+
# The outstanding balance with this Vendor
|
54
|
+
# @type: number
|
55
|
+
# @format: double
|
56
|
+
field :amount_billed_outstanding
|
57
|
+
|
58
|
+
# The number of open bills with this Vendor
|
59
|
+
# @type: integer
|
60
|
+
# @format: int32
|
61
|
+
field :open_bill_count
|
62
|
+
|
63
|
+
# The number of bills paid to this Vendor in the last 30 days
|
64
|
+
# @type: integer
|
65
|
+
# @format: int32
|
66
|
+
field :paid_bill_count
|
67
|
+
|
68
|
+
# The total count of open bills and those paid in the last 30 days
|
69
|
+
# @type: integer
|
70
|
+
# @format: int32
|
71
|
+
field :total_bill_count
|
72
|
+
|
73
|
+
|
74
|
+
belongs_to :company, {:class_name=>"Lockstep::Account", :primary_key=>:company_id, :foreign_key=>"company_id"}
|
75
|
+
belongs_to :account, {:class_name=>"Lockstep::Account", :primary_key=>:company_id, :foreign_key=>"company_id"}
|
76
|
+
|
77
|
+
|
78
|
+
end
|
@@ -5,15 +5,15 @@ def self.id_ref
|
|
5
5
|
nil
|
6
6
|
end
|
7
7
|
|
8
|
-
# The unique ID of this record, automatically assigned by Lockstep when this record is
|
8
|
+
# The unique ID of this record, automatically assigned by Lockstep when this record is
|
9
9
|
# added to the Lockstep platform.
|
10
10
|
# @type: string
|
11
11
|
# @format: uuid
|
12
12
|
field :webhook_id
|
13
13
|
|
14
|
-
# The GroupKey uniquely identifies a single Lockstep Platform account. All records for this
|
15
|
-
# account will share the same GroupKey value. GroupKey values cannot be changed once created.
|
16
|
-
#
|
14
|
+
# The GroupKey uniquely identifies a single Lockstep Platform account. All records for this
|
15
|
+
# account will share the same GroupKey value. GroupKey values cannot be changed once created.
|
16
|
+
#
|
17
17
|
# For more information, see [Accounts and GroupKeys](https://developer.lockstep.io/docs/accounts-and-groupkeys).
|
18
18
|
# @type: string
|
19
19
|
# @format: uuid
|
@@ -31,7 +31,7 @@ end
|
|
31
31
|
# @type: string
|
32
32
|
field :status_message
|
33
33
|
|
34
|
-
# An secret set during webhook creation that can be used to verify that the notification
|
34
|
+
# An secret set during webhook creation that can be used to verify that the notification
|
35
35
|
# is coming from the Lockstep API.
|
36
36
|
# @type: string
|
37
37
|
field :client_secret
|
@@ -44,17 +44,17 @@ end
|
|
44
44
|
# @type: string
|
45
45
|
field :callback_http_method
|
46
46
|
|
47
|
-
# The URL where the notification will be sent via the method set in CallbackHttpMethod.
|
48
|
-
#
|
49
|
-
# When creating a webhook, the Lockstep API will make a call to this url via the method
|
50
|
-
# set in the CallbackHttpMethod property with a query parameter of "code" set to an encoded
|
51
|
-
# string. To successfully create the webhook, the call must return a successful status code
|
47
|
+
# The URL where the notification will be sent via the method set in CallbackHttpMethod.
|
48
|
+
#
|
49
|
+
# When creating a webhook, the Lockstep API will make a call to this url via the method
|
50
|
+
# set in the CallbackHttpMethod property with a query parameter of "code" set to an encoded
|
51
|
+
# string. To successfully create the webhook, the call must return a successful status code
|
52
52
|
# with the query parameter's value as the plain text content.
|
53
53
|
# @type: string
|
54
54
|
# @format: uri
|
55
55
|
field :callback_url
|
56
56
|
|
57
|
-
# The expiration date for the given webhook subscription. Once the expiration date passes,
|
57
|
+
# The expiration date for the given webhook subscription. Once the expiration date passes,
|
58
58
|
# notifications will no longer be sent to the callback url.
|
59
59
|
# @type: string
|
60
60
|
# @format: date-time
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lockstep_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.26
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vivek AG
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -55,7 +55,13 @@ files:
|
|
55
55
|
- app/models/lockstep/note.rb
|
56
56
|
- app/models/lockstep/payment.rb
|
57
57
|
- app/models/lockstep/payment_summary.rb
|
58
|
+
- app/models/lockstep/report_ar_aging_header.rb
|
59
|
+
- app/models/lockstep/report_cashflow.rb
|
60
|
+
- app/models/lockstep/report_daily_sales_outstanding.rb
|
61
|
+
- app/models/lockstep/report_risk_rate.rb
|
58
62
|
- app/models/lockstep/user.rb
|
63
|
+
- app/models/lockstep/vendor_summary.rb
|
64
|
+
- app/models/lockstep/webhook.rb
|
59
65
|
- app/platform_api/model_template.rb.erb
|
60
66
|
- app/platform_api/schema/action_result.rb
|
61
67
|
- app/platform_api/schema/activity.rb
|
@@ -192,6 +198,7 @@ files:
|
|
192
198
|
- app/platform_api/schema/user_account_fetch_result.rb
|
193
199
|
- app/platform_api/schema/user_role.rb
|
194
200
|
- app/platform_api/schema/user_role_fetch_result.rb
|
201
|
+
- app/platform_api/schema/vendor_summary.rb
|
195
202
|
- app/platform_api/schema/webhook.rb
|
196
203
|
- app/platform_api/schema/webhook_fetch_result.rb
|
197
204
|
- app/platform_api/schema/webhook_history_table_storage.rb
|