c80_estate 0.1.0.1 → 0.1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/admin/c80_estate/sevents.rb +71 -0
- data/app/assets/javascript/c80_estate/backend/admin/areas.js +1 -1
- data/app/assets/javascript/c80_estate/backend/admin/sevents.js +199 -0
- data/app/assets/javascript/c80_estate/lib/google_charts_loader.js +149 -0
- data/app/assets/javascript/c80_estate_active_admin.js.coffee +1 -1
- data/app/assets/stylesheets/c80_estate/backend/admin_sevents.scss +111 -0
- data/app/controllers/c80_estate/ajax_controller.rb +14 -0
- data/app/models/c80_estate/area.rb +60 -0
- data/app/models/c80_estate/astatus.rb +1 -0
- data/app/models/c80_estate/atype.rb +2 -0
- data/app/models/c80_estate/owner.rb +2 -0
- data/app/models/c80_estate/property.rb +1 -0
- data/app/models/c80_estate/sevent.rb +368 -0
- data/config/routes.rb +1 -0
- data/db/migrate/20160713043333_create_c80_estate_sevents.rb +13 -0
- data/lib/c80_estate/version.rb +1 -1
- metadata +8 -2
@@ -0,0 +1,111 @@
|
|
1
|
+
body.admin_sevents {
|
2
|
+
|
3
|
+
&.index {
|
4
|
+
|
5
|
+
div#main_content {
|
6
|
+
opacity: 0;
|
7
|
+
|
8
|
+
-webkit-transition: opacity .2s ease-in;
|
9
|
+
-moz-transition: opacity .2s ease-in;
|
10
|
+
-ms-transition: opacity .2s ease-in;
|
11
|
+
-o-transition: opacity .2s ease-in;
|
12
|
+
transition: opacity .2s ease-in;
|
13
|
+
|
14
|
+
div#index_adds {
|
15
|
+
height: calc(183px + 15px);
|
16
|
+
min-height: calc(183px + 15px);
|
17
|
+
margin-bottom: 0;
|
18
|
+
|
19
|
+
> div {
|
20
|
+
float: left;
|
21
|
+
padding: 10px;
|
22
|
+
border-radius: 2px;
|
23
|
+
border: 2px solid #f1f1f1;
|
24
|
+
height: 183px;
|
25
|
+
|
26
|
+
&#ecoef {
|
27
|
+
width: 200px;
|
28
|
+
text-align: center;
|
29
|
+
|
30
|
+
p {
|
31
|
+
width: 100%;
|
32
|
+
|
33
|
+
&.val {
|
34
|
+
margin-top: 15px;
|
35
|
+
margin-bottom: 0;
|
36
|
+
font-size: 40px;
|
37
|
+
}
|
38
|
+
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
&#text_stats {
|
43
|
+
width: 400px;
|
44
|
+
margin-left: 30px;
|
45
|
+
|
46
|
+
ul {
|
47
|
+
padding: 0 5px;
|
48
|
+
list-style: none;
|
49
|
+
#title {
|
50
|
+
font-weight: bold;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
}
|
55
|
+
|
56
|
+
&#graph {
|
57
|
+
/*width: calc(100% - 200px - 400px - 30px - 30px);*/
|
58
|
+
width: 100%;
|
59
|
+
height: 200px;
|
60
|
+
margin-top: 15px;
|
61
|
+
|
62
|
+
/*margin-left: 30px;*/
|
63
|
+
padding: 0;
|
64
|
+
display: none;
|
65
|
+
opacity: 0;
|
66
|
+
|
67
|
+
-webkit-transition: opacity .2s ease-in;
|
68
|
+
-moz-transition: opacity .2s ease-in;
|
69
|
+
-ms-transition: opacity .2s ease-in;
|
70
|
+
-o-transition: opacity .2s ease-in;
|
71
|
+
transition: opacity .2s ease-in;
|
72
|
+
}
|
73
|
+
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
}
|
78
|
+
|
79
|
+
.batch_actions_selector {
|
80
|
+
display: none;
|
81
|
+
}
|
82
|
+
|
83
|
+
.action_items {
|
84
|
+
display: none;
|
85
|
+
}
|
86
|
+
|
87
|
+
a.delete_link {
|
88
|
+
display: none;
|
89
|
+
}
|
90
|
+
|
91
|
+
.col-actions {
|
92
|
+
text-align: right;
|
93
|
+
}
|
94
|
+
|
95
|
+
a.edit_link {
|
96
|
+
display: none;
|
97
|
+
}
|
98
|
+
|
99
|
+
h2#page_title {
|
100
|
+
opacity: 0;
|
101
|
+
|
102
|
+
-webkit-transition: opacity .2s ease-in;
|
103
|
+
-moz-transition: opacity .2s ease-in;
|
104
|
+
-ms-transition: opacity .2s ease-in;
|
105
|
+
-o-transition: opacity .2s ease-in;
|
106
|
+
transition: opacity .2s ease-in;
|
107
|
+
}
|
108
|
+
|
109
|
+
}
|
110
|
+
|
111
|
+
}
|
@@ -13,5 +13,19 @@ module C80Estate
|
|
13
13
|
|
14
14
|
end
|
15
15
|
|
16
|
+
def areas_ecoef
|
17
|
+
|
18
|
+
area_id = request.params[:area_id] == "" ? nil:request.params[:area_id]
|
19
|
+
start_date = request.params[:start_date] == "" ? nil:request.params[:start_date]
|
20
|
+
end_date = request.params[:end_date] == "" ? nil:request.params[:end_date]
|
21
|
+
|
22
|
+
obj = Sevent.ecoef(area_id: area_id, start_date: start_date, end_date: end_date)
|
23
|
+
|
24
|
+
respond_to do |format|
|
25
|
+
format.js { render json: obj, status: :ok }
|
26
|
+
# format.json
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
16
30
|
end
|
17
31
|
end
|
@@ -24,6 +24,11 @@ module C80Estate
|
|
24
24
|
has_and_belongs_to_many :astatuses, # единственный статус: либо занята, либо свободна
|
25
25
|
:join_table => 'c80_estate_areas_astatuses'
|
26
26
|
|
27
|
+
has_many :sevents, :dependent => :destroy
|
28
|
+
|
29
|
+
after_create :create_initial_sevent
|
30
|
+
after_update :check_and_generate_sevent
|
31
|
+
|
27
32
|
def self.all_areas
|
28
33
|
self.all
|
29
34
|
end
|
@@ -60,6 +65,14 @@ module C80Estate
|
|
60
65
|
res
|
61
66
|
end
|
62
67
|
|
68
|
+
def astatus_id
|
69
|
+
res = -1
|
70
|
+
if astatuses.count > 0
|
71
|
+
res = astatuses.first.id
|
72
|
+
end
|
73
|
+
res
|
74
|
+
end
|
75
|
+
|
63
76
|
def assigned_person_title
|
64
77
|
res = "-"
|
65
78
|
if assigned_person.present?
|
@@ -68,5 +81,52 @@ module C80Estate
|
|
68
81
|
res
|
69
82
|
end
|
70
83
|
|
84
|
+
def owner_id
|
85
|
+
res = -1
|
86
|
+
if owner.present?
|
87
|
+
res = owner.id
|
88
|
+
end
|
89
|
+
res
|
90
|
+
end
|
91
|
+
|
92
|
+
protected
|
93
|
+
|
94
|
+
# при создании площади генерится начальное событие
|
95
|
+
def create_initial_sevent
|
96
|
+
Rails.logger.debug "<Area.create_initial_sevent>"
|
97
|
+
|
98
|
+
Sevent.create!({
|
99
|
+
area_id: self.id,
|
100
|
+
atype_id: self.atype_id,
|
101
|
+
property_id: self.property_id,
|
102
|
+
astatus_id: self.astatus_id,
|
103
|
+
auser_id: self.owner_id, # инициатор события - создатель Площади
|
104
|
+
auser_type: 'AdminUser'
|
105
|
+
})
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
def check_and_generate_sevent
|
110
|
+
Rails.logger.debug "<Area.check_and_generate_sevent>"
|
111
|
+
|
112
|
+
# находим последнее известное событие
|
113
|
+
# фиксируем его статус
|
114
|
+
last_known_sevent = self.sevents.last.astatus.tag
|
115
|
+
|
116
|
+
# если статус этого события отличен
|
117
|
+
# от нового статуса - генерим событие
|
118
|
+
if last_known_sevent != self.astatuses.first.tag
|
119
|
+
Sevent.create!({
|
120
|
+
area_id: self.id,
|
121
|
+
atype_id: self.atype_id,
|
122
|
+
property_id: self.property_id,
|
123
|
+
astatus_id: self.astatus_id,
|
124
|
+
auser_id: self.owner_id, # инициатор события - редактор Площади
|
125
|
+
auser_type: 'AdminUser'
|
126
|
+
})
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
71
131
|
end
|
72
132
|
end
|
@@ -14,6 +14,8 @@ module C80Estate
|
|
14
14
|
# has_many :properties, :dependent => :destroy
|
15
15
|
has_many :atphotos, :dependent => :destroy # одна или несколько фоток
|
16
16
|
|
17
|
+
has_many :sevents, :dependent => :nullify
|
18
|
+
|
17
19
|
extend FriendlyId
|
18
20
|
friendly_id :slug_candidates, :use => :slugged
|
19
21
|
|
@@ -38,6 +38,8 @@ module C80Estate
|
|
38
38
|
# эта взаимосвязь трактуется, как "площадь, назначенная сотруднику"
|
39
39
|
has_many :assigned_properties, :as => :assigned_person, :class_name => 'C80Estate::Property', :dependent => :nullify
|
40
40
|
|
41
|
+
has_many :sevents, :as => :auser, :class_name => 'C80Estate::Sevent', :dependent => :nullify
|
42
|
+
|
41
43
|
after_create :create_role
|
42
44
|
|
43
45
|
def create_role
|
@@ -0,0 +1,368 @@
|
|
1
|
+
module C80Estate
|
2
|
+
class Sevent < ActiveRecord::Base
|
3
|
+
belongs_to :area
|
4
|
+
belongs_to :atype
|
5
|
+
belongs_to :property
|
6
|
+
belongs_to :astatus
|
7
|
+
belongs_to :auser, :polymorphic => true
|
8
|
+
|
9
|
+
=begin
|
10
|
+
def self.all_areas
|
11
|
+
self.all
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.free_areas
|
15
|
+
self.joins(:astatuses).where(:c80_estate_astatuses => { tag: 'free'})
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.busy_areas
|
19
|
+
self.joins(:astatuses).where(:c80_estate_astatuses => { tag: 'busy'})
|
20
|
+
end
|
21
|
+
=end
|
22
|
+
|
23
|
+
def self.ecoef(area_id: nil, prop_id: nil, atype_id: nil, start_date: nil, end_date: nil)
|
24
|
+
# start_date: строка вида 2015-12-12
|
25
|
+
|
26
|
+
result = {}
|
27
|
+
|
28
|
+
# unless end_date.present?
|
29
|
+
# end_date = Time.now.utc #.to_s(:db)
|
30
|
+
# end
|
31
|
+
# unless start_date.present?
|
32
|
+
# if prop_id.present?
|
33
|
+
# start_date =
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
|
37
|
+
# произведём выборку из базы в list согласно параметрам
|
38
|
+
list = []
|
39
|
+
|
40
|
+
# если ничего не подано - выбираем всё и считаем среднее
|
41
|
+
if area_id.nil? && prop_id.nil? && atype_id.nil? && start_date.nil? && end_date.nil?
|
42
|
+
|
43
|
+
# в result соберём хэш, где ключ - area_id
|
44
|
+
# а значение - объект вида {time_free, time_busy} -
|
45
|
+
# время, сколько площадь была в аренде или была свободна
|
46
|
+
|
47
|
+
# раскидаем все sevents по area_id related спискам
|
48
|
+
self.all.each do |sevent|
|
49
|
+
aid = sevent.area_id
|
50
|
+
unless result[aid].present?
|
51
|
+
result[aid] = {
|
52
|
+
time_free: 0,
|
53
|
+
time_busy: 0,
|
54
|
+
ecoef: 0,
|
55
|
+
start_date:self.first.created_at,
|
56
|
+
end_date:Time.now,
|
57
|
+
sevents: []
|
58
|
+
}
|
59
|
+
end
|
60
|
+
result[aid][:sevents] << sevent
|
61
|
+
end
|
62
|
+
|
63
|
+
# теперь пробежимся по спискам площадей и посчитаем время
|
64
|
+
result.each_key do |area_id|
|
65
|
+
|
66
|
+
# фиксируем area
|
67
|
+
a = result[area_id]
|
68
|
+
|
69
|
+
# считаем free busy time
|
70
|
+
t = self._calc_busy_time(a)
|
71
|
+
a[:time_free] = t[:time_free]
|
72
|
+
a[:time_busy] = t[:time_busy]
|
73
|
+
a[:ecoef] = t[:ecoef]
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
# теперь имеется result в котором посчитаны time_free и time_busy
|
78
|
+
# каждой площади
|
79
|
+
# пробежимся по нему и посчитаем коэф-ты
|
80
|
+
k = 0
|
81
|
+
summ = 0
|
82
|
+
result.each_key do |area_id|
|
83
|
+
a = result[area_id]
|
84
|
+
# a[:ecoef] = a[:time_busy] / (a[:time_busy] + a[:time_free])
|
85
|
+
Rails.logger.debug "<ecoef> area_id=#{area_id}, time_free=#{a[:time_free]}, time_busy=#{a[:time_busy]}, ecoef=#{a[:ecoef]}"
|
86
|
+
k += 1
|
87
|
+
summ += a[:ecoef]
|
88
|
+
end
|
89
|
+
|
90
|
+
result[:average_value] = sprintf "%.2f%", summ/k*100
|
91
|
+
result[:comment] = "<abbr title='Период рассчёта эффективности: с момента самого первого известного события до текущего дня'>C #{Time.at(self.first.created_at).strftime('%Y/%m/%d')} по #{Time.now.year}/#{sprintf "%02d", Time.now.month}/#{sprintf "%02d", Time.now.day}</abbr>"
|
92
|
+
result[:abbr] = 'Среднее значение для всех площадей за весь период'
|
93
|
+
result[:title] = 'Статистика - Все площади'
|
94
|
+
result[:props] = [
|
95
|
+
{tag:'all_areas_count', val: "Площадей всего: #{Area.all.count}"},
|
96
|
+
{tag:'free_areas_count', val: "Площадей свободно: #{Area.free_areas.count}"},
|
97
|
+
{tag:'busy_areas_count', val: "Площадей занято: #{Area.busy_areas.count}"}
|
98
|
+
]
|
99
|
+
|
100
|
+
|
101
|
+
# если фильтруем по area
|
102
|
+
elsif area_id.present?
|
103
|
+
|
104
|
+
# фиксируем area
|
105
|
+
area = Area.find(area_id)
|
106
|
+
|
107
|
+
# обозначим диапазон фильтрации
|
108
|
+
area_created_at = Time.at(area.created_at)
|
109
|
+
time_now = Time.now
|
110
|
+
Rails.logger.debug("area_created_at = #{area_created_at}")
|
111
|
+
Rails.logger.debug("time_now = #{time_now}")
|
112
|
+
|
113
|
+
# если подана нижняя граница диапазона и она позже, чем время создания Площади,
|
114
|
+
# выравниваем период рассчета коэф-та по этой нижней границе диапазона
|
115
|
+
if start_date.present?
|
116
|
+
start_date_tt = Time.parse(start_date)
|
117
|
+
if start_date_tt > area_created_at
|
118
|
+
used_start_date = start_date_tt
|
119
|
+
Rails.logger.debug("start_date: используем аргумент: #{start_date_tt}")
|
120
|
+
else
|
121
|
+
used_start_date = area_created_at
|
122
|
+
Rails.logger.debug("start_date: используем время рождения Площади: #{area_created_at}")
|
123
|
+
end
|
124
|
+
else
|
125
|
+
used_start_date = area_created_at
|
126
|
+
Rails.logger.debug("start_date: используем время рождения Площади: #{area_created_at}")
|
127
|
+
end
|
128
|
+
used_start_date_str = used_start_date.strftime('%Y/%m/%d')
|
129
|
+
|
130
|
+
if end_date.present?
|
131
|
+
end_date_tt = Time.parse(end_date)
|
132
|
+
if end_date < time_now
|
133
|
+
used_end_date = end_date_tt
|
134
|
+
Rails.logger.debug("end_date: используем аргумент: #{end_date_tt}")
|
135
|
+
else
|
136
|
+
used_end_date = time_now
|
137
|
+
Rails.logger.debug("end_date: используем текущее время")
|
138
|
+
end
|
139
|
+
else
|
140
|
+
used_end_date = time_now
|
141
|
+
Rails.logger.debug("end_date: используем текущее время")
|
142
|
+
end
|
143
|
+
used_end_date_str = used_end_date.strftime('%Y/%m/%d')
|
144
|
+
|
145
|
+
Rails.logger.debug("start_date = #{start_date}; end_date = #{end_date}; used_start_date = #{used_start_date}; used_end_date = #{used_end_date}")
|
146
|
+
# sevents = self.where(:area_id => area_id).where(:created_at => used_start_date..used_end_date)
|
147
|
+
sevents = self.where(:area_id => area_id).where("created_at BETWEEN ? AND ?", used_start_date, used_end_date)
|
148
|
+
|
149
|
+
# если в этот промежуток небыло событий - значит промежуток целиком попал в какое-то событие
|
150
|
+
# найдем его
|
151
|
+
# заодно поднимем вспомогательный флаг, который обработаем во view
|
152
|
+
mark_whole = false
|
153
|
+
if sevents.count == 0
|
154
|
+
sevents = [self.where(:area_id => area_id).where("created_at < ?", used_start_date).last]
|
155
|
+
mark_whole = true
|
156
|
+
# sevents.each do |se|
|
157
|
+
# Rails.logger.debug "\t\t\t #{used_start_date - se.created_at}"
|
158
|
+
# end
|
159
|
+
end
|
160
|
+
|
161
|
+
t = _calc_busy_time({
|
162
|
+
time_free: 0,
|
163
|
+
time_busy: 0,
|
164
|
+
ecoef: 0,
|
165
|
+
sevents: sevents,
|
166
|
+
start_date:used_start_date,
|
167
|
+
end_date:used_end_date
|
168
|
+
})
|
169
|
+
|
170
|
+
result[area_id] = {
|
171
|
+
time_free: t[:time_free],
|
172
|
+
time_busy: t[:time_busy],
|
173
|
+
ecoef: t[:ecoef],
|
174
|
+
# sevents: self.where(:area_id => area_id)
|
175
|
+
sevents: sevents
|
176
|
+
}
|
177
|
+
|
178
|
+
result[:average_value] = sprintf "%.2f%", result[area_id][:ecoef]*100
|
179
|
+
result[:comment] = "<abbr title='Период рассчёта коэф-та эффективности'>C #{used_start_date_str} по #{used_end_date_str}</abbr>"
|
180
|
+
result[:abbr] = 'Коэф-т эффективности площади за указанный период'
|
181
|
+
result[:title] = "Статистика - #{area.title}"
|
182
|
+
result[:graph] = _parse_for_js_graph(sevents)
|
183
|
+
|
184
|
+
if mark_whole
|
185
|
+
if t[:time_busy] == 0
|
186
|
+
t[:time_free] = used_end_date - used_start_date
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
result[:props] = [
|
191
|
+
{ tag: 'title', val: "#{area.title}" },
|
192
|
+
{ tag: 'atype', val: "Тип: #{area.atype_title}" },
|
193
|
+
# { tag: 'born_date', val: "Дата создания: #{area.created_at.in_time_zone('Moscow')}" },
|
194
|
+
{ tag: 'busy_time', val: "<abbr title='В указанный период'>Времени занята</abbr>: #{time_duration(t[:time_busy])}" },
|
195
|
+
{ tag: 'free_time', val: "<abbr title='В указанный период'>Времени свободна</abbr>: #{time_duration(t[:time_free])}" },
|
196
|
+
{ tag: 'all_time', val: "<abbr title='В указанный период'>Времени всего</abbr>: #{time_duration(t[:time_busy] + t[:time_free])}" },
|
197
|
+
{ tag: 'assigned_person_title', val: "Ответственный: #{area.assigned_person_title}" },
|
198
|
+
{ tag: 'property_title', val: "Объект: #{area.property_title}" }
|
199
|
+
]
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
result
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
def area_title
|
208
|
+
res = "-"
|
209
|
+
if area.present?
|
210
|
+
res = area.title
|
211
|
+
end
|
212
|
+
res
|
213
|
+
end
|
214
|
+
|
215
|
+
def atype_title
|
216
|
+
res = "-"
|
217
|
+
if atype.present?
|
218
|
+
res = atype.title
|
219
|
+
end
|
220
|
+
res
|
221
|
+
end
|
222
|
+
|
223
|
+
def property_title
|
224
|
+
res = "-"
|
225
|
+
if property.present?
|
226
|
+
res = property.title
|
227
|
+
end
|
228
|
+
res
|
229
|
+
end
|
230
|
+
|
231
|
+
def astatus_title
|
232
|
+
res = "-"
|
233
|
+
if astatus.present?
|
234
|
+
res = astatus.title
|
235
|
+
end
|
236
|
+
res
|
237
|
+
end
|
238
|
+
|
239
|
+
def auser_title
|
240
|
+
res = "-"
|
241
|
+
if auser.present?
|
242
|
+
res = auser.email
|
243
|
+
end
|
244
|
+
res
|
245
|
+
end
|
246
|
+
|
247
|
+
private
|
248
|
+
|
249
|
+
def self._calc_busy_time(a)
|
250
|
+
Rails.logger.debug "<Sevent._calc_busy_time> START ---"
|
251
|
+
# {
|
252
|
+
# time_free: 0,
|
253
|
+
# time_busy: 0,
|
254
|
+
# ecoef:0,
|
255
|
+
# sevents: [],
|
256
|
+
# start_date: '2016-12-12' или nil,
|
257
|
+
# end_date: '2016-12-12' или nil
|
258
|
+
# }
|
259
|
+
|
260
|
+
res = {
|
261
|
+
time_free: 0,
|
262
|
+
time_busy: 0,
|
263
|
+
ecoef: 0
|
264
|
+
}
|
265
|
+
|
266
|
+
# переберём area related sevents
|
267
|
+
a[:sevents].each_with_index do |sevent, index|
|
268
|
+
|
269
|
+
# если это первый элемент (т.е. до меня нет никого)
|
270
|
+
if index == 0
|
271
|
+
|
272
|
+
# если это единственный элемент
|
273
|
+
if a[:sevents].count == 1
|
274
|
+
|
275
|
+
# считаем его статус до текущего времени
|
276
|
+
res = _calc_busy_time_las(res,sevent,index,a[:end_date])
|
277
|
+
|
278
|
+
end
|
279
|
+
|
280
|
+
# если это последний элемент - то добавляем, сколько времени была площадь в последнем известном статусе ДО текущего момента
|
281
|
+
elsif index == a[:sevents].count - 1
|
282
|
+
# TODO_MY:: учитывать end_date и передавать соответствующий mark_calc_to_now
|
283
|
+
res = _calc_busy_time_las(res,sevent,index,a[:end_date])
|
284
|
+
|
285
|
+
# в случае массива из 2 элементов
|
286
|
+
if a[:sevents].count == 2
|
287
|
+
prev_sevent = a[:sevents][index-1]
|
288
|
+
res = _calc_busy_time_bef(res,sevent,prev_sevent,index)
|
289
|
+
end
|
290
|
+
|
291
|
+
# если перед элементом есть кто-то
|
292
|
+
else
|
293
|
+
prev_sevent = a[:sevents][index-1]
|
294
|
+
res = _calc_busy_time_bef(res,sevent,prev_sevent,index)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
res[:ecoef] = res[:time_busy] / (res[:time_busy] + res[:time_free])
|
299
|
+
Rails.logger.debug "<Sevent._calc_busy_time> END ---"
|
300
|
+
|
301
|
+
res
|
302
|
+
end
|
303
|
+
|
304
|
+
def self._calc_busy_time_las(res,sevent, index, end_date)
|
305
|
+
|
306
|
+
# TODO_MY:: добавить аргумент mark_to_now и фиксировать текущее время по условию
|
307
|
+
# TODO_MY:: или добавить обработчик end_date и учитывать его
|
308
|
+
# фиксируем текущее время
|
309
|
+
# tnow = Time.now
|
310
|
+
tnow = end_date
|
311
|
+
d = tnow - sevent.created_at
|
312
|
+
Rails.logger.debug "\t\t i=#{index}, last: #{sevent.astatus.tag}, dur: #{d}"
|
313
|
+
|
314
|
+
case sevent.astatus.tag
|
315
|
+
when 'free'
|
316
|
+
res[:time_free] += d
|
317
|
+
when 'busy'
|
318
|
+
res[:time_busy] += d
|
319
|
+
end
|
320
|
+
Rails.logger.debug "\t\t time_free=#{res[:time_free]}, time_busy = #{res[:time_busy]}"
|
321
|
+
res
|
322
|
+
end
|
323
|
+
|
324
|
+
def self._calc_busy_time_bef(res,sevent,prev_sevent,index)
|
325
|
+
|
326
|
+
# и считаем его длительность
|
327
|
+
d = sevent.created_at - prev_sevent.created_at
|
328
|
+
Rails.logger.debug "\t\t i=#{index}, prev_sevent: #{prev_sevent.astatus.tag}, dur: #{d}"
|
329
|
+
|
330
|
+
case prev_sevent.astatus.tag
|
331
|
+
when 'free'
|
332
|
+
res[:time_free] += d
|
333
|
+
when 'busy'
|
334
|
+
res[:time_busy] += d
|
335
|
+
end
|
336
|
+
Rails.logger.debug "\t\t time_free=#{res[:time_free]}, time_busy = #{res[:time_busy]}"
|
337
|
+
res
|
338
|
+
end
|
339
|
+
|
340
|
+
def self.time_duration(t)
|
341
|
+
mm, ss = t.divmod(60) #=> [4515, 21]
|
342
|
+
hh, mm = mm.divmod(60) #=> [75, 15]
|
343
|
+
dd, hh = hh.divmod(24) #=> [3, 3]
|
344
|
+
# puts "%d days, %d hours, %d minutes and %d seconds" % [dd, hh, mm, ss]
|
345
|
+
"%dд %dч %dмин % dс" % [dd,hh,mm,ss]
|
346
|
+
end
|
347
|
+
|
348
|
+
def self._parse_for_js_graph(sevents)
|
349
|
+
# res = [
|
350
|
+
# ['Year', 'Sales', 'Expenses'],
|
351
|
+
# ['2013', 1000, 400],
|
352
|
+
# ['2014', 1170, 460],
|
353
|
+
# ['2015', 660, 1120],
|
354
|
+
# ['2016/12/12', 1030, 540]
|
355
|
+
# ]
|
356
|
+
res = []
|
357
|
+
sevents.each do |sevent|
|
358
|
+
v = 0
|
359
|
+
if sevent.astatus.tag == 'free'
|
360
|
+
v = 1
|
361
|
+
end
|
362
|
+
res << [ sevent.created_at.strftime('%Y/%m/%d'), v ]
|
363
|
+
end
|
364
|
+
res
|
365
|
+
end
|
366
|
+
|
367
|
+
end
|
368
|
+
end
|