civic311_test3 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  3. data/app/assets/fonts/glyphicons-halflings-regular.svg +288 -0
  4. data/app/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  5. data/app/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  6. data/app/assets/fonts/glyphicons-halflings-regular.woff2 +0 -0
  7. data/app/assets/images/.keep +0 -0
  8. data/app/assets/javascripts/admin.coffee +3 -0
  9. data/app/assets/javascripts/application.js +17 -0
  10. data/app/assets/javascripts/bootstrap.js.coffee +4 -0
  11. data/app/assets/javascripts/custom.js +147 -0
  12. data/app/assets/stylesheets/admin.scss +3 -0
  13. data/app/assets/stylesheets/application.css +72 -0
  14. data/app/assets/stylesheets/bootstrap.min.css +5 -0
  15. data/app/assets/stylesheets/bootstrap_and_overrides.css.less +34 -0
  16. data/app/assets/stylesheets/rails_admin.css +69 -0
  17. data/app/controllers/admin_controller.rb +404 -0
  18. data/app/controllers/application_controller.rb +5 -0
  19. data/app/controllers/concerns/.keep +0 -0
  20. data/app/helpers/admin_helper.rb +2 -0
  21. data/app/helpers/application_helper.rb +16 -0
  22. data/app/mailers/.keep +0 -0
  23. data/app/models/.keep +0 -0
  24. data/app/models/acceptance.rb +13 -0
  25. data/app/models/agent.rb +270 -0
  26. data/app/models/agent_change_info.rb +67 -0
  27. data/app/models/agent_designation.rb +12 -0
  28. data/app/models/agent_language.rb +12 -0
  29. data/app/models/agent_specialty.rb +12 -0
  30. data/app/models/agent_ticket.rb +12 -0
  31. data/app/models/agent_zip_code.rb +16 -0
  32. data/app/models/best_use.rb +4 -0
  33. data/app/models/buying_wishlist.rb +33 -0
  34. data/app/models/concerns/.keep +0 -0
  35. data/app/models/connection.rb +13 -0
  36. data/app/models/customer.rb +76 -0
  37. data/app/models/customer_device.rb +248 -0
  38. data/app/models/customer_location_alert.rb +31 -0
  39. data/app/models/delayed_job.rb +6 -0
  40. data/app/models/designation.rb +29 -0
  41. data/app/models/help.rb +6 -0
  42. data/app/models/investing_wishlist.rb +18 -0
  43. data/app/models/investing_wishlist_type.rb +12 -0
  44. data/app/models/investment_type.rb +13 -0
  45. data/app/models/issue.rb +9 -0
  46. data/app/models/language.rb +39 -0
  47. data/app/models/license.rb +31 -0
  48. data/app/models/payment_transaction.rb +12 -0
  49. data/app/models/promotion_code.rb +10 -0
  50. data/app/models/property_type.rb +15 -0
  51. data/app/models/question.rb +6 -0
  52. data/app/models/rating.rb +13 -0
  53. data/app/models/rating_question.rb +28 -0
  54. data/app/models/rating_request.rb +8 -0
  55. data/app/models/renting_wishlist.rb +31 -0
  56. data/app/models/request_showing.rb +14 -0
  57. data/app/models/schema_migration.rb +6 -0
  58. data/app/models/selling_wishlist.rb +28 -0
  59. data/app/models/setting.rb +6 -0
  60. data/app/models/sharing.rb +15 -0
  61. data/app/models/specialty.rb +25 -0
  62. data/app/models/state.rb +21 -0
  63. data/app/models/suggestion.rb +10 -0
  64. data/app/models/user.rb +107 -0
  65. data/app/models/user_history.rb +6 -0
  66. data/app/models/wishlist.rb +17 -0
  67. data/app/views/admin/_form.html.erb +184 -0
  68. data/app/views/admin/_header.html.erb +58 -0
  69. data/app/views/admin/dashboard.html.erb +142 -0
  70. data/app/views/admin/delete.html.erb +0 -0
  71. data/app/views/admin/edit.html.erb +25 -0
  72. data/app/views/admin/export.html.erb +64 -0
  73. data/app/views/admin/index.html.erb +111 -0
  74. data/app/views/admin/new.html.erb +25 -0
  75. data/app/views/admin/new.js.erb +1 -0
  76. data/app/views/admin/show.html.erb +57 -0
  77. data/app/views/admin/test.html.erb +41 -0
  78. data/app/views/kaminari/_first_page.html.erb +11 -0
  79. data/app/views/kaminari/_gap.html.erb +8 -0
  80. data/app/views/kaminari/_last_page.html.erb +11 -0
  81. data/app/views/kaminari/_next_page.html.erb +11 -0
  82. data/app/views/kaminari/_page.html.erb +12 -0
  83. data/app/views/kaminari/_paginator.html.erb +23 -0
  84. data/app/views/kaminari/_prev_page.html.erb +11 -0
  85. data/app/views/layouts/_sidebar.html.erb +10 -0
  86. data/app/views/layouts/application.html.erb +51 -0
  87. data/civic311_test3-0.0.1.gem +0 -0
  88. data/civic311_test3.gemspec +3 -2
  89. data/config/application.rb +26 -0
  90. data/config/boot.rb +3 -0
  91. data/config/database.yml +54 -0
  92. data/config/environment.rb +5 -0
  93. data/config/environments/development.rb +41 -0
  94. data/config/environments/production.rb +79 -0
  95. data/config/environments/test.rb +42 -0
  96. data/config/initializers/assets.rb +11 -0
  97. data/config/initializers/auto_admin.rb +9 -0
  98. data/config/initializers/backtrace_silencers.rb +7 -0
  99. data/config/initializers/cookies_serializer.rb +3 -0
  100. data/config/initializers/filter_parameter_logging.rb +4 -0
  101. data/config/initializers/inflections.rb +16 -0
  102. data/config/initializers/mime_types.rb +4 -0
  103. data/config/initializers/session_store.rb +3 -0
  104. data/config/initializers/wrap_parameters.rb +14 -0
  105. data/config/locales/en.bootstrap.yml +17 -0
  106. data/config/locales/en.yml +28 -0
  107. data/config/routes.rb +71 -0
  108. data/config/secrets.yml +22 -0
  109. data/lib/civic311_test3/version.rb +1 -1
  110. metadata +123 -3
