caboose-rets 0.1.183 → 0.1.184
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/caboose_rets/saved_properties_controller.rb +2 -1
- data/app/mailers/caboose_rets/rets_mailer.rb +72 -0
- data/app/models/caboose_rets/notification.rb +206 -0
- data/app/models/caboose_rets/property.rb +15 -0
- data/app/models/caboose_rets/rets_importer.rb +19 -183
- data/app/models/caboose_rets/schema.rb +12 -0
- data/app/views/caboose_rets/rets_mailer/_property_row.html.erb +31 -0
- data/app/views/caboose_rets/rets_mailer/daily_report.html.erb +76 -0
- data/app/views/caboose_rets/rets_mailer/property_price_change.html.erb +69 -0
- data/app/views/caboose_rets/rets_mailer/property_status_change.html.erb +69 -0
- data/app/views/caboose_rets/rets_mailer/user_welcome.html.erb +2 -2
- data/app/views/caboose_rets/saved_properties/rets_info.html.erb +39 -3
- data/lib/caboose_rets/version.rb +1 -1
- data/lib/tasks/caboose_rets.rake +9 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84ef101eafb83b5891a32f9557f355e5f46de43e3d1e544aad19e5a533e78b6e
|
4
|
+
data.tar.gz: 1ddefc2dbff138dcb82eb3e4c879f9b19956726d2dd20ca134ec7106a45ce99e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 754a940a4a13708921c8e4b7bd05c311f04f14b448ac8cb6d6938c752f3f20960a7954465fa84530b3a9b0c8bc6b3cde2394414a6aa07981e5029e5b66aa5ce7
|
7
|
+
data.tar.gz: 80eace42b684e7bb8a25b4c7e88263c596fd1cdb2bd41e6fe709b260ec8401675c6fad0c26e56fc341eb247a103d30f69c3550d20a969b097a19df7b7bcd5605
|
@@ -11,7 +11,8 @@ module CabooseRets
|
|
11
11
|
# GET /admin/users/:id/mls
|
12
12
|
def rets_info
|
13
13
|
@edituser = Caboose::User.where(:id => params[:id], :site_id => @site.id).first
|
14
|
-
@saved = SavedProperty.where(:user_id => @edituser.id).order('date_saved desc').
|
14
|
+
@saved = SavedProperty.where(:user_id => @edituser.id).order('date_saved desc').limit(100)
|
15
|
+
@emails = Notification.where(:user_id => @edituser.id).order('date_sent desc').limit(100)
|
15
16
|
render :layout => 'caboose/admin'
|
16
17
|
end
|
17
18
|
|
@@ -56,4 +56,76 @@ class CabooseRets::RetsMailer < ActionMailer::Base
|
|
56
56
|
)
|
57
57
|
end
|
58
58
|
|
59
|
+
def daily_report(user, new_listings, related_listings)
|
60
|
+
@user = user
|
61
|
+
@new_listings = new_listings
|
62
|
+
@related_listings = related_listings
|
63
|
+
@site = user.site
|
64
|
+
to_address = user.email
|
65
|
+
reply_to = @site.contact_email.blank? ? 'noreply@caboosecms.com' : @site.contact_email
|
66
|
+
@color = @site.theme ? @site.theme.color_main : @site.theme_color
|
67
|
+
@domain = "https://#{@site.primary_domain.domain}"
|
68
|
+
@domain = "http://dev.pmre.com:3000" if Rails.env.development?
|
69
|
+
@url = @domain
|
70
|
+
@url += "/real-estate" if @site.id == 541
|
71
|
+
@logo_url = @site.logo.url(:large)
|
72
|
+
subject = @site.id == 541 ? "New and Suggested Listings from Pritchett-Moore Real Estate" : "New and Suggested Listings from #{@site.description}"
|
73
|
+
@logo_url = "https:#{@logo_url}" if !@logo_url.include?('http')
|
74
|
+
@unsubscribe_url = "https://#{@site.primary_domain.domain}/rets-unsubscribe?token=7b8v9j#{@user.id}9b6h0c2n"
|
75
|
+
mail(
|
76
|
+
:to => to_address,
|
77
|
+
:from => from_address(@site.id, nil),
|
78
|
+
:subject => subject,
|
79
|
+
:reply_to => reply_to
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
def property_status_change(user, property, old_status)
|
84
|
+
@user = user
|
85
|
+
@property = property
|
86
|
+
@old_status = old_status
|
87
|
+
@site = user.site
|
88
|
+
to_address = user.email
|
89
|
+
reply_to = @site.contact_email.blank? ? 'noreply@caboosecms.com' : @site.contact_email
|
90
|
+
@color = @site.theme ? @site.theme.color_main : @site.theme_color
|
91
|
+
@domain = "https://#{@site.primary_domain.domain}"
|
92
|
+
@domain = "http://dev.pmre.com:3000" if Rails.env.development?
|
93
|
+
@url = @domain
|
94
|
+
@url += "/real-estate" if @site.id == 541
|
95
|
+
@logo_url = @site.logo.url(:large)
|
96
|
+
subject = "Status Change for Listing MLS ##{@property.mls_number}"
|
97
|
+
@logo_url = "https:#{@logo_url}" if !@logo_url.include?('http')
|
98
|
+
@unsubscribe_url = "https://#{@site.primary_domain.domain}/rets-unsubscribe?token=7b8v9j#{@user.id}9b6h0c2n"
|
99
|
+
mail(
|
100
|
+
:to => to_address,
|
101
|
+
:from => from_address(@site.id, nil),
|
102
|
+
:subject => subject,
|
103
|
+
:reply_to => reply_to
|
104
|
+
)
|
105
|
+
end
|
106
|
+
|
107
|
+
def property_price_change(user, property, old_price)
|
108
|
+
@user = user
|
109
|
+
@property = property
|
110
|
+
@old_price = old_price
|
111
|
+
@site = user.site
|
112
|
+
to_address = user.email
|
113
|
+
reply_to = @site.contact_email.blank? ? 'noreply@caboosecms.com' : @site.contact_email
|
114
|
+
@color = @site.theme ? @site.theme.color_main : @site.theme_color
|
115
|
+
@domain = "https://#{@site.primary_domain.domain}"
|
116
|
+
@domain = "http://dev.pmre.com:3000" if Rails.env.development?
|
117
|
+
@url = @domain
|
118
|
+
@url += "/real-estate" if @site.id == 541
|
119
|
+
@logo_url = @site.logo.url(:large)
|
120
|
+
subject = "Price Change for Listing MLS ##{@property.mls_number}"
|
121
|
+
@logo_url = "https:#{@logo_url}" if !@logo_url.include?('http')
|
122
|
+
@unsubscribe_url = "https://#{@site.primary_domain.domain}/rets-unsubscribe?token=7b8v9j#{@user.id}9b6h0c2n"
|
123
|
+
mail(
|
124
|
+
:to => to_address,
|
125
|
+
:from => from_address(@site.id, nil),
|
126
|
+
:subject => subject,
|
127
|
+
:reply_to => reply_to
|
128
|
+
)
|
129
|
+
end
|
130
|
+
|
59
131
|
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
class CabooseRets::Notification < ActiveRecord::Base
|
2
|
+
|
3
|
+
self.table_name = "rets_notifications"
|
4
|
+
|
5
|
+
belongs_to :user, :class_name => "Caboose::User"
|
6
|
+
belongs_to :site, :class_name => "Caboose::Site"
|
7
|
+
|
8
|
+
def self.property_status_changed(property, old_status)
|
9
|
+
return if property.nil?
|
10
|
+
|
11
|
+
us = Caboose::Setting.where(:site_id => 541, :name => "test_usernames").first
|
12
|
+
allowed_users = us ? us.value : ""
|
13
|
+
allowed_users = 'billyswifty' if Rails.env.development?
|
14
|
+
uwhere = allowed_users.blank? ? "" : "('#{allowed_users}' ILIKE '%' || username || '%')"
|
15
|
+
|
16
|
+
user_ids = CabooseRets::SavedProperty.where(:mls_number => property.mls_number).pluck(:user_id)
|
17
|
+
if user_ids.count > 0
|
18
|
+
user_ids.each do |user_id|
|
19
|
+
user = Caboose::User.where(uwhere).where(:id => user_id, :tax_exempt => false).first
|
20
|
+
d1 = DateTime.now - 24.hours
|
21
|
+
if user
|
22
|
+
# Check if a similar notification has already been sent
|
23
|
+
n = CabooseRets::Notification.where(
|
24
|
+
:user_id => user.id,
|
25
|
+
:site_id => user.site_id,
|
26
|
+
:kind => "Property Status Changed",
|
27
|
+
:sent_to => user.email,
|
28
|
+
:object_kind => "Property",
|
29
|
+
:object_id => property.mls_number,
|
30
|
+
:old_value => old_status,
|
31
|
+
:new_value => property.status
|
32
|
+
).where("date_sent >= ?", d1).first
|
33
|
+
if n.nil?
|
34
|
+
n = CabooseRets::Notification.create(
|
35
|
+
:user_id => user.id,
|
36
|
+
:site_id => user.site_id,
|
37
|
+
:date_sent => DateTime.now,
|
38
|
+
:kind => "Property Status Changed",
|
39
|
+
:sent_to => user.email,
|
40
|
+
:object_kind => "Property",
|
41
|
+
:object_id => property.mls_number,
|
42
|
+
:old_value => old_status,
|
43
|
+
:new_value => property.status
|
44
|
+
)
|
45
|
+
CabooseRets::RetsMailer.configure_for_site(user.site_id).property_status_change(user, property, old_status).deliver_later
|
46
|
+
else
|
47
|
+
puts "Found a duplicate notification, not sending..."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.property_price_changed(property, old_price)
|
55
|
+
return if property.nil? || property.status != 'Active'
|
56
|
+
|
57
|
+
us = Caboose::Setting.where(:site_id => 541, :name => "test_usernames").first
|
58
|
+
allowed_users = us ? us.value : ""
|
59
|
+
allowed_users = 'billyswifty' if Rails.env.development?
|
60
|
+
uwhere = allowed_users.blank? ? "" : "('#{allowed_users}' ILIKE '%' || username || '%')"
|
61
|
+
|
62
|
+
user_ids = CabooseRets::SavedProperty.where(:mls_number => property.mls_number).pluck(:user_id)
|
63
|
+
if user_ids.count > 0
|
64
|
+
user_ids.each do |user_id|
|
65
|
+
user = Caboose::User.where(uwhere).where(:id => user_id, :tax_exempt => false).first
|
66
|
+
d1 = DateTime.now - 24.hours
|
67
|
+
if user
|
68
|
+
# Check if a similar notification has already been sent
|
69
|
+
n = CabooseRets::Notification.where(
|
70
|
+
:user_id => user.id,
|
71
|
+
:site_id => user.site_id,
|
72
|
+
:kind => "Property Price Changed",
|
73
|
+
:sent_to => user.email,
|
74
|
+
:object_kind => "Property",
|
75
|
+
:object_id => property.mls_number,
|
76
|
+
:old_value => old_price,
|
77
|
+
:new_value => property.list_price
|
78
|
+
).where("date_sent >= ?", d1).first
|
79
|
+
if n.nil?
|
80
|
+
n = CabooseRets::Notification.create(
|
81
|
+
:user_id => user.id,
|
82
|
+
:site_id => user.site_id,
|
83
|
+
:date_sent => DateTime.now,
|
84
|
+
:kind => "Property Price Changed",
|
85
|
+
:sent_to => user.email,
|
86
|
+
:object_kind => "Property",
|
87
|
+
:object_id => property.mls_number,
|
88
|
+
:old_value => old_price,
|
89
|
+
:new_value => property.list_price
|
90
|
+
)
|
91
|
+
CabooseRets::RetsMailer.configure_for_site(user.site_id).property_price_change(user, property, old_price).deliver_later
|
92
|
+
else
|
93
|
+
puts "Found a duplicate notification, not sending..."
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.send_new_suggested_emails
|
101
|
+
roles = Caboose::Role.where(:name => "RETS Visitor").order(:id).all
|
102
|
+
if roles.count > 0
|
103
|
+
role_ids = roles.map{|r| r.id}
|
104
|
+
|
105
|
+
us = Caboose::Setting.where(:site_id => 541, :name => "test_usernames").first
|
106
|
+
allowed_users = us ? us.value : ""
|
107
|
+
allowed_users = 'billyswifty' if Rails.env.development?
|
108
|
+
uwhere = allowed_users.blank? ? "" : "('#{allowed_users}' ILIKE '%' || username || '%')"
|
109
|
+
|
110
|
+
users = Caboose::User.joins(:role_memberships).where(uwhere).where("role_memberships.role_id in (?)", role_ids).where(:tax_exempt => false).order(:id).all
|
111
|
+
|
112
|
+
if users.count > 0
|
113
|
+
|
114
|
+
new_listings = CabooseRets::Property.where(:status => 'Active', :property_type => 'Residential').order('original_entry_timestamp desc').take(3)
|
115
|
+
|
116
|
+
users.each do |user|
|
117
|
+
|
118
|
+
puts "Gathering data for user: #{user.username}" if Rails.env.development?
|
119
|
+
|
120
|
+
saved_mls = CabooseRets::SavedProperty.where(:user_id => user.id).pluck(:mls_number)
|
121
|
+
saved_properties = saved_mls && saved_mls.count > 0 ? CabooseRets::Property.where(:status => 'Active', :property_type => 'Residential').where(:mls_number => saved_mls).limit(100) : []
|
122
|
+
|
123
|
+
if saved_properties.count > 0
|
124
|
+
|
125
|
+
puts "Saved listings: #{saved_properties.count}" if Rails.env.development?
|
126
|
+
|
127
|
+
price_where = "list_price is not null and (list_price >= ? AND list_price <= ?)"
|
128
|
+
beds_where = "beds_total is not null and (beds_total >= ? AND beds_total <= ?)"
|
129
|
+
|
130
|
+
all_prices = saved_properties.map{|p| p.list_price}
|
131
|
+
price_min = all_prices.count > 0 ? (all_prices.min * 0.8) : 150000
|
132
|
+
price_max = all_prices.count > 0 ? (all_prices.max * 1.2) : 350000
|
133
|
+
|
134
|
+
puts "Price range: #{price_min} - #{price_max}" if Rails.env.development?
|
135
|
+
|
136
|
+
all_beds = saved_properties.map{|p| p.beds_total}
|
137
|
+
beds_min = all_beds.count > 0 ? (all_beds.min - 1) : 2
|
138
|
+
beds_max = all_beds.count > 0 ? (all_beds.max + 1) : 5
|
139
|
+
|
140
|
+
puts "Beds range: #{beds_min} - #{beds_max}" if Rails.env.development?
|
141
|
+
|
142
|
+
property_subtypes = []
|
143
|
+
property_areas = []
|
144
|
+
|
145
|
+
saved_properties.each do |sp|
|
146
|
+
property_subtypes << sp.property_subtype if !property_subtypes.include?(sp.property_subtype)
|
147
|
+
property_areas << sp.area if !property_areas.include?(sp.area)
|
148
|
+
end
|
149
|
+
|
150
|
+
puts "Property subtypes: #{property_subtypes}" if Rails.env.development?
|
151
|
+
puts "Property areas: #{property_areas}" if Rails.env.development?
|
152
|
+
|
153
|
+
related_listings = CabooseRets::Property.where(:property_type => 'Residential', :status => 'Active', :property_subtype => property_subtypes, :area => property_areas).where("mls_number not in (?)", saved_mls).where(price_where,price_min,price_max).where(beds_where,beds_min,beds_max).order('original_entry_timestamp desc').take(3)
|
154
|
+
|
155
|
+
else
|
156
|
+
|
157
|
+
related_listings = []
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
if new_listings.count > 0 || related_listings.count > 0
|
162
|
+
|
163
|
+
msg = ""
|
164
|
+
|
165
|
+
if new_listings.count > 0
|
166
|
+
mls1 = new_listings.map{ |l| l.mls_number }
|
167
|
+
msg += "New Listings: #{mls1.join(', ')}"
|
168
|
+
end
|
169
|
+
|
170
|
+
if related_listings.count > 0
|
171
|
+
mls2 = related_listings.map{ |l| l.mls_number }
|
172
|
+
msg += "\n" if new_listings.count > 0
|
173
|
+
msg += "Related Listings: #{mls2.join(', ')}"
|
174
|
+
end
|
175
|
+
|
176
|
+
d = DateTime.now - 7.days
|
177
|
+
n = CabooseRets::Notification.where(
|
178
|
+
:user_id => user.id,
|
179
|
+
:site_id => user.site_id,
|
180
|
+
:kind => "New and Suggested Listings",
|
181
|
+
:sent_to => user.email,
|
182
|
+
:message => msg
|
183
|
+
).where("date_sent >= ?", d).first
|
184
|
+
|
185
|
+
if n.nil?
|
186
|
+
n = CabooseRets::Notification.create(
|
187
|
+
:user_id => user.id,
|
188
|
+
:site_id => user.site_id,
|
189
|
+
:date_sent => DateTime.now,
|
190
|
+
:kind => "New and Suggested Listings",
|
191
|
+
:sent_to => user.email,
|
192
|
+
:message => msg
|
193
|
+
)
|
194
|
+
CabooseRets::RetsMailer.configure_for_site(user.site_id).daily_report(user, new_listings, related_listings).deliver_later
|
195
|
+
else
|
196
|
+
puts "Found a duplicate notification, not sending..."
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
@@ -24,10 +24,12 @@ class CabooseRets::Property <ActiveRecord::Base
|
|
24
24
|
m = Caboose::Media.where(:id => img.media_id).first
|
25
25
|
if m && m.image && m.image.url(:large)
|
26
26
|
img_url = m.image.url(:large)
|
27
|
+
img_url = "https:#{img_url}" if !img_url.include?('http')
|
27
28
|
return img_url
|
28
29
|
break
|
29
30
|
end
|
30
31
|
end
|
32
|
+
img_url = "https:#{img_url}" if !img_url.include?('http')
|
31
33
|
return img_url
|
32
34
|
end
|
33
35
|
|
@@ -55,6 +57,10 @@ class CabooseRets::Property <ActiveRecord::Base
|
|
55
57
|
end
|
56
58
|
|
57
59
|
def parse(data)
|
60
|
+
|
61
|
+
old_price = self.list_price
|
62
|
+
old_status = self.status
|
63
|
+
|
58
64
|
# puts(data.to_s)
|
59
65
|
# self.access = nil
|
60
66
|
self.acreage = data['LotSizeAcres'].blank? ? nil : data['LotSizeAcres'].to_f
|
@@ -249,5 +255,14 @@ class CabooseRets::Property <ActiveRecord::Base
|
|
249
255
|
self.zoning = data['Zoning']
|
250
256
|
# self.zoning_northport = data['ZoningNorthPort']
|
251
257
|
# self.zoning_tusc = data['ZoningTusc']
|
258
|
+
|
259
|
+
|
260
|
+
if old_status != self.status # status was changed
|
261
|
+
CabooseRets::Notification.delay(:queue => "rets").property_status_changed(self, old_status)
|
262
|
+
elsif old_price != self.list_price && self.status == 'Active' # price was changed
|
263
|
+
CabooseRets::Notification.delay(:queue => "rets").property_price_changed(self, old_price)
|
264
|
+
end
|
265
|
+
|
266
|
+
|
252
267
|
end
|
253
268
|
end
|
@@ -70,7 +70,6 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
70
70
|
:search_type => m.search_type,
|
71
71
|
:class => class_type,
|
72
72
|
:query => query,
|
73
|
-
# :limit => 3,
|
74
73
|
:timeout => -1
|
75
74
|
}
|
76
75
|
obj = nil
|
@@ -135,7 +134,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
135
134
|
|
136
135
|
statusquery = ""
|
137
136
|
case class_type
|
138
|
-
when 'Property' then statusquery = "
|
137
|
+
when 'Property' then statusquery = "OriginatingSystemName=WESTAL"
|
139
138
|
when 'Office' then statusquery = "OfficeStatus=Active"
|
140
139
|
when 'Member' then statusquery = "MemberStatus=Active"
|
141
140
|
when 'OpenHouse' then statusquery = "OpenHouseKeyNumeric=0+"
|
@@ -164,7 +163,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
164
163
|
end
|
165
164
|
|
166
165
|
# Check for changed images
|
167
|
-
if class_type == 'Property'
|
166
|
+
if class_type == 'Property' && Rails.env.production?
|
168
167
|
self.log3("Property",nil,"Checking for modified images on Properties...")
|
169
168
|
d1 = (self.last_updated - 1.hours).in_time_zone(CabooseRets::timezone).strftime("%FT%T")
|
170
169
|
params = {
|
@@ -191,17 +190,6 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
191
190
|
# Single model import methods (called from a worker dyno)
|
192
191
|
#=============================================================================
|
193
192
|
|
194
|
-
# def self.import_property(mui, save_images = true)
|
195
|
-
# self.import('Listing', "(Matrix_Unique_ID=#{mui})")
|
196
|
-
# p = CabooseRets::Property.where(:matrix_unique_id => mui.to_s).first
|
197
|
-
# if p != nil
|
198
|
-
# self.download_property_images(p)
|
199
|
-
# self.update_coords(p)
|
200
|
-
# else
|
201
|
-
# self.log("No Property associated with #{mui}")
|
202
|
-
# end
|
203
|
-
# end
|
204
|
-
|
205
193
|
def self.import_properties(mls_id, save_images = true)
|
206
194
|
si = save_images ? 'saving images' : 'not saving images'
|
207
195
|
self.log3('Property',mls_id,"Importing Property #{mls_id} and #{si}...")
|
@@ -209,12 +197,12 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
209
197
|
self.import('Property', "(ListingId=#{mls_id})")
|
210
198
|
p = CabooseRets::Property.where(:mls_number => mls_id.to_s).first
|
211
199
|
if p != nil && p.status == 'Active'
|
212
|
-
self.download_property_images(p) if save_images == true
|
200
|
+
self.download_property_images(p) if save_images == true && Rails.env.production?
|
213
201
|
if p.latitude.blank? || p.latitude == '0.0' || p.longitude.blank? || p.longitude == '0.0'
|
214
202
|
self.update_coords(p)
|
215
203
|
end
|
216
204
|
else
|
217
|
-
self.log3(nil,nil,"No Property associated with #{mls_id}")
|
205
|
+
self.log3(nil,nil,"No Active Property associated with #{mls_id}, not downloading images")
|
218
206
|
end
|
219
207
|
end
|
220
208
|
|
@@ -265,43 +253,8 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
265
253
|
# Images go here
|
266
254
|
#=============================================================================
|
267
255
|
|
268
|
-
# def self.download_property_images(p, save_images = true)
|
269
|
-
# return if save_images == false
|
270
|
-
# self.log("- Downloading GFX records for #{p.matrix_unique_id}...")
|
271
|
-
# params = {
|
272
|
-
# :search_type => 'Media',
|
273
|
-
# :class => 'Photo',
|
274
|
-
# :type => 'Photo',
|
275
|
-
# :resource => 'Property',
|
276
|
-
# :query => "(ID=*#{p.matrix_unique_id}:1*)",
|
277
|
-
# :limit => 1000,
|
278
|
-
# :timeout => -1
|
279
|
-
# }
|
280
|
-
# ids = []
|
281
|
-
# self.client.search(params) do |data|
|
282
|
-
# puts data
|
283
|
-
# ids << data['MEDIA_ID']
|
284
|
-
# m = CabooseRets::Media.where(:media_id => data['MEDIA_ID']).first
|
285
|
-
# m = CabooseRets::Media.new if m.nil?
|
286
|
-
# data.MEDIA_MUI = p.matrix_unique_id
|
287
|
-
# m.parse(data)
|
288
|
-
# m.save
|
289
|
-
# end
|
290
|
-
# if ids.count > 0
|
291
|
-
# # Delete any records in the local database that shouldn't be there
|
292
|
-
# self.log("- Deleting GFX records for MLS ##{p.matrix_unique_id} in the local database that are not in the remote database...")
|
293
|
-
# query = "select media_id from rets_media where matrix_unique_id = '#{p.matrix_unique_id}'"
|
294
|
-
# rows = ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send(:sanitize_sql_array, query))
|
295
|
-
# local_ids = rows.collect{ |row| row['media_id'] }
|
296
|
-
# ids_to_remove = local_ids - ids
|
297
|
-
# if ids_to_remove && ids_to_remove.count > 0
|
298
|
-
# query = ["delete from rets_media where media_id in (?)", ids_to_remove]
|
299
|
-
# ActiveRecord::Base.connection.execute(ActiveRecord::Base.send(:sanitize_sql_array, query))
|
300
|
-
# end
|
301
|
-
# end
|
302
|
-
# end
|
303
|
-
|
304
256
|
def self.download_property_images(p)
|
257
|
+
return if Rails.env.development?
|
305
258
|
self.log3('Property',p.mls_number,"Downloading images for #{p.mls_number}...")
|
306
259
|
ids_to_keep = []
|
307
260
|
begin
|
@@ -369,93 +322,21 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
369
322
|
end
|
370
323
|
end
|
371
324
|
|
372
|
-
# # Get first image
|
373
|
-
# self.client.get_object(:resource => 'Property', :type => 'Photo', :location=> false, :id => "#{p.matrix_unique_id}:0") do |headers, content|
|
374
|
-
# self.log3('Media',p.mls_number,"Downloading first photo with content-id #{headers['content-id']}, orderhint #{headers['orderhint']}, object-id #{headers['object-id']}")
|
375
|
-
# m = CabooseRets::Media.where(:media_mui => headers['content-id'], :media_order => 0).first
|
376
|
-
# m = CabooseRets::Media.new if m.nil?
|
377
|
-
# tmp_path = "#{Rails.root}/tmp/rets_media_#{headers['content-id']}:0.jpeg"
|
378
|
-
# File.open(tmp_path, "wb") do |f|
|
379
|
-
# f.write(content)
|
380
|
-
# end
|
381
|
-
# m.media_mui = headers['content-id']
|
382
|
-
# m.media_order = 0
|
383
|
-
# m.media_type = 'Photo'
|
384
|
-
# cm = Caboose::Media.new
|
385
|
-
# cm.image = File.open(tmp_path)
|
386
|
-
# cm.name = "rets_media_#{headers['content-id']}_0"
|
387
|
-
# cm.original_name = "rets_media_#{headers['content-id']}_0.jpeg"
|
388
|
-
# cm.processed = true
|
389
|
-
# cm.save
|
390
|
-
# m.media_id = cm.id
|
391
|
-
# m.save
|
392
|
-
# self.log3("Media",p.mls_number,"Created new RetsMedia object #{m.id}, CabooseMedia object #{cm.id}")
|
393
|
-
# `rm #{tmp_path}`
|
394
|
-
# self.log3("Media",p.mls_number,"Image rets_media_#{headers['content-id']}_0 saved")
|
395
|
-
# end
|
396
|
-
# # Get rest of images
|
397
|
-
# self.client.get_object(:resource => 'Property', :type => 'Photo', :location=> false, :id => "#{p.matrix_unique_id}:*") do |headers, content|
|
398
|
-
# self.log3('Media',p.mls_number,"Downloading subsequent photo with content-id #{headers['content-id']}, orderhint #{headers['orderhint']}, object-id #{headers['object-id']}")
|
399
|
-
# m = CabooseRets::Media.where(:media_mui => headers['content-id'], :media_order => headers['orderhint']).first
|
400
|
-
# m = CabooseRets::Media.new if m.nil?
|
401
|
-
# tmp_path = "#{Rails.root}/tmp/rets_media_#{headers['content-id']}:#{headers['object-id']}.jpeg"
|
402
|
-
# File.open(tmp_path, "wb") do |f|
|
403
|
-
# f.write(content)
|
404
|
-
# end
|
405
|
-
# m.media_mui = headers['content-id']
|
406
|
-
# m.media_order = headers['orderhint']
|
407
|
-
# m.media_type = 'Photo'
|
408
|
-
# cm = Caboose::Media.new
|
409
|
-
# cm.image = File.open(tmp_path)
|
410
|
-
# cm.name = "rets_media_#{headers['content-id']}_#{headers['object-id']}"
|
411
|
-
# cm.original_name = "rets_media_#{headers['content-id']}_#{headers['object-id']}.jpeg"
|
412
|
-
# cm.processed = true
|
413
|
-
# cm.save
|
414
|
-
# m.media_id = cm.id
|
415
|
-
# m.save
|
416
|
-
# self.log3("Media",p.mls_number,"Created new RetsMedia object #{m.id}, CabooseMedia object #{cm.id}")
|
417
|
-
# `rm #{tmp_path}`
|
418
|
-
# self.log3("Media",p.mls_number,"Image rets_media_#{headers['content-id']}_#{headers['object-id']} saved")
|
419
|
-
# end
|
420
|
-
# rescue RETS::APIError => err
|
421
|
-
# self.log "No image for #{p.mls_number}."
|
422
|
-
# self.log err
|
423
|
-
# end
|
424
325
|
end
|
425
326
|
|
426
327
|
def self.download_missing_images
|
427
328
|
self.log3("Property",nil,"Downloading all missing images...")
|
428
|
-
CabooseRets::Property.where("photo_count = ? OR photo_count is null", '').all.each do |p|
|
329
|
+
CabooseRets::Property.where("photo_count = ? OR photo_count is null", '').where(:status => "Active").all.each do |p|
|
429
330
|
self.delay(:priority => 10, :queue => 'rets').import_properties(p.mls_number, true)
|
430
331
|
end
|
431
332
|
end
|
432
333
|
|
433
334
|
def self.download_agent_image(agent)
|
434
|
-
|
435
|
-
# begin
|
436
|
-
# self.client.get_object(:resource => :Member, :type => :Photo, :location => true, :id => property.list_agent_mls_id) do |headers, content|
|
437
|
-
# agent.verify_meta_exists
|
438
|
-
# agent.meta.image_location = headers['location']
|
439
|
-
# agent.meta.save
|
440
|
-
# end
|
441
|
-
# rescue RETS::APIError => err
|
442
|
-
# self.log "No image for #{agent.first_name} #{agent.last_name}."
|
443
|
-
# self.log err
|
444
|
-
# end
|
335
|
+
|
445
336
|
end
|
446
337
|
|
447
338
|
def self.download_office_image(office)
|
448
|
-
|
449
|
-
#begin
|
450
|
-
# self.client.get_object(:resource => :Agent, :type => :Photo, :location => true, :id => agent.la_code) do |headers, content|
|
451
|
-
# agent.verify_meta_exists
|
452
|
-
# agent.meta.image_location = headers['location']
|
453
|
-
# agent.meta.save
|
454
|
-
# end
|
455
|
-
#rescue RETS::APIError => err
|
456
|
-
# self.log "No image for #{agent.first_name} #{agent.last_name}."
|
457
|
-
# self.log err
|
458
|
-
#end
|
339
|
+
|
459
340
|
end
|
460
341
|
|
461
342
|
#=============================================================================
|
@@ -517,6 +398,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
517
398
|
def self.purge_open_houses() self.delay(:priority => 10, :queue => 'rets').purge_helper('OpenHouse', '2012-01-01') end
|
518
399
|
|
519
400
|
|
401
|
+
# Adds/removes records in the database
|
520
402
|
def self.purge_helper(class_type, date_modified)
|
521
403
|
m = self.meta(class_type)
|
522
404
|
self.log(m.search_type)
|
@@ -573,12 +455,12 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
573
455
|
ids_to_remove = local_ids - ids
|
574
456
|
self.log3(class_type,nil,"Found #{ids_to_remove.count} #{class_type} records in the local database that are not in the remote database.")
|
575
457
|
|
576
|
-
# Delete all RetsMedia and CabooseMedia for the deleted property listings
|
458
|
+
# Delete all RetsMedia and CabooseMedia for the deleted property listings (except keep the first image)
|
577
459
|
if class_type == 'Property' && ids_to_remove && ids_to_remove.count > 0
|
578
460
|
self.log3(class_type,nil,"Deleting Media objects that shouldn't be there...")
|
579
461
|
muis = CabooseRets::Property.where("#{k} in (?)", ids_to_remove).pluck(:matrix_unique_id)
|
580
|
-
if muis && muis.count > 0
|
581
|
-
CabooseRets::Media.where("media_mui in (?)", muis).each do |med|
|
462
|
+
if muis && muis.count > 0 && Rails.env.production?
|
463
|
+
CabooseRets::Media.where("media_mui in (?)", muis).where("media_order != ?", 1).each do |med|
|
582
464
|
self.log3("Media",med.id,"Deleting old RetsMedia #{med.id} and CabooseMedia #{med.media_id}...")
|
583
465
|
m = Caboose::Media.where(:id => med.media_id).where("name ILIKE ?","rets_media%").first
|
584
466
|
m.destroy if m
|
@@ -587,9 +469,11 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
587
469
|
end
|
588
470
|
end
|
589
471
|
|
590
|
-
|
591
|
-
|
592
|
-
|
472
|
+
if class_type != 'Property' # keep all properties in the DB
|
473
|
+
self.log3(class_type,nil,"Deleting #{class_type} records in the local database that shouldn't be there...")
|
474
|
+
query = ["delete from #{t} where #{k} in (?)", ids_to_remove]
|
475
|
+
ActiveRecord::Base.connection.execute(ActiveRecord::Base.send(:sanitize_sql_array, query))
|
476
|
+
end
|
593
477
|
|
594
478
|
# Find any ids in the remote database that should be in the local database
|
595
479
|
self.log3(class_type,nil,"Finding #{class_type} records in the remote database that should be in the local database...")
|
@@ -612,54 +496,6 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
612
496
|
end
|
613
497
|
end
|
614
498
|
|
615
|
-
# def self.get_media_urls
|
616
|
-
# m = self.meta(class_type)
|
617
|
-
|
618
|
-
# # Get the total number of records
|
619
|
-
# params = {
|
620
|
-
# :search_type => m.search_type,
|
621
|
-
# :class => class_type,
|
622
|
-
# :query => "(#{m.matrix_modified_dt}=#{date_modified}T00:00:01+)",
|
623
|
-
# :standard_names_only => true,
|
624
|
-
# :timeout => -1
|
625
|
-
# }
|
626
|
-
# self.client.search(params.merge({ :count => 1 }))
|
627
|
-
# count = self.client.rets_data[:code] == "20201" ? 0 : self.client.rets_data[:count]
|
628
|
-
# batch_count = (count.to_f/5000.0).ceil
|
629
|
-
|
630
|
-
# ids = []
|
631
|
-
# k = m.remote_key_field
|
632
|
-
# (0...batch_count).each do |i|
|
633
|
-
# self.client.search(params.merge({ :select => [k], :limit => 5000, :offset => 5000*i })) do |data|
|
634
|
-
# ids << data[k]
|
635
|
-
# end
|
636
|
-
# end
|
637
|
-
|
638
|
-
# if ids.count > 0
|
639
|
-
# # Delete any records in the local database that shouldn't be there
|
640
|
-
# t = m.local_table
|
641
|
-
# k = m.local_key_field
|
642
|
-
# query = ["delete from #{t} where #{k} not in (?)", ids]
|
643
|
-
# ActiveRecord::Base.connection.execute(ActiveRecord::Base.send(:sanitize_sql_array, query))
|
644
|
-
|
645
|
-
# # Find any ids in the remote database that should be in the local database
|
646
|
-
# query = "select distinct #{k} from #{t}"
|
647
|
-
# rows = ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send(:sanitize_sql_array, query))
|
648
|
-
# local_ids = rows.collect{ |row| row[k] }
|
649
|
-
# ids_to_add = ids - local_ids
|
650
|
-
# ids_to_add.each do |id|
|
651
|
-
# self.log("Importing #{id}...")
|
652
|
-
# case class_type
|
653
|
-
# when "Property" then self.delay(:priority => 10, :queue => 'rets').import_properties(id, true)
|
654
|
-
# when "Office" then self.delay(:priority => 10, :queue => 'rets').import_office(id, false)
|
655
|
-
# when "Member" then self.delay(:priority => 10, :queue => 'rets').import_agent(id, false)
|
656
|
-
# when "OpenHouse" then self.delay(:priority => 10, :queue => 'rets').import_open_house(id, false)
|
657
|
-
# end
|
658
|
-
# end
|
659
|
-
# end
|
660
|
-
|
661
|
-
# end
|
662
|
-
|
663
499
|
#=============================================================================
|
664
500
|
# Logging
|
665
501
|
#=============================================================================
|
@@ -704,7 +540,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
704
540
|
overlap = 1.week
|
705
541
|
end
|
706
542
|
self.update_after((self.last_updated - overlap), false)
|
707
|
-
self.download_missing_images
|
543
|
+
self.download_missing_images if Rails.env.production?
|
708
544
|
self.log3(nil,nil,"Saving the timestamp for when we updated to #{task_started.to_s}...")
|
709
545
|
self.save_last_updated(task_started)
|
710
546
|
self.log2("Unlocking the task...")
|
@@ -725,7 +561,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
725
561
|
end
|
726
562
|
|
727
563
|
# Delete RETS logs over 7 days old
|
728
|
-
dt = DateTime.now -
|
564
|
+
dt = DateTime.now - 5.days
|
729
565
|
sql = "delete from rets_logs where timestamp < '#{dt}';"
|
730
566
|
ActiveRecord::Base.connection.select_all(sql)
|
731
567
|
|
@@ -347,6 +347,18 @@ class CabooseRets::Schema < Caboose::Utilities::Schema
|
|
347
347
|
Caboose::User => [
|
348
348
|
[ :rets_agent_mls_id , :string ]
|
349
349
|
],
|
350
|
+
CabooseRets::Notification => [
|
351
|
+
[ :user_id, :integer ],
|
352
|
+
[ :date_sent, :datetime ],
|
353
|
+
[ :site_id, :integer ],
|
354
|
+
[ :kind, :string ],
|
355
|
+
[ :sent_to, :string ],
|
356
|
+
[ :object_kind, :string ],
|
357
|
+
[ :object_id, :string ],
|
358
|
+
[ :old_value, :string ],
|
359
|
+
[ :new_value, :string ],
|
360
|
+
[ :message, :text ]
|
361
|
+
],
|
350
362
|
CabooseRets::RetsConfig => [
|
351
363
|
[ :site_id, :integer ],
|
352
364
|
[ :office_mls, :string ],
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<table border="0" cellpadding="0" cellspacing="0" width="800" id="templateColumns" style="width:100%;margin:0 0 20px 0;text-align:left;">
|
2
|
+
<tr>
|
3
|
+
<td align="left" valign="top" width="25%" class="templateColumnContainer" style="width:25%;padding:0;">
|
4
|
+
<a style="display:block;text-decoration:none;" href="<%= url %>/properties/<%= p.mls_number %>/details">
|
5
|
+
<% if p.featured_photo_url %>
|
6
|
+
<img style="display:block;max-width:200px;height:auto;" width="200" alt="MLS # <%= p.mls_number %>" src="<%= p.featured_photo_url %>" />
|
7
|
+
<% end %>
|
8
|
+
</a>
|
9
|
+
</td>
|
10
|
+
<td align="left" valign="top" width="37.5%" class="templateColumnContainer" style="width:37.5%;padding:5px 5px 5px 10px;">
|
11
|
+
<p style="margin:0 0 5px 0;font-size:14px;line-height:16px;"><strong>MLS#: <%= p.mls_number %></strong></p>
|
12
|
+
<address style="margin:0 0 5px 0;font-size:15px;line-height:17px;"><%== p.full_address_city %></address>
|
13
|
+
<p style="margin:0 0 5px 0;font-size:15px;line-height:17px;">
|
14
|
+
<% if !p.subdivision.blank? %><span><%= p.subdivision.titleize %></span> | <% end %>
|
15
|
+
<% if !p.city.blank? && p.city.upcase != "NONE" %><span><%= p.city.titleize %></span><% end %>
|
16
|
+
</p>
|
17
|
+
</td>
|
18
|
+
<td align="left" valign="top" width="37.5%" class="templateColumnContainer" style="width:37.5%;padding:5px 0 5px 10px;">
|
19
|
+
<p style="margin:0 0 5px 0;font-size:16px;line-height:18px;"><strong><%= number_to_currency(p.list_price, :precision => 0) %></strong></p>
|
20
|
+
<p style="margin:0 0 5px 0;font-size:15px;line-height:17px;">
|
21
|
+
<% if !p.beds_total.blank? %><span><strong><%= p.beds_total %></strong> beds</span><br /><% end %>
|
22
|
+
<% if !p.baths_full.blank? %><span><strong><%= p.baths_full %></strong> baths</span><br /><% end %>
|
23
|
+
<% if !p.baths_half.blank? && p.baths_half > 0 %><span><strong><%= p.baths_half %></strong> ½ baths</span><br /><% end %>
|
24
|
+
<% if !p.sqft_total.blank? %><span><strong><%= number_with_delimiter(p.sqft_total.to_i, :delimiter => ',') %></strong> sqft</span><% end %>
|
25
|
+
</p>
|
26
|
+
<% if !p.original_entry_timestamp.blank? %>
|
27
|
+
<p style="margin:0;font-size:13px;line-height:15px;">Listed <%= time_ago_in_words(p.original_entry_timestamp) %> ago</p>
|
28
|
+
<% end %>
|
29
|
+
</td>
|
30
|
+
</tr>
|
31
|
+
</table>
|
@@ -0,0 +1,76 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
5
|
+
<title></title>
|
6
|
+
<style>
|
7
|
+
@media only screen and (max-width: 480px) {
|
8
|
+
#templateColumns{
|
9
|
+
width: 100% !important;
|
10
|
+
}
|
11
|
+
.templateColumnContainer{
|
12
|
+
display: block !important;
|
13
|
+
width: 100% !important;
|
14
|
+
padding: 10px !important;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
</style>
|
18
|
+
</head>
|
19
|
+
<body>
|
20
|
+
<table border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="bodyTable">
|
21
|
+
<tr>
|
22
|
+
<td align="center" valign="top">
|
23
|
+
<table border="0" cellpadding="20" cellspacing="0" width="800" id="emailContainer">
|
24
|
+
<tr>
|
25
|
+
<td align="center" valign="top">
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
<div style="text-align:center;margin-bottom:20px;padding:20px;background-color:<%= @color %>;">
|
30
|
+
<a style="display:inline-block;text-decoration:none;" href="<%= @url %>" target="_blank">
|
31
|
+
<img style="display:block;margin:0;" src="<%= @logo_url %>" alt="<%= @site.description %>" width="220" />
|
32
|
+
</a>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div style="text-align:center;padding:20px;">
|
36
|
+
<h2>New and Suggested Listings</h2>
|
37
|
+
|
38
|
+
<% if @new_listings.count > 0 %>
|
39
|
+
<h3>New Listings</h3>
|
40
|
+
<% @new_listings.each do |prop| %>
|
41
|
+
<%== render :partial => "caboose_rets/rets_mailer/property_row", :locals => { :p => prop, :url => @domain } %>
|
42
|
+
<% end %>
|
43
|
+
<div style="padding:10px 10px 40px 10px;text-align:center;">
|
44
|
+
<a style="display:inline-block;border-radius:5px;background:<%= @color %>;color:#fff;padding:5px 15px;line-height:30px;text-decoration:none;font-size:15px;" target="_blank" href="<%= @url %>">See More New Listings</a>
|
45
|
+
</div>
|
46
|
+
<% end %>
|
47
|
+
|
48
|
+
<% if @related_listings.count > 0 %>
|
49
|
+
<h3>Suggested Listings</h3>
|
50
|
+
<% @related_listings.each do |prop| %>
|
51
|
+
<%== render :partial => "caboose_rets/rets_mailer/property_row", :locals => { :p => prop, :url => @domain } %>
|
52
|
+
<% end %>
|
53
|
+
<div style="padding:10px 10px 40px 10px;text-align:center;">
|
54
|
+
<a style="display:inline-block;border-radius:5px;background:<%= @color %>;color:#fff;padding:5px 15px;line-height:30px;text-decoration:none;font-size:15px;" target="_blank" href="<%= @domain %>/saved-properties">See My Saved Listings</a>
|
55
|
+
</div>
|
56
|
+
<% end %>
|
57
|
+
|
58
|
+
</div>
|
59
|
+
|
60
|
+
<div style="text-align:center;margin-top:20px;padding:20px;background-color:<%= @color %>;">
|
61
|
+
<p style="margin:0;font-size:13px;">
|
62
|
+
<a style="color:#fff;text-decoration:none;font-size:13px;display:inline-block;" target="_blank" href="<%= @unsubscribe_url %>">
|
63
|
+
Unsubscribe
|
64
|
+
</a>
|
65
|
+
</p>
|
66
|
+
</div>
|
67
|
+
|
68
|
+
</td>
|
69
|
+
</tr>
|
70
|
+
</table>
|
71
|
+
</td>
|
72
|
+
</tr>
|
73
|
+
</table>
|
74
|
+
</body>
|
75
|
+
</html>
|
76
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
5
|
+
<title></title>
|
6
|
+
<style>
|
7
|
+
@media only screen and (max-width: 480px) {
|
8
|
+
#templateColumns{
|
9
|
+
width: 100% !important;
|
10
|
+
}
|
11
|
+
.templateColumnContainer{
|
12
|
+
display: block !important;
|
13
|
+
width: 100% !important;
|
14
|
+
padding: 10px !important;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
</style>
|
18
|
+
</head>
|
19
|
+
<body>
|
20
|
+
<table border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="bodyTable">
|
21
|
+
<tr>
|
22
|
+
<td align="center" valign="top">
|
23
|
+
<table border="0" cellpadding="20" cellspacing="0" width="800" id="emailContainer">
|
24
|
+
<tr>
|
25
|
+
<td align="center" valign="top">
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
<div style="text-align:center;margin-bottom:20px;padding:20px;background-color:<%= @color %>;">
|
30
|
+
<a style="display:inline-block;text-decoration:none;" href="<%= @url %>" target="_blank">
|
31
|
+
<img style="display:block;margin:0;" src="<%= @logo_url %>" alt="<%= @site.description %>" width="220" />
|
32
|
+
</a>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div style="text-align:center;padding:20px;">
|
36
|
+
<h2>Price Changed</h2>
|
37
|
+
|
38
|
+
<% if @property %>
|
39
|
+
<%== render :partial => "caboose_rets/rets_mailer/property_row", :locals => { :p => @property, :url => @domain } %>
|
40
|
+
<div style="padding:0 10px;text-align:center;">
|
41
|
+
<p style="margin:0 0 6px 0;">
|
42
|
+
<strong>Old Price</strong>: <%= number_to_currency(@old_price, :precision => 0) %>
|
43
|
+
</p>
|
44
|
+
<p style="margin:0;">
|
45
|
+
<strong>New Price</strong>: <%= number_to_currency(@property.list_price, :precision => 0) %>
|
46
|
+
</p>
|
47
|
+
</div>
|
48
|
+
<% end %>
|
49
|
+
|
50
|
+
|
51
|
+
</div>
|
52
|
+
|
53
|
+
<div style="text-align:center;margin-top:20px;padding:20px;background-color:<%= @color %>;">
|
54
|
+
<p style="margin:0;font-size:13px;">
|
55
|
+
<a style="color:#fff;text-decoration:none;font-size:13px;display:inline-block;" target="_blank" href="<%= @unsubscribe_url %>">
|
56
|
+
Unsubscribe
|
57
|
+
</a>
|
58
|
+
</p>
|
59
|
+
</div>
|
60
|
+
|
61
|
+
</td>
|
62
|
+
</tr>
|
63
|
+
</table>
|
64
|
+
</td>
|
65
|
+
</tr>
|
66
|
+
</table>
|
67
|
+
</body>
|
68
|
+
</html>
|
69
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
5
|
+
<title></title>
|
6
|
+
<style>
|
7
|
+
@media only screen and (max-width: 480px) {
|
8
|
+
#templateColumns{
|
9
|
+
width: 100% !important;
|
10
|
+
}
|
11
|
+
.templateColumnContainer{
|
12
|
+
display: block !important;
|
13
|
+
width: 100% !important;
|
14
|
+
padding: 10px !important;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
</style>
|
18
|
+
</head>
|
19
|
+
<body>
|
20
|
+
<table border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="bodyTable">
|
21
|
+
<tr>
|
22
|
+
<td align="center" valign="top">
|
23
|
+
<table border="0" cellpadding="20" cellspacing="0" width="800" id="emailContainer">
|
24
|
+
<tr>
|
25
|
+
<td align="center" valign="top">
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
<div style="text-align:center;margin-bottom:20px;padding:20px;background-color:<%= @color %>;">
|
30
|
+
<a style="display:inline-block;text-decoration:none;" href="<%= @url %>" target="_blank">
|
31
|
+
<img style="display:block;margin:0;" src="<%= @logo_url %>" alt="<%= @site.description %>" width="220" />
|
32
|
+
</a>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div style="text-align:center;padding:20px;">
|
36
|
+
<h2>Status Changed</h2>
|
37
|
+
|
38
|
+
<% if @property %>
|
39
|
+
<%== render :partial => "caboose_rets/rets_mailer/property_row", :locals => { :p => @property, :url => @domain } %>
|
40
|
+
<div style="padding:0 10px;text-align:center;">
|
41
|
+
<p style="margin:0 0 6px 0;">
|
42
|
+
<strong>Old Status</strong>: <%= @old_status %>
|
43
|
+
</p>
|
44
|
+
<p style="margin:0;">
|
45
|
+
<strong>New Status</strong>: <%= @property.status %>
|
46
|
+
</p>
|
47
|
+
</div>
|
48
|
+
<% end %>
|
49
|
+
|
50
|
+
|
51
|
+
</div>
|
52
|
+
|
53
|
+
<div style="text-align:center;margin-top:20px;padding:20px;background-color:<%= @color %>;">
|
54
|
+
<p style="margin:0;font-size:13px;">
|
55
|
+
<a style="color:#fff;text-decoration:none;font-size:13px;display:inline-block;" target="_blank" href="<%= @unsubscribe_url %>">
|
56
|
+
Unsubscribe
|
57
|
+
</a>
|
58
|
+
</p>
|
59
|
+
</div>
|
60
|
+
|
61
|
+
</td>
|
62
|
+
</tr>
|
63
|
+
</table>
|
64
|
+
</td>
|
65
|
+
</tr>
|
66
|
+
</table>
|
67
|
+
</body>
|
68
|
+
</html>
|
69
|
+
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div style="text-align:center;margin-bottom:20px;padding:20px;background-color:<%= @color %>;">
|
2
2
|
<a style="display:inline-block;text-decoration:none;" href="<%= @url %>" target="_blank">
|
3
|
-
<img style="display:block;" src="<%= @logo_url %>" alt="<%= @site.description %>" width="220" />
|
3
|
+
<img style="display:block;margin:0;" src="<%= @logo_url %>" alt="<%= @site.description %>" width="220" />
|
4
4
|
</a>
|
5
5
|
</div>
|
6
6
|
|
@@ -12,7 +12,7 @@
|
|
12
12
|
</div>
|
13
13
|
|
14
14
|
<div style="text-align:center;margin-top:20px;padding:20px;background-color:<%= @color %>;">
|
15
|
-
<p style="margin
|
15
|
+
<p style="margin:0;font-size:13px;">
|
16
16
|
<a style="color:#fff;text-decoration:none;font-size:13px;display:inline-block;" target="_blank" href="<%= @unsubscribe_url %>">
|
17
17
|
Unsubscribe
|
18
18
|
</a>
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
<div class="mb-holder">
|
6
6
|
<p><div id='user_<%= @edituser.id %>_rets_agent_mls_id' ></div></p>
|
7
|
-
<% if @edituser.date_created %><p>Date Registered: <%= @edituser.date_created.in_time_zone('Central Time (US & Canada)').strftime('%B %-d, %Y') %></p><% end %>
|
7
|
+
<% if @edituser.date_created %><p>Date Registered: <%= @edituser.date_created.in_time_zone('Central Time (US & Canada)').strftime('%B %-d, %Y, %l:%M%P') %></p><% end %>
|
8
8
|
</div>
|
9
9
|
|
10
10
|
<% if @saved.count > 0 %>
|
@@ -15,7 +15,30 @@
|
|
15
15
|
<% next if prop.nil? || prop.status != 'Active' %>
|
16
16
|
<li>
|
17
17
|
<a href="/properties/<%= sp.mls_number %>/details" target="_blank">MLS #<%= sp.mls_number %> - <%= prop.full_address %></a>
|
18
|
-
<% if !sp.date_saved.blank? %><span> - saved on <%= sp.date_saved.in_time_zone('Central Time (US & Canada)').strftime('%B %-d, %Y') %></span><% end %>
|
18
|
+
<% if !sp.date_saved.blank? %><span> - saved on <%= sp.date_saved.in_time_zone('Central Time (US & Canada)').strftime('%B %-d, %Y, %l:%M%P') %></span><% end %>
|
19
|
+
</li>
|
20
|
+
<% end %>
|
21
|
+
</ul>
|
22
|
+
<% end %>
|
23
|
+
|
24
|
+
<% if @emails.count > 0 %>
|
25
|
+
<h3 class="sp">Emails Sent</h3>
|
26
|
+
<ul class="saved">
|
27
|
+
<% @emails.each do |em| %>
|
28
|
+
<li>
|
29
|
+
<strong><%= em.kind %></strong>
|
30
|
+
<span>- sent on <%= em.date_sent.in_time_zone('Central Time (US & Canada)').strftime('%B %-d, %Y, %l:%M%P') %></span>
|
31
|
+
<% if !em.message.blank? %>
|
32
|
+
<p><%== em.message.gsub("\n","<br />") %></p>
|
33
|
+
<% elsif em.object_kind == 'Property' && em.object_id %>
|
34
|
+
<p><a href="/properties/<%= em.object_id %>/details" target="_blank">MLS # <%= em.object_id %></a>,
|
35
|
+
<% if em.kind.include?('Price') %>
|
36
|
+
Old Price: <%= number_to_currency(em.old_value, :precision => 0) %> -> New Price: <%= number_to_currency(em.new_value, :precision => 0) %>
|
37
|
+
<% else %>
|
38
|
+
Old Status: <%= em.old_value %> -> New Status: <%= em.new_value %>
|
39
|
+
<% end %>
|
40
|
+
</p>
|
41
|
+
<% end %>
|
19
42
|
</li>
|
20
43
|
<% end %>
|
21
44
|
</ul>
|
@@ -29,12 +52,25 @@
|
|
29
52
|
margin: 30px 0 10px 0;
|
30
53
|
}
|
31
54
|
ul.saved {
|
55
|
+
margin: 0;
|
32
56
|
padding-left: 0;
|
33
57
|
list-style-type: none;
|
34
58
|
}
|
35
59
|
ul.saved li {
|
36
60
|
display: block;
|
37
|
-
margin-bottom:
|
61
|
+
margin-bottom: 5px;
|
62
|
+
}
|
63
|
+
ul.saved li a {
|
64
|
+
text-decoration: none;
|
65
|
+
color: #3939a7;
|
66
|
+
}
|
67
|
+
ul.saved li a:hover {
|
68
|
+
color: #59a739;
|
69
|
+
}
|
70
|
+
ul.saved li p {
|
71
|
+
margin: 3px 0 0 0;
|
72
|
+
color: #3e3e3e;
|
73
|
+
font-size: 13px;
|
38
74
|
}
|
39
75
|
ul.saved li a {
|
40
76
|
text-decoration: none;
|
data/lib/caboose_rets/version.rb
CHANGED
data/lib/tasks/caboose_rets.rake
CHANGED
@@ -242,6 +242,10 @@ namespace :caboose_rets do
|
|
242
242
|
CabooseRets::RetsImporter.update_helper('Property', last_updated, false)
|
243
243
|
end
|
244
244
|
|
245
|
+
task :send_daily_emails => :environment do
|
246
|
+
CabooseRets::Notification.delay(:queue => "rets").send_new_suggested_emails
|
247
|
+
end
|
248
|
+
|
245
249
|
#desc "Delete old rets properties"
|
246
250
|
#task :delete_old_properties => :environment do
|
247
251
|
# CabooseRets::RetsImporter.delete_old_properties
|
@@ -275,6 +279,11 @@ namespace :caboose_rets do
|
|
275
279
|
CabooseRets::RetsImporter.update_helper("OpenHouse", d, false)
|
276
280
|
end
|
277
281
|
|
282
|
+
desc "update rets"
|
283
|
+
task :updater => :environment do
|
284
|
+
CabooseRets::RetsImporter.delay(:queue => "rets").update_rets
|
285
|
+
end
|
286
|
+
|
278
287
|
desc "Updates all the listings from MLS"
|
279
288
|
task :update_rets => :environment do
|
280
289
|
if task_is_locked
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: caboose-rets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.184
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Barry
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: caboose-cms
|
@@ -71,6 +71,7 @@ files:
|
|
71
71
|
- app/models/caboose_rets/agent_meta.rb
|
72
72
|
- app/models/caboose_rets/log.rb
|
73
73
|
- app/models/caboose_rets/media.rb
|
74
|
+
- app/models/caboose_rets/notification.rb
|
74
75
|
- app/models/caboose_rets/office.rb
|
75
76
|
- app/models/caboose_rets/office_meta.rb
|
76
77
|
- app/models/caboose_rets/open_house.rb
|
@@ -107,7 +108,11 @@ files:
|
|
107
108
|
- app/views/caboose_rets/properties/property_not_exists.html.erb
|
108
109
|
- app/views/caboose_rets/properties/test_form.html.erb
|
109
110
|
- app/views/caboose_rets/rets/admin_import_form.html.erb
|
111
|
+
- app/views/caboose_rets/rets_mailer/_property_row.html.erb
|
112
|
+
- app/views/caboose_rets/rets_mailer/daily_report.html.erb
|
110
113
|
- app/views/caboose_rets/rets_mailer/new_user.html.erb
|
114
|
+
- app/views/caboose_rets/rets_mailer/property_price_change.html.erb
|
115
|
+
- app/views/caboose_rets/rets_mailer/property_status_change.html.erb
|
111
116
|
- app/views/caboose_rets/rets_mailer/user_welcome.html.erb
|
112
117
|
- app/views/caboose_rets/saved_properties/index.html.erb
|
113
118
|
- app/views/caboose_rets/saved_properties/rets_info.html.erb
|