Class: SalesGoal
Overview
== Schema Information
Table name: sales_goals
Database name: primary
id :integer not null, primary key
bonus_t1_flat :decimal(6, 2)
bonus_t1_multiplier :decimal(8, 4)
bonus_t2_flat :decimal(6, 2)
bonus_t2_multiplier :decimal(8, 4)
period_begins :date not null
period_ends :date not null
report_grouping :string(255)
sales_goal :decimal(10, 2) default(0.0), not null
sales_goal_t2 :decimal(8, 2)
created_at :datetime
updated_at :datetime
company_id :integer
creator_id :integer
employee_id :integer
updater_id :integer
Indexes
idx_unique_sales_goals (employee_id,report_grouping,period_begins,period_ends)
Constant Summary
Models::Auditable::ALWAYS_IGNORED
Constants included
from Schedulable
Schedulable::SIMPLE_FORM_OPTIONS
Instance Attribute Summary collapse
#creator, #updater
Class Method Summary
collapse
Instance Method Summary
collapse
#all_skipped_columns, #audit_reference_data, #should_not_save_version, #stamp_record
ransackable_associations, ransackable_attributes, ransortable_attributes, #to_relation
config
#after_commit
#publish_event
Instance Attribute Details
#bonus_t1_flat ⇒ Object
45
|
# File 'app/models/sales_goal.rb', line 45
validates :bonus_t1_flat, numericality: { greater_than: 0, less_than: 5000, if: -> { bonus_t1_flat.present? } }
|
#bonus_t1_multiplier ⇒ Object
43
|
# File 'app/models/sales_goal.rb', line 43
validates :bonus_t1_multiplier, numericality: { greater_than: 0, less_than: 0.03, if: -> { bonus_t1_multiplier.present? } }
|
#bonus_t2_flat ⇒ Object
46
|
# File 'app/models/sales_goal.rb', line 46
validates :bonus_t2_flat, numericality: { greater_than: 0, less_than: 5000, if: -> { bonus_t2_flat.present? } }
|
#bonus_t2_multiplier ⇒ Object
44
|
# File 'app/models/sales_goal.rb', line 44
validates :bonus_t2_multiplier, numericality: { greater_than: 0, less_than: 0.03, if: -> { bonus_t2_multiplier.present? } }
|
#force_sync ⇒ Object
Returns the value of attribute force_sync.
32
33
34
|
# File 'app/models/sales_goal.rb', line 32
def force_sync
@force_sync
end
|
#period_begins ⇒ Object
37
|
# File 'app/models/sales_goal.rb', line 37
validates :period_begins, :period_ends, :sales_goal, presence: true
|
#period_ends ⇒ Object
37
|
# File 'app/models/sales_goal.rb', line 37
validates :period_begins, :period_ends, :sales_goal, presence: true
|
#sales_goal ⇒ Object
37
|
# File 'app/models/sales_goal.rb', line 37
validates :period_begins, :period_ends, :sales_goal, presence: true
|
#sales_goal_t2 ⇒ Object
38
|
# File 'app/models/sales_goal.rb', line 38
validates :sales_goal_t2, presence: { if: -> { bonus_t2_multiplier.present? or bonus_t2_flat.present? } }
|
Class Method Details
.channels_for_select ⇒ Object
292
293
294
|
# File 'app/models/sales_goal.rb', line 292
def self.channels_for_select
CustomerConstants::REPORT_GROUPINGS
end
|
.in_period ⇒ ActiveRecord::Relation<SalesGoal>
A relation of SalesGoals that are in period. Active Record Scope
61
62
63
64
|
# File 'app/models/sales_goal.rb', line 61
scope :in_period, ->(date) {
date = Date.parse(date) unless date.is_a?(Date)
where(period_begins: ..date, period_ends: date..)
}
|
.in_same_quarter ⇒ ActiveRecord::Relation<SalesGoal>
A relation of SalesGoals that are in same quarter. Active Record Scope
57
58
59
60
|
# File 'app/models/sales_goal.rb', line 57
scope :in_same_quarter, ->(date) {
date = Date.parse(date) unless date.is_a?(Date)
where(period_begins: date.all_quarter)
}
|
.monthly_goals ⇒ ActiveRecord::Relation<SalesGoal>
A relation of SalesGoals that are monthly goals. Active Record Scope
55
|
# File 'app/models/sales_goal.rb', line 55
scope :monthly_goals, -> { where('(period_ends - period_begins) BETWEEN 27 and 32') }
|
.periods(date = nil) ⇒ Object
97
98
99
|
# File 'app/models/sales_goal.rb', line 97
def self.periods(date = nil)
[] + periods_for_quarter_for_select(date) + periods_for_year_for_select(date)
end
|
.periods_for_quarter_for_select(date = nil) ⇒ Object
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
# File 'app/models/sales_goal.rb', line 72
def self.periods_for_quarter_for_select(date = nil)
date ||= Date.current
periods = []
date_start = date.beginning_of_year
(0..11).to_a.each do |m|
dt = date_start + m.month
dt_label = "#{dt.strftime('%B')} #{dt.year}"
dt_val = "#{dt}|#{dt.end_of_month}"
periods << [dt_label, dt_val]
end
(1..4).to_a.each do |q|
dt = Date.new(date_start.year, q * 3, 1).beginning_of_quarter
periods << ["Quarter #{q}, #{dt.year}", "#{dt}|#{dt.end_of_quarter}"]
end
periods
end
|
.periods_for_year_for_select(date = nil) ⇒ Object
90
91
92
93
94
95
|
# File 'app/models/sales_goal.rb', line 90
def self.periods_for_year_for_select(date = nil)
date ||= Date.current
dts = date.beginning_of_year
dte = date.end_of_year
[["Year #{date.year}", "#{dts}|#{dte}"]]
end
|
.quarterly_goals ⇒ ActiveRecord::Relation<SalesGoal>
A relation of SalesGoals that are quarterly goals. Active Record Scope
56
|
# File 'app/models/sales_goal.rb', line 56
scope :quarterly_goals, -> { where('(period_ends - period_begins) BETWEEN 83 and 94') }
|
.ransackable_scopes(_auth_user = nil) ⇒ Object
68
69
70
|
# File 'app/models/sales_goal.rb', line 68
def self.ransackable_scopes(_auth_user = nil)
%i[in_same_quarter in_period]
end
|
.sorted ⇒ ActiveRecord::Relation<SalesGoal>
A relation of SalesGoals that are sorted. Active Record Scope
66
|
# File 'app/models/sales_goal.rb', line 66
scope :sorted, -> { order('parties.full_name, sales_goals.period_ends, sales_goals.period_begins DESC, sales_goals.report_grouping') }
|
Instance Method Details
#active? ⇒ Boolean
170
171
172
|
# File 'app/models/sales_goal.rb', line 170
def active?
Date.current.between?(period_begins, period_ends)
end
|
#all_standard_monthly_goals_in_period ⇒ Object
275
276
277
|
# File 'app/models/sales_goal.rb', line 275
def all_standard_monthly_goals_in_period
SalesGoal.monthly_goals.in_same_quarter(period_begins).where(employee_id: employee_id).where(report_grouping: nil) if employee_id
end
|
#bonus_t1 ⇒ Object
210
211
212
213
214
215
216
217
218
219
|
# File 'app/models/sales_goal.rb', line 210
def bonus_t1
bonus = nil
if met_t1? && !met_t2?
bonus = 0.0
bonus += booked * bonus_t1_multiplier if bonus_t1_multiplier
bonus += bonus_t1_flat if bonus_t1_flat
bonus = nil if bonus <= 0
end
bonus
end
|
#bonus_t2 ⇒ Object
221
222
223
224
225
226
227
228
229
230
|
# File 'app/models/sales_goal.rb', line 221
def bonus_t2
bonus = nil
if met_t2?
bonus = 0.0
bonus += booked * bonus_t2_multiplier if bonus_t2_multiplier
bonus += bonus_t2_flat if bonus_t2_flat
bonus = nil if bonus <= 0
end
bonus
end
|
#booked ⇒ Object
174
175
176
177
178
179
180
|
# File 'app/models/sales_goal.rb', line 174
def booked
inv = Invoice.sales_orders.where('invoices.shipped_date BETWEEN ? and ?', period_begins, period_ends)
inv = inv.where(primary_sales_rep_id: employee_id) if employee_id
inv = inv.where(report_grouping: report_grouping) if report_grouping.present?
inv = inv.where(company_id: company_id) if company_id.present?
inv.sum(:revenue_consolidated) || 0.00
end
|
#business_days_left ⇒ Object
154
155
156
|
# File 'app/models/sales_goal.rb', line 154
def business_days_left
Date.current.working_days_until(period_ends) if (Date.current >= period_begins) && (Date.current <= period_ends)
end
|
Validations:
-
Presence
({ if: -> { report_grouping.present? }, message: 'must be specified if channel is set.' })
35
|
# File 'app/models/sales_goal.rb', line 35
belongs_to :company, optional: true
|
#daily_target_t1 ⇒ Object
158
159
160
161
162
|
# File 'app/models/sales_goal.rb', line 158
def daily_target_t1
if (bdl = business_days_left) && (rt = remaining_t1)
rt / bdl
end
end
|
#daily_target_t2 ⇒ Object
164
165
166
167
168
|
# File 'app/models/sales_goal.rb', line 164
def daily_target_t2
if (bdl = business_days_left) && (rt = remaining_t2)
rt / bdl
end
end
|
#editable? ⇒ Boolean
260
261
262
263
|
# File 'app/models/sales_goal.rb', line 260
def editable?
new_record? || period_ends > (Date.current + 2.weeks)
end
|
34
|
# File 'app/models/sales_goal.rb', line 34
belongs_to :employee, optional: true
|
#goal_name ⇒ Object
136
137
138
139
140
141
142
143
144
|
# File 'app/models/sales_goal.rb', line 136
def goal_name
n = []
n << employee.full_name if employee
n << report_grouping if report_grouping
n << period_name
n << Company.find(company_id).short_name if company_id.present?
n << 'goal'
n.join(' ')
end
|
#has_prequisite? ⇒ Boolean
256
257
258
|
# File 'app/models/sales_goal.rb', line 256
def has_prequisite?
prerequisite_goal.present?
end
|
#has_tier2_goal? ⇒ Boolean
252
253
254
|
# File 'app/models/sales_goal.rb', line 252
def has_tier2_goal?
employee_id.present? && sales_goal_t2.present? && sales_goal_t2 > 0
end
|
#met_t1? ⇒ Boolean
202
203
204
|
# File 'app/models/sales_goal.rb', line 202
def met_t1?
prerequisite_goal_met? and booked >= sales_goal
end
|
#met_t2? ⇒ Boolean
206
207
208
|
# File 'app/models/sales_goal.rb', line 206
def met_t2?
met_t1? and sales_goal_t2 and booked >= sales_goal_t2
end
|
#month? ⇒ Boolean
117
118
119
|
# File 'app/models/sales_goal.rb', line 117
def month?
(period_ends - period_begins) <= 31
end
|
#period ⇒ Object
105
106
107
|
# File 'app/models/sales_goal.rb', line 105
def period
"#{period_begins}|#{period_ends}"
end
|
#period=(val) ⇒ Object
101
102
103
|
# File 'app/models/sales_goal.rb', line 101
def period=(val)
self.period_begins, self.period_ends = val.split('|').map { |v| Date.strptime(v, '%Y-%m-%d') }
end
|
#period_name ⇒ Object
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
# File 'app/models/sales_goal.rb', line 121
def period_name
return unless period_begins && period_ends
if year?
"Year #{period_begins.year}"
elsif quarter?
quarter = period_begins.quarter_index
"Quarter #{quarter}, #{period_begins.year}"
elsif month?
"#{period_begins.strftime('%B')} #{period_begins.year}"
else
"#{period_begins} - #{period_ends}"
end
end
|
#prerequisite_goal ⇒ Object
240
241
242
243
244
245
246
247
248
249
250
|
# File 'app/models/sales_goal.rb', line 240
def prerequisite_goal
prg = nil
if employee_id && report_grouping
prg = SalesGoal.where(period_begins: period_begins,
period_ends: period_ends,
report_grouping: report_grouping,
employee_id: nil).first
end
prg
end
|
#prerequisite_goal_met? ⇒ Boolean
232
233
234
235
236
237
238
|
# File 'app/models/sales_goal.rb', line 232
def prerequisite_goal_met?
if prerequisite_goal
prerequisite_goal.met_t1?
else
true
end
end
|
#progress_t1 ⇒ Object
182
183
184
185
186
187
188
189
190
|
# File 'app/models/sales_goal.rb', line 182
def progress_t1
return unless sales_goal && (sales_goal > 0)
if booked > 0
[((booked / sales_goal) * 100).to_i, 100].min
else
0
end
end
|
#progress_t2 ⇒ Object
192
193
194
195
196
197
198
199
200
|
# File 'app/models/sales_goal.rb', line 192
def progress_t2
return unless sales_goal_t2 && (sales_goal_t2 > 0)
if booked > 0
[((booked / sales_goal_t2) * 100).to_i, 100].min
else
0
end
end
|
#quarter? ⇒ Boolean
113
114
115
|
# File 'app/models/sales_goal.rb', line 113
def quarter?
!year? && (period_ends - period_begins) > 31
end
|
#remaining_t1 ⇒ Object
146
147
148
|
# File 'app/models/sales_goal.rb', line 146
def remaining_t1
[sales_goal - booked, 0].max if sales_goal && (sales_goal > 0)
end
|
#remaining_t2 ⇒ Object
150
151
152
|
# File 'app/models/sales_goal.rb', line 150
def remaining_t2
[sales_goal_t2 - booked, 0].max if sales_goal_t2 && (sales_goal > 0)
end
|
#span ⇒ Object
265
266
267
268
269
270
271
272
273
|
# File 'app/models/sales_goal.rb', line 265
def span
if quarter?
'Quarter'
elsif month?
'Month'
else
'Custom'
end
end
|
#year? ⇒ Boolean
109
110
111
|
# File 'app/models/sales_goal.rb', line 109
def year?
(period_ends - period_begins) >= 364
end
|