@@ -0,0 +1,5 @@
1
+ class ApplicationController < ActionController::Base
2
+ # Prevent CSRF attacks by raising an exception.
3
+ # For APIs, you may want to use :null_session instead.
4
+ protect_from_forgery with: :exception
5
+ end
File without changes
@@ -0,0 +1,2 @@
1
+ module AdminHelper
2
+ end
@@ -0,0 +1,16 @@
1
+ module ApplicationHelper
2
+
3
+ def sortable(column, title = nil)
4
+ title ||= column.titleize
5
+ css_class = column == sort_column ? "current #{sort_direction}" : nil
6
+ direction = column == sort_column && sort_direction == "asc" ? "desc" : "asc"
7
+
8
+ per_page =10;
9
+ per_page = params[:per_page] ? params[:per_page] : 10;
10
+ params[:per_page]=per_page;
11
+ param1 = params[:param1] ? params[:param1] : 1;
12
+
13
+ link_to title, {:sort => column, :direction => direction, :per_page => per_page, :param1 => param1}, {:class => css_class}
14
+ end
15
+
16
+ end
data/app/mailers/.keep ADDED
File without changes
data/app/models/.keep ADDED
File without changes
@@ -0,0 +1,13 @@
1
+ class Acceptance < ActiveRecord::Base
2
+
3
+ self.table_name = "acceptances"
4
+ self.primary_key = 'id'
5
+
6
+ belongs_to :sharing, :inverse_of => :acceptance
7
+ belongs_to :agent, :inverse_of => :acceptances
8
+
9
+ def describe_id
10
+ "Acceptance ##{id}"
11
+ end
12
+
13
+ end
@@ -0,0 +1,270 @@
1
+ class Agent < ActiveRecord::Base
2
+
3
+ self.table_name = "agents"
4
+ self.primary_key = 'id'
5
+
6
+ #DEFAULT_RADIUS = APP_CONFIG["default_radius"]
7
+ #MAX_RADIUS = APP_CONFIG["max_radius"]
8
+ #MAX_AGENTS_TOTAL = APP_CONFIG["max_agents_total"]
9
+
10
+ #PENDING = "pending"
11
+ #APPROVED = "approved"
12
+ #REJECTED = "reject"
13
+ #UNKNOWN = "unknown"
14
+ #CHANGE_COMPANY_NAME = "change_company_name"
15
+ #CHANGE_PROFILE = "change_profile"
16
+
17
+ #geocoded_by :address
18
+ #after_validation :geocode
19
+
20
+ validates :phone_number, uniqueness: true
21
+ validates :sent_rating, numericality: true,allow_nil: true
22
+
23
+ has_many :acceptances, :inverse_of => :agent
24
+ has_many :agent_languages, :inverse_of => :agent
25
+ has_many :agent_specialties, :inverse_of => :agent
26
+ has_many :agent_designations, :inverse_of => :agent
27
+ has_many :agent_zip_codes, :inverse_of => :agent
28
+ has_many :licenses, :inverse_of => :agent
29
+ has_one :rating_request, :inverse_of => :agent
30
+ has_many :payment_transactions, :inverse_of => :agent
31
+ has_one :ratings, :inverse_of => :agent
32
+ # has_many :connections, :dependent => :delete_all
33
+ belongs_to :user, :inverse_of => :agent
34
+ belongs_to :state, :class_name => "State", :foreign_key => "license_state_issued"
35
+
36
+ #has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "150x200^" }, :default_url => ""
37
+ #validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
38
+
39
+ #rails_admin do
40
+ #configure :connections do
41
+ #visible(false)
42
+ #end
43
+
44
+ #configure :ratings do
45
+ #visible(false)
46
+ #end
47
+
48
+ #configure :rating_requests do
49
+ #visible(false)
50
+ #end
51
+
52
+ #configure :helpings do
53
+ #visible(false)
54
+ #end
55
+ #end
56
+
57
+ def name
58
+ if first_name.present? && last_name.present?
59
+ "#{first_name} #{last_name}"
60
+ end
61
+ end
62
+
63
+ def as_json(request)
64
+ avatar = ""
65
+ avatar = request.protocol + request.host_with_port + self.avatar.url if self.avatar.present?
66
+ {
67
+ email: self.user.email,
68
+ first_name: self.first_name,
69
+ last_name: self.last_name,
70
+ company_name: self.company_name,
71
+ phone_number: self.phone_number,
72
+ about: self.about,
73
+ license_number: self.license_number,
74
+ license_state_issued: self.license_state_issued,
75
+ license_issued_date: self.license_issued_date,
76
+ license_url: self.try(:state).try(:main_page_url),
77
+ status: self.status,
78
+ website_url: self.website_url,
79
+ listing_url: self.listing_url,
80
+ video_url: self.video_url,
81
+ avatar: avatar,
82
+ edit_profile_state: self.edit_profile_state,
83
+ edit_company_name_state: self.edit_company_name_state
84
+ }
85
+ end
86
+
87
+ def as_json2(request)
88
+ avatar = ""
89
+ avatar = request.protocol + request.host_with_port + self.avatar.url if self.avatar.present?
90
+ agent_change_info = self.user.agent_change_info.where(action: CHANGE_PROFILE, status: [PENDING, APPROVED]).last
91
+ agent_change_company_name = self.user.agent_change_info.where(action: CHANGE_COMPANY_NAME , status: [PENDING, APPROVED]).last
92
+ license = self.licenses.where(status: ["Pending", "Actived"]).last
93
+
94
+ {
95
+ email: self.user.email,
96
+ first_name: agent_change_info ? agent_change_info.first_name_new : self.first_name,
97
+ last_name: agent_change_info ? agent_change_info.last_name_new : self.last_name,
98
+ company_name: agent_change_company_name ? agent_change_company_name.company_name_new : self.company_name,
99
+ phone_number: self.phone_number,
100
+ about: self.about,
101
+ license_number: license ? license.license_number : self.license_number,
102
+ license_state_issued: license ? license.license_state_issued : self.license_state_issued,
103
+ license_issued_date: license ? license.license_issued_date : self.license_issued_date,
104
+ license_url: self.try(:state).try(:main_page_url),
105
+ status: self.status,
106
+ website_url: self.website_url,
107
+ listing_url: self.listing_url,
108
+ video_url: self.video_url,
109
+ avatar: avatar,
110
+ edit_profile_state: self.edit_profile_state,
111
+ edit_company_name_state: self.edit_company_name_state
112
+ }
113
+ end
114
+
115
+ def get_rating_information
116
+ ratings = Rating.where(agent_id: self.id)
117
+ numCustomerRates = ratings.distinct.count(:customer_id)
118
+ avgAll = ratings.average('rate').to_f
119
+ avgQuestion = ratings.group('rating_question_id').average('rate').map{|question, rate| {question: question, rate: rate}}
120
+ ratings = ratings.joins(:rating_question).group('category')
121
+ avgCategory = ratings.average('rate').map{|category, rate| {category: category, rate: rate}}
122
+ numRateCategory = ratings.distinct.count("customer_id").map{|category, num| {category: category, numCustomerRates: num}}
123
+ avgCategory_temp = ratings.average('rate').map{|category, rate| {category: category, numCustomerRates: rate}}
124
+ {numCustomerRates: numCustomerRates, avgAllRates: avgAll, numRateCategory: numRateCategory,avgCategory_temp: avgCategory_temp, avgCategory: avgCategory, avgQuestion: avgQuestion}
125
+ end
126
+
127
+ def get_agent_info_history
128
+ agent_change_info = AgentChangeInfo.where(user_id: self.user_id,status: APPROVED,action: CHANGE_COMPANY_NAME).last
129
+ if agent_change_info.blank? || agent_change_info.updated_at < Time.now - 1.months
130
+ self.update_attributes({:edit_company_name_state => PENDING})
131
+ return agent_change_info
132
+ end
133
+ return agent_change_info
134
+ end
135
+ def save_company_name(company_name_new)
136
+
137
+ agent_change_info = AgentChangeInfo.find_by(user_id: self.user_id,status: PENDING,action: CHANGE_COMPANY_NAME)
138
+ if agent_change_info.blank?
139
+ agent_change_info = AgentChangeInfo.new( user_id: self.user_id,company_name_old: self.company_name,
140
+ company_name_new: company_name_new, status: PENDING,
141
+ action: CHANGE_COMPANY_NAME)
142
+ first_times = true
143
+ else
144
+ first_times = false
145
+ gt_month = agent_change_info.updated_at.utc < Time.now.utc - 1.minute
146
+ agent_change_info.company_name_new = company_name_new
147
+ end
148
+ if agent_change_info.save
149
+ begin
150
+ if first_times
151
+ self.update!(edit_company_name_state: UNKNOWN)
152
+ message = I18n.t 'saveCompanyName_success_gt_30'
153
+ else
154
+ if gt_month
155
+ self.update!(edit_company_name_state: UNKNOWN)
156
+ message = I18n.t 'saveCompanyName_success_gt_30'
157
+ else
158
+ self.update!(edit_company_name_state: PENDING)
159
+ message = I18n.t 'saveCompanyName_success_ltq_30'
160
+ end
161
+ end
162
+ return true, message
163
+ rescue Exception => e
164
+ puts "============errors"
165
+ p e
166
+ return false, ""
167
+ end
168
+ end
169
+ puts "=========error"
170
+ puts agent_change_info.errors.inspect
171
+ return false
172
+ end
173
+
174
+ def save_fullname(first_name_new, last_name_new)
175
+ agent_change_info = AgentChangeInfo.find_by(user_id: self.user_id,status: PENDING,action: CHANGE_PROFILE)
176
+ if agent_change_info.blank?
177
+ agent_change_info = AgentChangeInfo.new(first_name_new: first_name_new, first_name_old: self.first_name, last_name_new: last_name_new,
178
+ last_name_old: self.last_name, user_id: self.user_id,
179
+ status: PENDING,action: CHANGE_PROFILE)
180
+ else
181
+ agent_change_info.first_name_new = first_name_new
182
+ agent_change_info.last_name_new = last_name_new
183
+ end
184
+ if agent_change_info.save
185
+ begin
186
+ self.update!(edit_profile_state: PENDING)
187
+ return true
188
+ rescue Exception => e
189
+ p e
190
+ return false
191
+ end
192
+ end
193
+ return false
194
+ end
195
+
196
+ def push_notification_online
197
+ customer_location_alerts = CustomerLocationAlert.where("time_expired > (?) and is_alert IS TRUE",Time.now).within(DEFAULT_RADIUS,:units => :miles, origin: [self.latitude, self.longitude])
198
+ user_ids = customer_location_alerts.select("user_id")
199
+ customer_devices = CustomerDevice.where(user_id: user_ids)
200
+ unless customer_location_alerts.blank? || customer_devices.blank?
201
+ sns = Aws::SNS::Client.new
202
+ p "======================================"
203
+ p customer_devices
204
+ customer_devices.each do |customer_device|
205
+ customer_device.push_notification_agent_online(self)
206
+ end
207
+ end
208
+ end
209
+ def push_notification_apply_change(message,change_info)
210
+ customer_devices = self.user.customer_devices
211
+ unless customer_devices.blank?
212
+ customer_devices.each do |customer_device|
213
+ customer_device.push_notification_change_first_last_name(message,change_info)
214
+ end
215
+
216
+ end
217
+ end
218
+
219
+ def push_notification_change_license(status)
220
+ customer_devices = self.user.customer_devices
221
+ unless customer_devices.blank?
222
+ customer_devices.each do |customer_device|
223
+ customer_device.push_notification_change_license(status,self)
224
+ end
225
+
226
+ end
227
+ end
228
+
229
+ def push_notification_apply_change_company(message,change_info)
230
+ customer_devices = self.user.customer_devices
231
+ unless customer_devices.blank?
232
+ customer_devices.each do |customer_device|
233
+ customer_device.push_notification_change_company_name(message,change_info)
234
+ end
235
+
236
+ end
237
+ end
238
+
239
+
240
+ def push_notification_to_agent_background(type,customer,sharing)
241
+ customer_devices = self.user.customer_devices
242
+ unless customer_devices.blank?
243
+ customer_devices.each do |customer_device|
244
+ customer_device.push_notification_background(type,self,customer,sharing)
245
+ end
246
+
247
+ end
248
+
249
+
250
+ end
251
+
252
+ def self.get_total_agent_from_current_location(latitude, longtitude)
253
+ radius = DEFAULT_RADIUS
254
+ total_agents = Agent.joins(:user).where("users.is_online = true").near([latitude, longtitude], radius, :units => :mi)
255
+ #total_agents = Agent.joins(:user).near([latitude, longtitude], radius, :units => :mi)
256
+ while total_agents.size.to_i <= MAX_AGENTS_TOTAL && radius < MAX_RADIUS
257
+ p total_agents.size.to_i
258
+ radius += DEFAULT_RADIUS
259
+ total_agents = Agent.joins(:user).where("users.is_online = true").near([latitude, longtitude], radius, :units => :mi)
260
+ #total_agents = Agent.joins(:user).near([latitude, longtitude], radius, :units => :mi)
261
+
262
+ end
263
+
264
+ total_agents.size.to_s
265
+ end
266
+
267
+ def is_holdon?
268
+ self.edit_profile_state == PENDING or self.edit_company_name_state == PENDING
269
+ end
270
+ end
@@ -0,0 +1,67 @@
1
+ class AgentChangeInfo < ActiveRecord::Base
2
+
3
+ self.table_name = "agent_change_infos"
4
+ self.primary_key = 'id'
5
+
6
+ PENDING = "pending"
7
+ APPROVED = "approved"
8
+ CHANGE_COMPANY_NAME = "change_company_name"
9
+ CHANGE_PROFILE = "change_profile"
10
+ REJECT = "reject"
11
+ belongs_to :user
12
+ #validate :first_name_new, :last_name_new, presence: true
13
+ after_update :update_edit_state
14
+
15
+ def describe_id
16
+ "AgentChangeInfo ##{id}"
17
+ end
18
+
19
+ def update_edit_state
20
+ if status_changed?
21
+ agent = self.user.agent
22
+ action = self.action
23
+ status = self.status
24
+ p action
25
+ p status
26
+ if action == CHANGE_PROFILE
27
+ if status == REJECT
28
+ begin
29
+ agent.update!(first_name: self.first_name_old, last_name: last_name_old,edit_profile_state: REJECT)
30
+ UserMailer.delay.send_email_notification(agent, CHANGE_PROFILE, REJECT)
31
+ agent.push_notification_apply_change(REJECT,self);
32
+ rescue Exception => e
33
+ p e
34
+ end
35
+ elsif status == APPROVED
36
+ begin
37
+ agent.update!(edit_profile_state: APPROVED,:first_name => self.first_name_new,:last_name => self.last_name_new)
38
+ UserMailer.delay.send_email_notification(agent, CHANGE_PROFILE, APPROVED)
39
+ agent.push_notification_apply_change(APPROVED,self)
40
+ rescue Exception => e
41
+ p e
42
+ end
43
+ else
44
+ return
45
+ end
46
+ elsif action == CHANGE_COMPANY_NAME
47
+ if status == REJECT
48
+ begin
49
+ agent.update!(company_name: self.company_name_old,edit_company_name_state: REJECT)
50
+ UserMailer.delay.send_email_notification(agent, CHANGE_COMPANY_NAME, REJECT)
51
+ agent.push_notification_apply_change_company(REJECT,self)
52
+ rescue Exception => e
53
+ p e
54
+ end
55
+ elsif status == APPROVED
56
+ begin
57
+ agent.update!(company_name: self.company_name_new,edit_company_name_state: APPROVED)
58
+ UserMailer.delay.send_email_notification(agent, CHANGE_COMPANY_NAME, APPROVED)
59
+ agent.push_notification_apply_change_company(APPROVED,self)
60
+ rescue Exception => e
61
+ p e
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,12 @@
1
+ class AgentDesignation < ActiveRecord::Base
2
+
3
+ self.table_name = "agent_designations"
4
+ self.primary_key = 'id'
5
+
6
+ belongs_to :designation, :inverse_of => :agent_designations
7
+ belongs_to :agent, :inverse_of => :agent_designations
8
+
9
+ def describe_id
10
+ "AgentDesignation ##{id}"
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ class AgentLanguage < ActiveRecord::Base
2
+
3
+ self.table_name = "agent_languages"
4
+ self.primary_key = 'id'
5
+
6
+ belongs_to :agent, :inverse_of => :agent_languages
7
+ belongs_to :language, :inverse_of => :agent_languages
8
+
9
+ def describe_id
10
+ "AgentLanguage ##{id}"
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ class AgentSpecialty < ActiveRecord::Base
2
+
3
+ self.table_name = "agent_specialties"
4
+ self.primary_key = 'id'
5
+
6
+ belongs_to :agent, :inverse_of => :agent_specialties
7
+ belongs_to :specialty, :inverse_of => :agent_specialties
8
+
9
+ def describe_id
10
+ "AgentSpecialty ##{id}"
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ class AgentTicket < ActiveRecord::Base
2
+
3
+ self.table_name = "agent_tickets"
4
+ self.primary_key = 'id'
5
+
6
+ validates :tick_type, presence: true
7
+ validates :name, presence: true
8
+ VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
9
+ validates :email, presence: true, format: {with: VALID_EMAIL_REGEX}
10
+ validates :phone_number, presence: true
11
+ validates :content, presence: true
12
+ end
@@ -0,0 +1,16 @@
1
+ class AgentZipCode < ActiveRecord::Base
2
+
3
+ self.table_name = "agent_zip_codes"
4
+ self.primary_key = 'id'
5
+
6
+ belongs_to :agent, :inverse_of => :agent_zip_codes
7
+
8
+ # Get Agent's zipcodes
9
+ def self.get_agent_zipcodes(agent)
10
+ AgentZipCode.where(agent_id: agent.id).pluck(:zip_code).map{|code| {zip_code: code}}
11
+ end
12
+
13
+ def describe_id
14
+ "AgentZipCode ##{id}"
15
+ end
16
+ end