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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0685d8060e2893e21ce7813a2258f5987c0b522b5cf38c2703300fd9508f114f'
4
- data.tar.gz: 5055f63de96a36585c00614e26d4f4f5b13bcb5575c6147ed70a1f6722f0f682
3
+ metadata.gz: 84ef101eafb83b5891a32f9557f355e5f46de43e3d1e544aad19e5a533e78b6e
4
+ data.tar.gz: 1ddefc2dbff138dcb82eb3e4c879f9b19956726d2dd20ca134ec7106a45ce99e
5
5
  SHA512:
6
- metadata.gz: 35f1c82f2581745f2c38b3543964163649e9b3b5b4a3560dba4624f576567c7532fe4be14119c55b808d5bbc4403373957c95c0ab1a77f0d538e56a9127156e5
7
- data.tar.gz: 382a2e824f97e5f0827021d192dc0914f926e18a7e46bbc05655d4660a63efe2b5f427c98d3168d89c91b7c6cd83cea3e04edf0581cc3669b66a1ee2b70a4ef2
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').all
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 = "MlsStatus=Active"
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
- # self.log "Saving image for #{agent.first_name} #{agent.last_name}..."
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
- #self.log "Saving image for #{agent.first_name} #{agent.last_name}..."
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
- self.log3(class_type,nil,"Deleting #{class_type} records in the local database that shouldn't be there...")
591
- query = ["delete from #{t} where #{k} in (?)", ids_to_remove]
592
- ActiveRecord::Base.connection.execute(ActiveRecord::Base.send(:sanitize_sql_array, query))
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 - 7.days
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-top:20px;font-size:13px;">
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: 3px;
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;
@@ -1,3 +1,3 @@
1
1
  module CabooseRets
2
- VERSION = '0.1.183'
2
+ VERSION = '0.1.184'
3
3
  end
@@ -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.183
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-07-27 00:00:00.000000000 Z
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