mls 1.5.1 → 1.6.0
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 +4 -4
- data/bin/mls +17 -0
- data/lib/mls.rb +3 -1
- data/lib/mls/cli.rb +48 -0
- data/lib/mls/cli/documents.rb +71 -0
- data/lib/mls/cli/storage.rb +1 -0
- data/lib/mls/cli/storage/s3.rb +99 -0
- data/lib/mls/{account.rb → models/account.rb} +27 -7
- data/lib/mls/{accounts_region.rb → models/accounts_region.rb} +0 -0
- data/lib/mls/models/action.rb +44 -0
- data/lib/mls/{address.rb → models/address.rb} +0 -0
- data/lib/mls/{api_key.rb → models/api_key.rb} +0 -0
- data/lib/mls/{coworking_space.rb → models/coworking_space.rb} +0 -1
- data/lib/mls/{credit_card.rb → models/credit_card.rb} +0 -0
- data/lib/mls/{datum.rb → models/datum.rb} +0 -0
- data/lib/mls/{document.rb → models/document.rb} +0 -0
- data/lib/mls/{email.rb → models/email.rb} +0 -0
- data/lib/mls/{email_address.rb → models/email_address.rb} +0 -0
- data/lib/mls/models/email_digest.rb +13 -0
- data/lib/mls/{event.rb → models/event.rb} +0 -0
- data/lib/mls/{flyer.rb → models/flyer.rb} +0 -0
- data/lib/mls/{geometry.rb → models/geometry.rb} +0 -0
- data/lib/mls/{image_ordering.rb → models/image_ordering.rb} +0 -0
- data/lib/mls/{impression_count.rb → models/impression_count.rb} +0 -0
- data/lib/mls/{inquiry.rb → models/inquiry.rb} +16 -1
- data/lib/mls/{invoice.rb → models/invoice.rb} +1 -1
- data/lib/mls/models/lead.rb +26 -0
- data/lib/mls/{listing.rb → models/listing.rb} +20 -4
- data/lib/mls/{locality.rb → models/locality.rb} +0 -0
- data/lib/mls/{metadatum.rb → models/metadatum.rb} +0 -0
- data/lib/mls/{mistake.rb → models/mistake.rb} +0 -0
- data/lib/mls/{organization.rb → models/organization.rb} +0 -0
- data/lib/mls/{ownership.rb → models/ownership.rb} +0 -0
- data/lib/mls/{phone.rb → models/phone.rb} +0 -0
- data/lib/mls/{property.rb → models/property.rb} +31 -3
- data/lib/mls/{recommendation.rb → models/recommendation.rb} +0 -0
- data/lib/mls/{reference.rb → models/reference.rb} +0 -0
- data/lib/mls/{region.rb → models/region.rb} +8 -2
- data/lib/mls/models/search.rb +63 -0
- data/lib/mls/models/service.rb +11 -0
- data/lib/mls/{session.rb → models/session.rb} +0 -0
- data/lib/mls/models/site.rb +26 -0
- data/lib/mls/{slug.rb → models/slug.rb} +0 -0
- data/lib/mls/{source.rb → models/source.rb} +0 -0
- data/lib/mls/{space.rb → models/space.rb} +0 -0
- data/lib/mls/{stat.rb → models/stat.rb} +0 -0
- data/lib/mls/models/subscription.rb +19 -0
- data/lib/mls/models/suggestion.rb +13 -0
- data/lib/mls/{task.rb → models/task.rb} +0 -0
- data/lib/mls/{team.rb → models/team.rb} +0 -0
- data/lib/mls/models/tim_alert.rb +7 -0
- data/lib/mls/{time_log.rb → models/time_log.rb} +0 -0
- data/lib/mls/{use.rb → models/use.rb} +0 -0
- data/lib/mls/{vendor.rb → models/vendor.rb} +0 -0
- data/lib/mls/{view.rb → models/view.rb} +0 -0
- data/lib/mls/{webpage.rb → models/webpage.rb} +0 -0
- data/lib/mls/rack/proxy.rb +78 -0
- data/lib/mls/railtie.rb +32 -0
- data/mls.gemspec +1 -1
- metadata +61 -49
- data/lib/mls/action.rb +0 -18
- data/lib/mls/email_digest.rb +0 -10
- data/lib/mls/lead.rb +0 -6
- data/lib/mls/membership.rb +0 -27
- data/lib/mls/subscription.rb +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '05855a1a8a8ff7514aa0d09798c336972c6443cc'
|
4
|
+
data.tar.gz: 689bc19414f3f6516d74bb8f8721d6019fb86060
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e675d1684d26d1fc2a5c64fe995bce74f185090a161844091bc24b5bfc7d6f36d723d2a6f57700ee41589dedb58d77044ab29a752ed75c3783f714fa2bdc827b
|
7
|
+
data.tar.gz: a94d1a6219a065cbc0c436e167f06a333c90662aec2160d5cf62e3a4dd1bed96100d2296e364d1ce71c9fd1b9cb6488aaaced1e66cdd0f9e60bf683534fad5ae
|
data/bin/mls
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.expand_path('../../lib/mls/cli', __FILE__)
|
3
|
+
|
4
|
+
case ARGV.shift.downcase.strip
|
5
|
+
when "documents:backup"
|
6
|
+
MLS::CLI.parse_args(ARGV).inspect
|
7
|
+
directory = ARGV.shift
|
8
|
+
|
9
|
+
if directory.nil? || !File.directory?(directory)
|
10
|
+
puts "Usage: mls documents:backup dir [options...]"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
MLS::CLI::Documents.backup(directory)
|
15
|
+
else
|
16
|
+
puts "Usage: mls documents:backup dir [options...]"
|
17
|
+
end
|
data/lib/mls.rb
CHANGED
data/lib/mls/cli.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path('../../mls', __FILE__)
|
2
|
+
require 'uri'
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
module MLS::CLI
|
6
|
+
|
7
|
+
def self.options
|
8
|
+
if !class_variable_defined?(:@@options)
|
9
|
+
@@options = {}
|
10
|
+
end
|
11
|
+
@@options
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.parse_args(args)
|
15
|
+
OptionParser.new do |opts|
|
16
|
+
opts.on("-aURL", "--auth=URL", "URL Credentials for MLS, S3 or B2") do |arg|
|
17
|
+
url = URI.parse(arg)
|
18
|
+
case url.scheme
|
19
|
+
when 's3' # ACCESS_KEY:SECRET_KEY@BUCKET[/PREFIX][?parition=4]
|
20
|
+
MLS::CLI.options[:s3] = {
|
21
|
+
access_key_id: URI.unescape(url.user),
|
22
|
+
secret_access_key: URI.unescape(url.password),
|
23
|
+
bucket: URI.unescape(url.host)
|
24
|
+
}
|
25
|
+
MLS::CLI.options[:s3][:prefix] = url.path if url.path && !url.path.empty?
|
26
|
+
url.query.split('&').each do |qp|
|
27
|
+
key, value = qp.split('=').map { |d| URI.unescape(d) }
|
28
|
+
case key
|
29
|
+
when 'partition'
|
30
|
+
MLS::CLI.options[:s3][:partition] = true
|
31
|
+
MLS::CLI.options[:s3][:partition_depth] = value.to_i
|
32
|
+
end
|
33
|
+
end
|
34
|
+
when 'b2'
|
35
|
+
|
36
|
+
when 'mls'
|
37
|
+
arg = arg.sub('mls://', 'https://')
|
38
|
+
MLS::CLI.options[:mls] = arg
|
39
|
+
MLS::Model.establish_connection(adapter: 'sunstone', url: arg)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end.parse!(args)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
require File.expand_path('../cli/storage', __FILE__)
|
48
|
+
require File.expand_path('../cli/documents', __FILE__)
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'digest'
|
3
|
+
|
4
|
+
module MLS::CLI::Documents
|
5
|
+
|
6
|
+
def self.partition(value, depth: 5)
|
7
|
+
split = value.scan(/.{1,4}/)
|
8
|
+
split.shift(depth).join("/") + split.join("")
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.calculate_digest(file)
|
12
|
+
md5_digest = Digest::MD5.new
|
13
|
+
sha1_digest = Digest::SHA1.new
|
14
|
+
sha256_digest = Digest::SHA256.new
|
15
|
+
|
16
|
+
buf = ""
|
17
|
+
file.rewind
|
18
|
+
while file.read(16384, buf)
|
19
|
+
md5_digest << buf
|
20
|
+
sha1_digest << buf
|
21
|
+
sha256_digest << buf
|
22
|
+
end
|
23
|
+
|
24
|
+
{
|
25
|
+
md5: md5_digest.hexdigest,
|
26
|
+
sha1: sha1_digest.hexdigest,
|
27
|
+
sha256: sha256_digest.hexdigest
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.backup(dir)
|
32
|
+
last_sync_file = File.join(dir, '.last_sync')
|
33
|
+
|
34
|
+
query = if File.exist?(last_sync_file)
|
35
|
+
from_timestamp = Time.iso8601(File.read(last_sync_file))
|
36
|
+
Document.filter(created_at: {gte: from_timestamp})
|
37
|
+
else
|
38
|
+
Document.all
|
39
|
+
end
|
40
|
+
|
41
|
+
query.find_each do |document|
|
42
|
+
if document.sha256 && File.exists?(File.join(dir, partition(document.sha256)))
|
43
|
+
puts "Downloaded #{document.id}"
|
44
|
+
next
|
45
|
+
end
|
46
|
+
|
47
|
+
if document.provider.nil? || document.provider.include?('s3/hash_key')
|
48
|
+
storage_engine = MLS::CLI::Storage::S3.new(MLS::CLI.options[:s3])
|
49
|
+
key = 'hash_key'
|
50
|
+
else
|
51
|
+
raise 'unkown storage engine'
|
52
|
+
end
|
53
|
+
|
54
|
+
puts "Downloading #{document.id}"
|
55
|
+
storage_engine.copy_to_tempfile(document.send(key)) do |file|
|
56
|
+
digests = calculate_digest(file)
|
57
|
+
|
58
|
+
raise 'MD5 does not match' if digests[:md5] != document.md5
|
59
|
+
document.update!(digests.merge({provider: ['s3/hash_key']}))
|
60
|
+
|
61
|
+
FileUtils.mkdir_p(File.dirname(File.join(dir, partition(document.sha256))))
|
62
|
+
FileUtils.mv(file.path, File.join(dir, partition(document.sha256)), verbose: true)
|
63
|
+
end
|
64
|
+
|
65
|
+
File.write(last_sync_file, document.created_at.iso8601(6))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
require File.expand_path('../storage/s3', __FILE__)
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'aws-sdk-s3'
|
2
|
+
|
3
|
+
module MLS::CLI::Storage
|
4
|
+
class S3
|
5
|
+
|
6
|
+
def initialize(configs = {})
|
7
|
+
@configs = configs
|
8
|
+
@configs[:region] ||= 'us-east-1'
|
9
|
+
@configs[:prefix] ||= ""
|
10
|
+
|
11
|
+
@client = Aws::S3::Client.new({
|
12
|
+
access_key_id: configs[:access_key_id],
|
13
|
+
secret_access_key: configs[:secret_access_key],
|
14
|
+
region: configs[:region]
|
15
|
+
})
|
16
|
+
end
|
17
|
+
|
18
|
+
def object_for(key)
|
19
|
+
Aws::S3::Object.new(@configs[:bucket], key, client: @client)
|
20
|
+
end
|
21
|
+
|
22
|
+
def local?
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
def url(key)
|
27
|
+
[host, destination(key)].join('/')
|
28
|
+
end
|
29
|
+
|
30
|
+
def host
|
31
|
+
h = @configs[:bucket_host_alias] || "https://s3.amazonaws.com/#{@configs[:bucket]}"
|
32
|
+
h.delete_suffix('/')
|
33
|
+
end
|
34
|
+
|
35
|
+
def destination(key)
|
36
|
+
"#{@configs[:prefix]}#{partition(key)}".gsub(/^\//, '')#delete_prefix('/')
|
37
|
+
end
|
38
|
+
|
39
|
+
def exists?(key)
|
40
|
+
object_for(destination(key)).exists?
|
41
|
+
end
|
42
|
+
|
43
|
+
# def write(key, file, meta_info)
|
44
|
+
# file = file.tempfile if file.is_a?(ActionDispatch::Http::UploadedFile)
|
45
|
+
#
|
46
|
+
# object_for(destination(key)).upload_file(file, {
|
47
|
+
# :acl => 'public-read',
|
48
|
+
# :content_disposition => "inline; filename=\"#{meta_info[:filename]}\"",
|
49
|
+
# :content_type => meta_info[:content_type]
|
50
|
+
# })
|
51
|
+
# end
|
52
|
+
|
53
|
+
def read(key, &block)
|
54
|
+
object_for(destination(key)).get()
|
55
|
+
end
|
56
|
+
|
57
|
+
def cp(key, path)
|
58
|
+
object_for(destination(key)).get({ response_target: path })
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
def delete(key)
|
63
|
+
object_for(destination(key)).delete
|
64
|
+
end
|
65
|
+
|
66
|
+
def copy_to_tempfile(key)
|
67
|
+
tmpfile = Tempfile.new([File.basename(key), File.extname(key)], binmode: true)
|
68
|
+
cp(key, tmpfile.path)
|
69
|
+
if block_given?
|
70
|
+
begin
|
71
|
+
yield(tmpfile)
|
72
|
+
ensure
|
73
|
+
tmpfile.close!
|
74
|
+
end
|
75
|
+
else
|
76
|
+
tmpfile
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def partition(value)
|
81
|
+
return value unless @configs[:partition]
|
82
|
+
split = value.scan(/.{1,4}/)
|
83
|
+
split.shift(@configs[:partition_depth] || 3).join("/") + split.join("")
|
84
|
+
end
|
85
|
+
|
86
|
+
def md5(key)
|
87
|
+
object_for(destination(key)).etag
|
88
|
+
end
|
89
|
+
|
90
|
+
def last_modified(key)
|
91
|
+
object_for(destination(key)).last_modified
|
92
|
+
end
|
93
|
+
|
94
|
+
def mime_type(key)
|
95
|
+
object_for(destination(key)).content_type
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
@@ -4,17 +4,23 @@ class Account < MLS::Model
|
|
4
4
|
include MLS::Avatar
|
5
5
|
|
6
6
|
belongs_to :organization
|
7
|
-
belongs_to :
|
8
|
-
|
7
|
+
belongs_to :cobroke_manager, class_name: "Account"
|
8
|
+
|
9
|
+
has_and_belongs_to_many :subscriptions
|
9
10
|
has_many :tasks
|
10
11
|
has_many :sources
|
11
12
|
has_many :ownerships, :inverse_of => :account, :dependent => :delete_all
|
12
13
|
has_many :assets, through: :ownerships
|
13
14
|
has_many :coworking_spaces, through: :ownerships, source: :asset, source_type: 'CoworkingSpace'
|
14
15
|
has_many :listings, through: :ownerships, source: :asset, source_type: 'Listing', inverse_of: :accounts
|
16
|
+
has_many :sites, through: :ownerships, source: :asset, source_type: 'Site', inverse_of: :accounts
|
15
17
|
has_many :email_digests
|
16
|
-
has_many :
|
17
|
-
has_many :
|
18
|
+
has_many :services, as: :subject
|
19
|
+
has_many :tim_alerts
|
20
|
+
has_many :references, as: :subject
|
21
|
+
|
22
|
+
has_many :searches
|
23
|
+
has_many :suggestions, foreign_key: "suggested_by_id"
|
18
24
|
|
19
25
|
has_many :credit_cards
|
20
26
|
|
@@ -28,6 +34,10 @@ class Account < MLS::Model
|
|
28
34
|
end
|
29
35
|
end
|
30
36
|
end
|
37
|
+
|
38
|
+
def deals
|
39
|
+
Search.filter([{manager_id: self.id}, "OR", {broker_id: self.id}])
|
40
|
+
end
|
31
41
|
|
32
42
|
has_many :phones do
|
33
43
|
|
@@ -66,15 +76,19 @@ class Account < MLS::Model
|
|
66
76
|
end
|
67
77
|
|
68
78
|
def tim_alerts?
|
69
|
-
|
79
|
+
subscriptions.map{|x| x.services.filter(status: "active", type: "tim_alerts").count}.sum > 0
|
70
80
|
end
|
71
81
|
|
72
82
|
def unlimited?
|
73
|
-
|
83
|
+
subscriptions.map{|x| x.services.filter(status: "active", type: "unlimited").count}.sum > 0
|
84
|
+
end
|
85
|
+
|
86
|
+
def referral?
|
87
|
+
subscriptions.map{|x| x.services.filter(status: "active", type: "referral").count}.sum > 0
|
74
88
|
end
|
75
89
|
|
76
90
|
def paying?
|
77
|
-
|
91
|
+
subscriptions.map{|x| x.services.filter(status: "active").count}.sum > 0
|
78
92
|
end
|
79
93
|
|
80
94
|
def password_required?
|
@@ -153,6 +167,12 @@ class Account < MLS::Model
|
|
153
167
|
req.body = {url: url}.to_json
|
154
168
|
Account.connection.instance_variable_get(:@connection).send_request(req)
|
155
169
|
end
|
170
|
+
|
171
|
+
def set_confirmation_token
|
172
|
+
req = Net::HTTP::Get.new("/accounts/#{self.id}/confirm")
|
173
|
+
response = Account.connection.instance_variable_get(:@connection).send_request(req)
|
174
|
+
self.confirmation_token = response.body
|
175
|
+
end
|
156
176
|
|
157
177
|
|
158
178
|
end
|
File without changes
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class Action < MLS::Model
|
2
|
+
self.inheritance_column = nil
|
3
|
+
attr_accessor :account_id
|
4
|
+
|
5
|
+
belongs_to :event
|
6
|
+
belongs_to :subject, :polymorphic => true
|
7
|
+
|
8
|
+
has_many :mistakes
|
9
|
+
has_many :metadata, foreign_key: :event_id, primary_key: :event_id
|
10
|
+
|
11
|
+
def self.by_performer(filter)
|
12
|
+
req = Net::HTTP::Get.new("/actions/by_performer")
|
13
|
+
req.body = {
|
14
|
+
where: filter
|
15
|
+
}.to_json
|
16
|
+
JSON.parse(connection.instance_variable_get(:@connection).send_request(req).body)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.squash(attributes)
|
20
|
+
squashed_actions = []
|
21
|
+
where(nil).each do |action|
|
22
|
+
action.account_id = action.metadata.where(key: 'performed_by_id').first&.value
|
23
|
+
|
24
|
+
action.diff = action.diff.slice(*attributes) if attributes
|
25
|
+
if squashed_actions.last &&
|
26
|
+
action.account_id == squashed_actions.last.account_id &&
|
27
|
+
action.timestamp + 15.minutes > squashed_actions.last.timestamp
|
28
|
+
|
29
|
+
action.diff.each do |key, value|
|
30
|
+
next if value[0] == value[1] # filter sometimes logs even if the same
|
31
|
+
if squashed_actions.last.diff[key]
|
32
|
+
squashed_actions.last.diff[key][0] = value[0]
|
33
|
+
else
|
34
|
+
squashed_actions.last.diff[key] = value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
else
|
38
|
+
squashed_actions << action
|
39
|
+
end
|
40
|
+
end
|
41
|
+
squashed_actions
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class EmailDigest < MLS::Model
|
2
|
+
|
3
|
+
belongs_to :search
|
4
|
+
belongs_to :account
|
5
|
+
accepts_nested_attributes_for :account
|
6
|
+
|
7
|
+
def filter
|
8
|
+
filter_to_read = read_attribute(:filter)
|
9
|
+
filter_to_read = search.filter if filter_to_read&.empty? && search
|
10
|
+
JSON.parse (filter_to_read || {}).to_json, object_class: OpenStruct
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,7 +1,8 @@
|
|
1
1
|
class Inquiry < MLS::Model
|
2
|
+
|
3
|
+
TERMS = %w(<1 1-2 3-5 5+ flexible)
|
2
4
|
|
3
5
|
has_many :emails
|
4
|
-
has_many :leads
|
5
6
|
belongs_to :subject, polymorphic: true
|
6
7
|
belongs_to :account
|
7
8
|
|
@@ -10,6 +11,20 @@ class Inquiry < MLS::Model
|
|
10
11
|
def property
|
11
12
|
subject.is_a? MLS::Model::Listing ? subject.property : subject
|
12
13
|
end
|
14
|
+
|
15
|
+
def term_units(value=nil)
|
16
|
+
value ||= self.term
|
17
|
+
case value
|
18
|
+
when "<1"
|
19
|
+
"year"
|
20
|
+
when "flexible"
|
21
|
+
""
|
22
|
+
when nil
|
23
|
+
""
|
24
|
+
else
|
25
|
+
"years"
|
26
|
+
end
|
27
|
+
end
|
13
28
|
|
14
29
|
def account_attributes=(account_attrs)
|
15
30
|
account_attrs = account_attrs&.with_indifferent_access
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Lead < MLS::Model
|
2
|
+
|
3
|
+
STATUSES = %w(delivered connected touring proposals leases closed lost)
|
4
|
+
|
5
|
+
has_many :inquiries
|
6
|
+
has_many :tim_alerts
|
7
|
+
|
8
|
+
def regions
|
9
|
+
Region.where(id: region_ids)
|
10
|
+
end
|
11
|
+
|
12
|
+
def term_units(value=nil)
|
13
|
+
value ||= self.term
|
14
|
+
case value
|
15
|
+
when "<1"
|
16
|
+
"year"
|
17
|
+
when "flexible"
|
18
|
+
""
|
19
|
+
when nil
|
20
|
+
""
|
21
|
+
else
|
22
|
+
"years"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -37,6 +37,10 @@ class Listing < MLS::Model
|
|
37
37
|
|
38
38
|
accepts_nested_attributes_for :uses, :ownerships, :image_orderings
|
39
39
|
|
40
|
+
def is_elite?
|
41
|
+
((property.elite_account_ids || []) & accounts.map(&:id)).length > 0
|
42
|
+
end
|
43
|
+
|
40
44
|
def premium_property?
|
41
45
|
Subscription.filter(started_at: true, ends_at: false, type: "premium", subject_type: "Property", subject_id: self.property_id).count > 0
|
42
46
|
end
|
@@ -49,11 +53,11 @@ class Listing < MLS::Model
|
|
49
53
|
end
|
50
54
|
end
|
51
55
|
|
52
|
-
def
|
56
|
+
def lead_contacts
|
53
57
|
if ownerships.loaded?
|
54
|
-
@
|
58
|
+
@lead_contacts ||= ownerships.select{|o| o.lead}.map(&:account)
|
55
59
|
else
|
56
|
-
@
|
60
|
+
@lead_contacts ||= ownerships.eager_load(:account).filter(:lead => true).map(&:account)
|
57
61
|
end
|
58
62
|
end
|
59
63
|
|
@@ -147,7 +151,7 @@ class Listing < MLS::Model
|
|
147
151
|
def name
|
148
152
|
return "New Listing" if !self.id
|
149
153
|
name = ""
|
150
|
-
if self.
|
154
|
+
if self.unit_type == "building"
|
151
155
|
name += "Entire Building"
|
152
156
|
else
|
153
157
|
name = "Unit #{self.unit}" if self.unit.present?
|
@@ -158,4 +162,16 @@ class Listing < MLS::Model
|
|
158
162
|
name = "Space" if name.blank?
|
159
163
|
name
|
160
164
|
end
|
165
|
+
|
166
|
+
def status
|
167
|
+
if self.leased_at
|
168
|
+
"Leased"
|
169
|
+
elsif self.archived
|
170
|
+
"Deleted"
|
171
|
+
elsif self.touched_at < 90.days.ago
|
172
|
+
"Expired"
|
173
|
+
else
|
174
|
+
"Active"
|
175
|
+
end
|
176
|
+
end
|
161
177
|
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -19,7 +19,7 @@ class Property < MLS::Model
|
|
19
19
|
has_many :image_orderings, as: :subject
|
20
20
|
has_many :data, as: :subject
|
21
21
|
has_many :photos, through: :image_orderings, source: :image
|
22
|
-
has_many :
|
22
|
+
has_many :services, as: :subject
|
23
23
|
|
24
24
|
has_many :uses
|
25
25
|
# has_and_belongs_to_many :uses
|
@@ -48,6 +48,12 @@ class Property < MLS::Model
|
|
48
48
|
def latitude
|
49
49
|
location.y
|
50
50
|
end
|
51
|
+
|
52
|
+
def is_elite_for_account_ids?(*account_ids)
|
53
|
+
return false unless self.elite_account_ids && self.elite_account_ids.length > 0
|
54
|
+
account_ids = Array(account_ids).flatten
|
55
|
+
(self.elite_account_ids & account_ids).length > 0
|
56
|
+
end
|
51
57
|
|
52
58
|
def display_description
|
53
59
|
return description if description.present?
|
@@ -122,6 +128,7 @@ class Property < MLS::Model
|
|
122
128
|
region = neighborhood_region
|
123
129
|
region ||= city_region
|
124
130
|
region ||= market
|
131
|
+
region ||= regions.where(depth: true).sort_by(&:depth).reverse.first
|
125
132
|
region
|
126
133
|
end
|
127
134
|
|
@@ -134,13 +141,28 @@ class Property < MLS::Model
|
|
134
141
|
|
135
142
|
def city_region
|
136
143
|
return @city_region if defined? @city_region
|
137
|
-
@city_region = fetch_region(:type =>
|
144
|
+
@city_region = fetch_region(:type => Region::CITY_TYPES)
|
145
|
+
end
|
146
|
+
|
147
|
+
def state_region
|
148
|
+
return @state_region if defined? @state_region
|
149
|
+
@state_region = fetch_region(:type => Region::STATE_TYPES)
|
138
150
|
end
|
139
151
|
|
140
152
|
def market
|
141
153
|
return @market if defined? @market
|
142
154
|
@market = fetch_region(:is_market => true)
|
143
155
|
end
|
156
|
+
|
157
|
+
def human_breadcrumbs
|
158
|
+
[
|
159
|
+
neighborhood.present? ? neighborhood : neighborhood_region&.name,
|
160
|
+
city.present? ? city : (city_region&.name || regions.select{|r|
|
161
|
+
r.depth && r.depth >= 3
|
162
|
+
}.first&.name),
|
163
|
+
state.present? ? state : state_region&.slug&.split("/")&.last&.upcase
|
164
|
+
].compact
|
165
|
+
end
|
144
166
|
|
145
167
|
def flagship
|
146
168
|
return @flagship if defined? @flagship
|
@@ -152,7 +174,13 @@ class Property < MLS::Model
|
|
152
174
|
if params[0][0] == :query
|
153
175
|
regions.to_a.find{|r| r.name == params[0][1]}
|
154
176
|
else
|
155
|
-
regions.to_a.find{|r|
|
177
|
+
regions.to_a.find{|r|
|
178
|
+
if params[0][1].is_a? Array
|
179
|
+
params[0][1].include? (r[params[0][0]])
|
180
|
+
else
|
181
|
+
r[params[0][0]] == params[0][1]
|
182
|
+
end
|
183
|
+
}
|
156
184
|
end
|
157
185
|
end
|
158
186
|
end
|
File without changes
|
File without changes
|
@@ -4,6 +4,8 @@ class Region < MLS::Model
|
|
4
4
|
|
5
5
|
self.inheritance_column = nil
|
6
6
|
|
7
|
+
COUNTRY_TYPES = ["Monarchy", "Republic"]
|
8
|
+
STATE_TYPES = ["State", "Territory", "Commonwealth", "Province"]
|
7
9
|
CITY_TYPES = ["City", "Municipality", "Village", "Rural Municipality", "Town", "Resort Village", "Community Government"]
|
8
10
|
|
9
11
|
belongs_to :cover_photo, :class_name => 'Image'
|
@@ -20,8 +22,12 @@ class Region < MLS::Model
|
|
20
22
|
def name
|
21
23
|
if common_name.try(:[], 'eng')
|
22
24
|
common_name['eng'].is_a?(Array) ? common_name['eng'].first : common_name['eng']
|
23
|
-
|
25
|
+
elsif official_name.try(:[], 'eng')
|
24
26
|
official_name['eng'].is_a?(Array) ? official_name['eng'].first : official_name['eng']
|
27
|
+
elsif common_name && common_name.size > 0
|
28
|
+
common_name.values.first
|
29
|
+
else
|
30
|
+
official_name.values.first
|
25
31
|
end
|
26
32
|
end
|
27
33
|
|
@@ -53,4 +59,4 @@ class Region < MLS::Model
|
|
53
59
|
result
|
54
60
|
end
|
55
61
|
|
56
|
-
end
|
62
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
class Search < MLS::Model
|
2
|
+
|
3
|
+
STATUS_OPTIONS = %w(active hold cold closed)
|
4
|
+
STAGE_OPTIONS = %w(initiated contacted delivered connected toured loi signed coworking)
|
5
|
+
BUDGET_UNITS = %w(per_month per_year per_sqft_per_year)
|
6
|
+
TERMS = %w(<1 1-2 3-5 5+ flexible)
|
7
|
+
MOVE_INS = %w(<3 3-6 6-12 12+ flexible)
|
8
|
+
|
9
|
+
belongs_to :account
|
10
|
+
belongs_to :broker, class_name: "Account"
|
11
|
+
belongs_to :manager, class_name: "Account"
|
12
|
+
belongs_to :lead
|
13
|
+
|
14
|
+
has_many :suggestions
|
15
|
+
has_many :email_digests
|
16
|
+
has_many :tasks, :as => :subject
|
17
|
+
|
18
|
+
accepts_nested_attributes_for :account
|
19
|
+
|
20
|
+
def name
|
21
|
+
read_attribute(:name) || account&.company || account&.name
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_json(options={})
|
25
|
+
output = super(options)
|
26
|
+
output = JSON.parse(super)
|
27
|
+
output["filter"] = read_attribute(:filter)
|
28
|
+
output.to_json
|
29
|
+
end
|
30
|
+
|
31
|
+
def filter
|
32
|
+
JSON.parse (read_attribute(:filter) || {}).to_json, object_class: OpenStruct
|
33
|
+
end
|
34
|
+
|
35
|
+
def regions
|
36
|
+
Region.where(id: self.region_ids)
|
37
|
+
end
|
38
|
+
|
39
|
+
def move_in_units(value=nil)
|
40
|
+
value ||= self.move_in
|
41
|
+
case value
|
42
|
+
when "<1"
|
43
|
+
"month"
|
44
|
+
when "flexible"
|
45
|
+
""
|
46
|
+
else
|
47
|
+
"months"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def term_units(value=nil)
|
52
|
+
value ||= self.term
|
53
|
+
case value
|
54
|
+
when "<1"
|
55
|
+
"year"
|
56
|
+
when "flexible"
|
57
|
+
""
|
58
|
+
else
|
59
|
+
"years"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Site < MLS::Model
|
2
|
+
|
3
|
+
belongs_to :region
|
4
|
+
belongs_to :cover_photo, :class_name => 'Image'
|
5
|
+
belongs_to :logo, :class_name => 'Image'
|
6
|
+
|
7
|
+
has_many :ownerships, as: :asset
|
8
|
+
has_many :accounts, through: :ownerships, source: :account, inverse_of: :sites
|
9
|
+
has_many :services, as: :subject
|
10
|
+
|
11
|
+
def contacts
|
12
|
+
if ownerships.loaded?
|
13
|
+
@contacts ||= ownerships.select{|o| o.receives_inquiries }.map(&:account)
|
14
|
+
else
|
15
|
+
@contacts ||= ownerships.eager_load(:account).filter(:receives_inquiries => true).map(&:account)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def lead_contacts
|
20
|
+
if ownerships.loaded?
|
21
|
+
@lead_contacts ||= ownerships.select{|o| o.lead}.map(&:account)
|
22
|
+
else
|
23
|
+
@lead_contacts ||= ownerships.eager_load(:account).filter(:lead => true).map(&:account)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Subscription < MLS::Model
|
2
|
+
self.inheritance_column = nil
|
3
|
+
|
4
|
+
has_and_belongs_to_many :accounts
|
5
|
+
has_many :invoices
|
6
|
+
has_many :services
|
7
|
+
belongs_to :organization
|
8
|
+
belongs_to :billing_contact, class_name: "Account"
|
9
|
+
belongs_to :credit_card
|
10
|
+
|
11
|
+
has_and_belongs_to_many :invoice_recipients, class_name: 'EmailAddress'
|
12
|
+
|
13
|
+
accepts_nested_attributes_for :services
|
14
|
+
|
15
|
+
def cost
|
16
|
+
read_attribute(:cost) / 100.0 if read_attribute(:cost)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'rack'
|
2
|
+
require 'rack/builder'
|
3
|
+
|
4
|
+
module MLS
|
5
|
+
module Rack
|
6
|
+
class Proxy
|
7
|
+
|
8
|
+
def self.new
|
9
|
+
app = super
|
10
|
+
::Rack::Builder.new do
|
11
|
+
use(ActionDispatch::Cookies)
|
12
|
+
use(ActionDispatch::Session::CookieStore, {
|
13
|
+
key: Rails.application.config.session_options[:key],
|
14
|
+
path: '/',
|
15
|
+
secret: Rails.application.secrets[:secret_key_base]
|
16
|
+
})
|
17
|
+
run app
|
18
|
+
end.to_app
|
19
|
+
end
|
20
|
+
|
21
|
+
def extract_http_request_headers(env)
|
22
|
+
headers = env.reject do |k, v|
|
23
|
+
!(/^HTTP_[A-Z_]+$/ === k) || v.nil?
|
24
|
+
end.map do |k, v|
|
25
|
+
[k.sub(/^HTTP_/, "").gsub("_", "-"), v]
|
26
|
+
end.inject({}) do |hash, k_v|
|
27
|
+
k, v = k_v
|
28
|
+
hash[k] = v
|
29
|
+
hash
|
30
|
+
end
|
31
|
+
|
32
|
+
headers.delete_if {|key, value| ["HOST", "API-VERSION", "CONNECTION", "VERSION"].include?(key) }
|
33
|
+
x_forwarded_for = (headers["X-Forwarded-For"].to_s.split(/, +/) << env["REMOTE_ADDR"]).join(", ")
|
34
|
+
|
35
|
+
headers.merge!("X-Forwarded-For" => x_forwarded_for)
|
36
|
+
end
|
37
|
+
|
38
|
+
def call(env)
|
39
|
+
request = Net::HTTP.const_get(env['REQUEST_METHOD'].capitalize).new(env['PATH_INFO'] + '?' + env['QUERY_STRING'])
|
40
|
+
request.initialize_http_header(extract_http_request_headers(env))
|
41
|
+
|
42
|
+
if request.request_body_permitted?
|
43
|
+
if env['TRANSFER-ENCODING'] == 'chunked'
|
44
|
+
request.body_stream = env['rack.input']
|
45
|
+
elsif env['CONTENT_LENGTH']
|
46
|
+
request.body = env['rack.input'].read
|
47
|
+
end
|
48
|
+
end
|
49
|
+
request['Content-Type'] = env['CONTENT_TYPE']
|
50
|
+
|
51
|
+
response = MLS::Model.connection_pool.with_connection do |conn|
|
52
|
+
with_cookie_store(env) do
|
53
|
+
request_uri = "http#{conn.instance_variable_get(:@connection).use_ssl ? 's' : ''}://#{conn.instance_variable_get(:@connection).host}#{conn.instance_variable_get(:@connection).port != 80 ? (conn.instance_variable_get(:@connection).port == 443 && conn.instance_variable_get(:@connection).use_ssl ? '' : ":#{conn.instance_variable_get(:@connection).port}") : ''}#{request.path}"
|
54
|
+
request['Cookie'] = Thread.current[:sunstone_cookie_store].cookie_header_for(request_uri)
|
55
|
+
conn.instance_variable_get(:@connection).send(:request_headers).each { |k, v| request[k] = v if ['Api-Version', 'Api-Key'].include?(k) }
|
56
|
+
|
57
|
+
conn.instance_variable_get(:@connection).instance_variable_get(:@connection).request(request)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
response_headers = {}
|
61
|
+
response.each_header { |k, v| response_headers[k] = v unless k == 'transfer-encoding' }
|
62
|
+
|
63
|
+
[response.code, response_headers, [response.body]]
|
64
|
+
end
|
65
|
+
|
66
|
+
def with_cookie_store(env)
|
67
|
+
store = CookieStore::HashStore.new
|
68
|
+
store.add_from_json(env['rack.session']['cookie_store']) if env['rack.session']['cookie_store']
|
69
|
+
Thread.current[:sunstone_cookie_store] = store
|
70
|
+
result = yield
|
71
|
+
Thread.current[:sunstone_cookie_store] = nil
|
72
|
+
env['rack.session']['cookie_store'] = store.to_json
|
73
|
+
result
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/mls/railtie.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# See notes from 'active_record/railtie'
|
2
|
+
require "action_controller/railtie"
|
3
|
+
|
4
|
+
class MLS::Railtie < Rails::Railtie
|
5
|
+
|
6
|
+
config.mls = ActiveSupport::OrderedOptions.new
|
7
|
+
|
8
|
+
config.action_dispatch.rescue_responses.merge!(
|
9
|
+
"Sunstone::Exception::NotFound" => :not_found,
|
10
|
+
"Sunstone::Exception::Unauthorized" => :unauthorized,
|
11
|
+
"Sunstone::Exception::Gone" => :gone
|
12
|
+
)
|
13
|
+
|
14
|
+
initializer 'mls' do |app|
|
15
|
+
|
16
|
+
url = app.config.mls.fetch('url') { app.secrets.mls }
|
17
|
+
user_agent = []
|
18
|
+
user_agent << app.config.mls.fetch('user_agent') {
|
19
|
+
app.class.name.split('::')[0..-2].join('::')
|
20
|
+
}
|
21
|
+
user_agent << "Rails/#{Rails.version}"
|
22
|
+
|
23
|
+
|
24
|
+
MLS::Model.establish_connection({
|
25
|
+
adapter: 'sunstone',
|
26
|
+
url: url,
|
27
|
+
user_agent: user_agent.compact.join(' ')
|
28
|
+
})
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/mls.gemspec
CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "mls"
|
6
|
-
s.version = '1.
|
6
|
+
s.version = '1.6.0'
|
7
7
|
s.authors = ["Jon Bracy", "James R. Bracy"]
|
8
8
|
s.email = ["jon@42floors.com", "james@42floors.com"]
|
9
9
|
s.homepage = "http://mls.42floors.com"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mls
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Bracy
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2018-01-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -239,7 +239,8 @@ description: Ruby library for integrating with the 42Floors MLS
|
|
239
239
|
email:
|
240
240
|
- jon@42floors.com
|
241
241
|
- james@42floors.com
|
242
|
-
executables:
|
242
|
+
executables:
|
243
|
+
- mls
|
243
244
|
extensions: []
|
244
245
|
extra_rdoc_files: []
|
245
246
|
files:
|
@@ -247,53 +248,64 @@ files:
|
|
247
248
|
- Gemfile
|
248
249
|
- README.rdoc
|
249
250
|
- Rakefile
|
251
|
+
- bin/mls
|
250
252
|
- lib/mls.rb
|
251
|
-
- lib/mls/
|
252
|
-
- lib/mls/
|
253
|
-
- lib/mls/
|
254
|
-
- lib/mls/
|
255
|
-
- lib/mls/api_key.rb
|
253
|
+
- lib/mls/cli.rb
|
254
|
+
- lib/mls/cli/documents.rb
|
255
|
+
- lib/mls/cli/storage.rb
|
256
|
+
- lib/mls/cli/storage/s3.rb
|
256
257
|
- lib/mls/comment.rb
|
257
|
-
- lib/mls/
|
258
|
-
- lib/mls/
|
259
|
-
- lib/mls/
|
260
|
-
- lib/mls/
|
261
|
-
- lib/mls/
|
262
|
-
- lib/mls/
|
263
|
-
- lib/mls/
|
264
|
-
- lib/mls/
|
265
|
-
- lib/mls/
|
266
|
-
- lib/mls/
|
267
|
-
- lib/mls/
|
268
|
-
- lib/mls/
|
269
|
-
- lib/mls/
|
270
|
-
- lib/mls/
|
271
|
-
- lib/mls/
|
272
|
-
- lib/mls/
|
273
|
-
- lib/mls/
|
274
|
-
- lib/mls/
|
275
|
-
- lib/mls/
|
276
|
-
- lib/mls/
|
277
|
-
- lib/mls/
|
278
|
-
- lib/mls/
|
279
|
-
- lib/mls/
|
280
|
-
- lib/mls/
|
281
|
-
- lib/mls/
|
282
|
-
- lib/mls/
|
283
|
-
- lib/mls/
|
284
|
-
- lib/mls/
|
285
|
-
- lib/mls/
|
286
|
-
- lib/mls/
|
287
|
-
- lib/mls/
|
288
|
-
- lib/mls/
|
289
|
-
- lib/mls/
|
290
|
-
- lib/mls/
|
291
|
-
- lib/mls/
|
292
|
-
- lib/mls/
|
293
|
-
- lib/mls/
|
294
|
-
- lib/mls/
|
295
|
-
- lib/mls/
|
296
|
-
- lib/mls/
|
258
|
+
- lib/mls/models/account.rb
|
259
|
+
- lib/mls/models/accounts_region.rb
|
260
|
+
- lib/mls/models/action.rb
|
261
|
+
- lib/mls/models/address.rb
|
262
|
+
- lib/mls/models/api_key.rb
|
263
|
+
- lib/mls/models/coworking_space.rb
|
264
|
+
- lib/mls/models/credit_card.rb
|
265
|
+
- lib/mls/models/datum.rb
|
266
|
+
- lib/mls/models/document.rb
|
267
|
+
- lib/mls/models/email.rb
|
268
|
+
- lib/mls/models/email_address.rb
|
269
|
+
- lib/mls/models/email_digest.rb
|
270
|
+
- lib/mls/models/event.rb
|
271
|
+
- lib/mls/models/flyer.rb
|
272
|
+
- lib/mls/models/geometry.rb
|
273
|
+
- lib/mls/models/image_ordering.rb
|
274
|
+
- lib/mls/models/impression_count.rb
|
275
|
+
- lib/mls/models/inquiry.rb
|
276
|
+
- lib/mls/models/invoice.rb
|
277
|
+
- lib/mls/models/lead.rb
|
278
|
+
- lib/mls/models/listing.rb
|
279
|
+
- lib/mls/models/locality.rb
|
280
|
+
- lib/mls/models/metadatum.rb
|
281
|
+
- lib/mls/models/mistake.rb
|
282
|
+
- lib/mls/models/organization.rb
|
283
|
+
- lib/mls/models/ownership.rb
|
284
|
+
- lib/mls/models/phone.rb
|
285
|
+
- lib/mls/models/property.rb
|
286
|
+
- lib/mls/models/recommendation.rb
|
287
|
+
- lib/mls/models/reference.rb
|
288
|
+
- lib/mls/models/region.rb
|
289
|
+
- lib/mls/models/search.rb
|
290
|
+
- lib/mls/models/service.rb
|
291
|
+
- lib/mls/models/session.rb
|
292
|
+
- lib/mls/models/site.rb
|
293
|
+
- lib/mls/models/slug.rb
|
294
|
+
- lib/mls/models/source.rb
|
295
|
+
- lib/mls/models/space.rb
|
296
|
+
- lib/mls/models/stat.rb
|
297
|
+
- lib/mls/models/subscription.rb
|
298
|
+
- lib/mls/models/suggestion.rb
|
299
|
+
- lib/mls/models/task.rb
|
300
|
+
- lib/mls/models/team.rb
|
301
|
+
- lib/mls/models/tim_alert.rb
|
302
|
+
- lib/mls/models/time_log.rb
|
303
|
+
- lib/mls/models/use.rb
|
304
|
+
- lib/mls/models/vendor.rb
|
305
|
+
- lib/mls/models/view.rb
|
306
|
+
- lib/mls/models/webpage.rb
|
307
|
+
- lib/mls/rack/proxy.rb
|
308
|
+
- lib/mls/railtie.rb
|
297
309
|
- mls.gemspec
|
298
310
|
- test/fixtures/flyer.pdf
|
299
311
|
- test/mls/attribute_test.rb
|
@@ -319,7 +331,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
319
331
|
version: '0'
|
320
332
|
requirements: []
|
321
333
|
rubyforge_project: mls
|
322
|
-
rubygems_version: 2.
|
334
|
+
rubygems_version: 2.6.11
|
323
335
|
signing_key:
|
324
336
|
specification_version: 4
|
325
337
|
summary: 42Floors MLS Client
|
data/lib/mls/action.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
class Action < MLS::Model
|
2
|
-
self.inheritance_column = nil
|
3
|
-
|
4
|
-
belongs_to :event
|
5
|
-
belongs_to :subject, :polymorphic => true
|
6
|
-
|
7
|
-
has_many :mistakes
|
8
|
-
has_many :metadata, foreign_key: :event_id, primary_key: :event_id
|
9
|
-
|
10
|
-
def self.by_performer(filter)
|
11
|
-
req = Net::HTTP::Get.new("/actions/by_performer")
|
12
|
-
req.body = {
|
13
|
-
where: filter
|
14
|
-
}.to_json
|
15
|
-
JSON.parse(connection.instance_variable_get(:@connection).send_request(req).body)
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|
data/lib/mls/email_digest.rb
DELETED
data/lib/mls/lead.rb
DELETED
data/lib/mls/membership.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
class Membership < MLS::Model
|
2
|
-
self.inheritance_column = nil
|
3
|
-
|
4
|
-
has_many :accounts
|
5
|
-
has_many :invoices
|
6
|
-
has_many :subscriptions
|
7
|
-
belongs_to :organization
|
8
|
-
belongs_to :billing_contact, class_name: "Account"
|
9
|
-
belongs_to :credit_card
|
10
|
-
belongs_to :sourced_by, class_name: "Account"
|
11
|
-
has_and_belongs_to_many :invoice_recipients, class_name: 'EmailAddress'
|
12
|
-
|
13
|
-
accepts_nested_attributes_for :subscriptions
|
14
|
-
|
15
|
-
def rate
|
16
|
-
subscriptions.select{|x| !x.ends_at}.map(&:cost).compact.sum
|
17
|
-
end
|
18
|
-
|
19
|
-
def costs
|
20
|
-
(read_attribute(:costs) || {}).with_indifferent_access
|
21
|
-
end
|
22
|
-
|
23
|
-
def value
|
24
|
-
read_attribute(:value) / 100.0 if read_attribute(:value)
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
data/lib/mls/subscription.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
class Subscription < MLS::Model
|
2
|
-
self.inheritance_column = nil
|
3
|
-
|
4
|
-
belongs_to :membership
|
5
|
-
belongs_to :subject, polymorphic: true
|
6
|
-
belongs_to :credit_card
|
7
|
-
|
8
|
-
def name
|
9
|
-
case self.type
|
10
|
-
when "unlimited"
|
11
|
-
"Unlimited Premium Listings"
|
12
|
-
when "premium"
|
13
|
-
"Premium Listings"
|
14
|
-
when "elite"
|
15
|
-
"Elite Account"
|
16
|
-
when "coworking"
|
17
|
-
"Coworking Space"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def cost
|
22
|
-
read_attribute(:cost) / 100.0 if read_attribute(:cost)
|
23
|
-
end
|
24
|
-
end
|