c80_estate 0.1.0.2 → 0.1.0.3
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/pstats.rb +37 -0
- data/app/admin/c80_estate/sevents.rb +3 -1
- data/app/assets/javascript/c80_estate/backend/admin/pstats.js +219 -0
- data/app/assets/stylesheets/c80_estate/backend/admin_pstats.scss +131 -0
- data/app/assets/stylesheets/c80_estate/backend/admin_sevents.scss +4 -0
- data/app/controllers/c80_estate/ajax_controller.rb +26 -1
- data/app/models/c80_estate/area.rb +88 -20
- data/app/models/c80_estate/atype.rb +2 -0
- data/app/models/c80_estate/property.rb +1 -0
- data/app/models/c80_estate/pstat.rb +289 -0
- data/app/models/c80_estate/sevent.rb +27 -0
- data/config/routes.rb +1 -0
- data/db/migrate/20160717094647_create_c80_estate_pstats.rb +17 -0
- data/lib/c80_estate/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 347ae43df7eb3ed899e9ae21f3a85648fff17baa
|
4
|
+
data.tar.gz: 38e409296f4dd3fb71867a38918da9c68823b678
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 858bcd250a2e8c33bbd56e5b28aa8c3849e9843392868a3433b53498cd3574dd7d5faccbd014f917816f6a918fc951e3533b02d0bebcaa4dc93c2fdacae44a22
|
7
|
+
data.tar.gz: 01a4d0cf2c9c6edf973f25c782ecbd1d09405592e206d8ee5dff257c86b22a010332947f266f1119c3d391ab211785bac73671530ebbec93a63c67ae19225ef3
|
@@ -0,0 +1,37 @@
|
|
1
|
+
ActiveAdmin.register C80Estate::Pstat, as: 'Pstat' do
|
2
|
+
|
3
|
+
# scope_to :current_admin_user, association_method: :sites_list
|
4
|
+
|
5
|
+
menu :label => "Объекты", :parent => 'Статистика'
|
6
|
+
|
7
|
+
config.sort_order = 'id_asc'
|
8
|
+
|
9
|
+
filter :property_id,
|
10
|
+
:as => :select,
|
11
|
+
:collection => -> { C80Estate::Property.all.map { |p| ["#{p.title}", p.id] } },
|
12
|
+
:input_html => {:class => 'selectpicker', 'data-size' => "10", 'data-width' => '100%'}
|
13
|
+
|
14
|
+
filter :atype_id,
|
15
|
+
:as => :select,
|
16
|
+
:collection => -> { C80Estate::Atype.all.map { |p| ["#{p.title}", p.id] } },
|
17
|
+
:input_html => {:class => 'selectpicker', 'data-size' => "10", 'data-width' => '100%'}
|
18
|
+
|
19
|
+
filter :created_at
|
20
|
+
|
21
|
+
index do
|
22
|
+
selectable_column
|
23
|
+
column :property do |ptype|
|
24
|
+
ptype.property_title
|
25
|
+
end
|
26
|
+
column :atype do |ptype|
|
27
|
+
ptype.atype_title
|
28
|
+
end
|
29
|
+
column :free_areas
|
30
|
+
column :busy_areas
|
31
|
+
column :coef_busy
|
32
|
+
column :coef_busy_sq
|
33
|
+
column :created_at
|
34
|
+
actions
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -19,7 +19,9 @@ ActiveAdmin.register C80Estate::Sevent, as: 'Sevent' do
|
|
19
19
|
# :input_html => {:class => 'selectpicker', 'data-size' => "10", 'data-width' => '100%'}
|
20
20
|
filter :area_id,
|
21
21
|
:as => :select,
|
22
|
-
:collection => -> { C80Estate::Area.all.map { |
|
22
|
+
:collection => -> { C80Estate::Area.all.map { |a|
|
23
|
+
["#{a.property.title}: #{a.title}", a.id]
|
24
|
+
} },
|
23
25
|
:input_html => {:class => 'selectpicker', 'data-size' => "10", 'data-width' => '100%'}
|
24
26
|
# filter :atype_id,
|
25
27
|
# :as => :select,
|
@@ -0,0 +1,219 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var fPstatsIndex = function () {
|
4
|
+
|
5
|
+
// элементы html страницы
|
6
|
+
var $main_content; // правая сторона, там живёт таблица
|
7
|
+
var $select_atype; // фильтр atype
|
8
|
+
var $select_property; // фильтр property
|
9
|
+
var $input_start_date; // фильтр "дата начала периода"
|
10
|
+
var $input_end_date; // фильтр "дата конца периода"
|
11
|
+
var $h2_page_title; // заголовок страницы
|
12
|
+
|
13
|
+
// компонент "над таблицей"
|
14
|
+
var $div_index_adds;
|
15
|
+
var $div_busy_coef;
|
16
|
+
var $p_busy_coef; // здесь выводим число - коэф-т эффективности
|
17
|
+
var $p_ecoef_mess; // здесь вешаем hint на подпись "эффективность"
|
18
|
+
var $p_ecoef_comment; // здесь выводим комментарий
|
19
|
+
var $div_area_text_stats;
|
20
|
+
var $ul_props; // здесь выводим текстовые свойства
|
21
|
+
var $div_graph; // в этом div живет график
|
22
|
+
var $div_graph2; // в этом div живет график
|
23
|
+
|
24
|
+
var fBuild = function () {
|
25
|
+
|
26
|
+
// зафиксируем html элементы
|
27
|
+
$main_content = $('#main_content');
|
28
|
+
$select_atype = $("#q_atype_id");
|
29
|
+
$select_property = $("#q_property_id");
|
30
|
+
$input_start_date = $("#q_created_at_gteq");
|
31
|
+
$input_end_date = $("#q_created_at_lteq");
|
32
|
+
$h2_page_title = $("h2#page_title");
|
33
|
+
|
34
|
+
// построим компонент "над таблицей"
|
35
|
+
$div_index_adds = $("<div id='index_adds'></div>");
|
36
|
+
|
37
|
+
$div_busy_coef = $("<div id='coef'></div>");
|
38
|
+
$p_busy_coef = $("<p class='val'></p>");
|
39
|
+
$p_ecoef_mess = $("<p class='title'><abbr class='abbr_ecoef' title='TITLE'>Занятость</abbr></p>");
|
40
|
+
$p_ecoef_comment = $("<p class='comment'></p>");
|
41
|
+
|
42
|
+
$div_busy_coef.append($p_busy_coef);
|
43
|
+
$div_busy_coef.append($p_ecoef_mess);
|
44
|
+
$div_busy_coef.append($p_ecoef_comment);
|
45
|
+
|
46
|
+
$div_area_text_stats = $("<div id='text_stats'></div>");
|
47
|
+
$ul_props = $("<ul><li id='title'></li><li id='born_date'></li><li id='atype_filter'></li><li id='all_areas_count'></li><li id='free_areas_count'></li><li id='busy_areas_count'></li></ul>");
|
48
|
+
$div_area_text_stats.append($ul_props);
|
49
|
+
|
50
|
+
$div_graph = $("<div id='graph'></div>");
|
51
|
+
$div_graph2 = $("<div id='graph2'></div>");
|
52
|
+
|
53
|
+
$div_index_adds.append($div_busy_coef);
|
54
|
+
$div_index_adds.append($div_area_text_stats);
|
55
|
+
$div_index_adds.append($div_graph);
|
56
|
+
$div_index_adds.append($div_graph2);
|
57
|
+
|
58
|
+
$main_content.prepend($div_index_adds);
|
59
|
+
|
60
|
+
// теперь покажем
|
61
|
+
$main_content.css('opacity', '1.0');
|
62
|
+
};
|
63
|
+
|
64
|
+
var fRequest = function () {
|
65
|
+
|
66
|
+
var atype_id = $select_atype.val();
|
67
|
+
var property_id = $select_property.val();
|
68
|
+
var start_date = $input_start_date.val();
|
69
|
+
var end_date = $input_end_date.val();
|
70
|
+
|
71
|
+
$.ajax({
|
72
|
+
url: '/estate/properties_busy_coef',
|
73
|
+
type: 'POST',
|
74
|
+
dataType: 'json',
|
75
|
+
data: {
|
76
|
+
atype_id: atype_id,
|
77
|
+
prop_id: property_id,
|
78
|
+
start_date: start_date,
|
79
|
+
end_date: end_date
|
80
|
+
}
|
81
|
+
}).done(function (data, result) {
|
82
|
+
if (result == 'success') {
|
83
|
+
console.log(data);
|
84
|
+
|
85
|
+
$p_busy_coef.text(data["busy_coef"]);
|
86
|
+
$p_ecoef_comment.html(data["comment"]);
|
87
|
+
$p_ecoef_mess.find('.abbr_ecoef').attr('title', data["abbr"]);
|
88
|
+
|
89
|
+
if (data["props"] != undefined) {
|
90
|
+
|
91
|
+
var i, iob, itag, ival, $ili;
|
92
|
+
for (i = 0; i < data["props"].length; i++) {
|
93
|
+
iob = data["props"][i];
|
94
|
+
itag = iob["tag"];
|
95
|
+
ival = iob["val"];
|
96
|
+
$ili = $ul_props.find("#" + itag);
|
97
|
+
$ili.html(ival);
|
98
|
+
}
|
99
|
+
|
100
|
+
}
|
101
|
+
|
102
|
+
if (data["graph"] != undefined) {
|
103
|
+
fDrawChart(data["graph"], data["graph_dynamic"]);
|
104
|
+
}
|
105
|
+
|
106
|
+
$h2_page_title.text(data["title"]);
|
107
|
+
$h2_page_title.css('opacity', '1.0');
|
108
|
+
$(document).attr('title', data["title"]);
|
109
|
+
|
110
|
+
} else {
|
111
|
+
alert('fail: /estate/properties_busy_coef');
|
112
|
+
}
|
113
|
+
//fPreloaderHide();
|
114
|
+
});
|
115
|
+
|
116
|
+
//fPreloaderShow();
|
117
|
+
};
|
118
|
+
|
119
|
+
var fInit = function () {
|
120
|
+
fBuild();
|
121
|
+
fRequest();
|
122
|
+
};
|
123
|
+
|
124
|
+
var fDrawChart = function (data_array_rows_radial, data_array_rows_dynamic) {
|
125
|
+
|
126
|
+
google.charts.load('current', {'packages': ['corechart']});
|
127
|
+
google.charts.setOnLoadCallback(drawChart);
|
128
|
+
|
129
|
+
function drawChart() {
|
130
|
+
|
131
|
+
var data, options, chart;
|
132
|
+
|
133
|
+
if (data_array_rows_radial != undefined) {
|
134
|
+
data = google.visualization.arrayToDataTable(data_array_rows_radial);
|
135
|
+
|
136
|
+
options = {
|
137
|
+
title: ''
|
138
|
+
};
|
139
|
+
|
140
|
+
chart = new google.visualization.PieChart(document.getElementById('graph'));
|
141
|
+
|
142
|
+
chart.draw(data, options);
|
143
|
+
}
|
144
|
+
|
145
|
+
if (data_array_rows_dynamic != undefined) {
|
146
|
+
//data_array = [
|
147
|
+
// ['Director (Year)', 'Rotten Tomatoes', 'IMDB'],
|
148
|
+
// ['Alfred Hitchcock (1935)', 8.4, 7.9],
|
149
|
+
// ['Ralph Thomas (1959)', 6.9, 6.5],
|
150
|
+
// ['Don Sharp (1978)', 6.5, 6.4],
|
151
|
+
// ['James Hawes (2008)', 4.4, 6.2]
|
152
|
+
//]
|
153
|
+
|
154
|
+
//var data = google.visualization.arrayToDataTable(data_array_rows_dynamic);
|
155
|
+
|
156
|
+
data = new google.visualization.DataTable();
|
157
|
+
data.addColumn('date', ''); // Implicit domain column.
|
158
|
+
data.addColumn('number', ''); // Implicit data column.
|
159
|
+
//data.addColumn({type:'number', role:'interval'});
|
160
|
+
//data.addColumn({type:'number', role:'interval'});
|
161
|
+
//data.addColumn('number', 'Expenses');
|
162
|
+
|
163
|
+
var i, iob, yearValue, monthValue, dayValue;
|
164
|
+
for (i = 0; i < data_array_rows_dynamic.length; i++) {
|
165
|
+
iob = data_array_rows_dynamic[i];
|
166
|
+
yearValue = iob[0].substr(0, 4);
|
167
|
+
monthValue = iob[0].substr(5, 2) - 1;
|
168
|
+
dayValue = iob[0].substr(8, 2);
|
169
|
+
console.log(iob + " => " + yearValue + "/" + monthValue + "/" + dayValue); // + ": " + data_array_rows_dynamic[i][0]
|
170
|
+
data_array_rows_dynamic[i][0] = new Date(parseInt(yearValue), parseInt(monthValue), parseInt(dayValue));
|
171
|
+
}
|
172
|
+
|
173
|
+
data.addRows(data_array_rows_dynamic);
|
174
|
+
|
175
|
+
options = {
|
176
|
+
title: 'Занятость',
|
177
|
+
vAxis: {title: '', ticks: [0, 1]},
|
178
|
+
ignoreBounds: true,
|
179
|
+
isStacked: false
|
180
|
+
};
|
181
|
+
|
182
|
+
chart = new google.visualization.SteppedAreaChart(document.getElementById('graph2'));
|
183
|
+
|
184
|
+
chart.draw(data, options);
|
185
|
+
}
|
186
|
+
|
187
|
+
}
|
188
|
+
|
189
|
+
if (data_array_rows_radial != undefined) {
|
190
|
+
$('#graph').css('opacity', '1.0').css('display', 'block');
|
191
|
+
}
|
192
|
+
|
193
|
+
if (data_array_rows_dynamic != undefined) {
|
194
|
+
$('#graph2').css('opacity', '1.0').css('display', 'block');
|
195
|
+
}
|
196
|
+
|
197
|
+
};
|
198
|
+
|
199
|
+
fInit();
|
200
|
+
|
201
|
+
};
|
202
|
+
|
203
|
+
var fPstatsEdit = function () {
|
204
|
+
|
205
|
+
alert("edit");
|
206
|
+
|
207
|
+
};
|
208
|
+
|
209
|
+
var fPstatsNew = function () {
|
210
|
+
|
211
|
+
alert("new");
|
212
|
+
|
213
|
+
};
|
214
|
+
|
215
|
+
YOUR_APP.pstats = {
|
216
|
+
edit: fPstatsEdit,
|
217
|
+
"new": fPstatsNew,
|
218
|
+
index: fPstatsIndex
|
219
|
+
};
|
@@ -0,0 +1,131 @@
|
|
1
|
+
body.admin_pstats {
|
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
|
+
&#coef {
|
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
|
+
&#graph2 {
|
75
|
+
width: 100%;
|
76
|
+
margin-top: 15px;
|
77
|
+
padding: 0;
|
78
|
+
display: none;
|
79
|
+
opacity: 0;
|
80
|
+
|
81
|
+
-webkit-transition: opacity .2s ease-in;
|
82
|
+
-moz-transition: opacity .2s ease-in;
|
83
|
+
-ms-transition: opacity .2s ease-in;
|
84
|
+
-o-transition: opacity .2s ease-in;
|
85
|
+
transition: opacity .2s ease-in;
|
86
|
+
|
87
|
+
}
|
88
|
+
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
}
|
93
|
+
|
94
|
+
.batch_actions_selector {
|
95
|
+
display: none;
|
96
|
+
}
|
97
|
+
|
98
|
+
.action_items {
|
99
|
+
display: none;
|
100
|
+
}
|
101
|
+
|
102
|
+
a.delete_link {
|
103
|
+
display: none;
|
104
|
+
}
|
105
|
+
|
106
|
+
.col-actions {
|
107
|
+
text-align: right;
|
108
|
+
width: 99px !important;
|
109
|
+
}
|
110
|
+
|
111
|
+
a.edit_link {
|
112
|
+
display: none;
|
113
|
+
}
|
114
|
+
|
115
|
+
h2#page_title {
|
116
|
+
opacity: 0;
|
117
|
+
|
118
|
+
-webkit-transition: opacity .2s ease-in;
|
119
|
+
-moz-transition: opacity .2s ease-in;
|
120
|
+
-ms-transition: opacity .2s ease-in;
|
121
|
+
-o-transition: opacity .2s ease-in;
|
122
|
+
transition: opacity .2s ease-in;
|
123
|
+
}
|
124
|
+
|
125
|
+
div.blank_slate_container {
|
126
|
+
display: none !important;
|
127
|
+
}
|
128
|
+
|
129
|
+
}
|
130
|
+
|
131
|
+
}
|
@@ -16,16 +16,41 @@ module C80Estate
|
|
16
16
|
def areas_ecoef
|
17
17
|
|
18
18
|
area_id = request.params[:area_id] == "" ? nil:request.params[:area_id]
|
19
|
+
atype_id = request.params[:atype_id] == "" ? nil:request.params[:atype_id]
|
19
20
|
start_date = request.params[:start_date] == "" ? nil:request.params[:start_date]
|
20
21
|
end_date = request.params[:end_date] == "" ? nil:request.params[:end_date]
|
21
22
|
|
22
|
-
obj = Sevent.ecoef(area_id: area_id,
|
23
|
+
obj = Sevent.ecoef(area_id: area_id,
|
24
|
+
start_date: start_date,
|
25
|
+
end_date: end_date,
|
26
|
+
atype_id: atype_id
|
27
|
+
)
|
23
28
|
|
24
29
|
respond_to do |format|
|
25
30
|
format.js { render json: obj, status: :ok }
|
26
31
|
# format.json
|
27
32
|
end
|
28
33
|
end
|
34
|
+
|
35
|
+
def properties_busy_coef
|
36
|
+
|
37
|
+
prop_id = request.params[:prop_id] == "" ? nil:request.params[:prop_id]
|
38
|
+
start_date = request.params[:start_date] == "" ? nil:request.params[:start_date]
|
39
|
+
atype_id = request.params[:atype_id] == "" ? nil:request.params[:atype_id]
|
40
|
+
end_date = request.params[:end_date] == "" ? nil:request.params[:end_date]
|
41
|
+
|
42
|
+
obj = Pstat.busy_coef(prop_id: prop_id,
|
43
|
+
start_date: start_date,
|
44
|
+
end_date: end_date,
|
45
|
+
atype_id: atype_id
|
46
|
+
)
|
47
|
+
|
48
|
+
respond_to do |format|
|
49
|
+
format.js { render json: obj, status: :ok }
|
50
|
+
# format.json
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
29
54
|
|
30
55
|
end
|
31
56
|
end
|
@@ -37,10 +37,20 @@ module C80Estate
|
|
37
37
|
self.joins(:astatuses).where(:c80_estate_astatuses => { tag: 'free'})
|
38
38
|
end
|
39
39
|
|
40
|
+
# посчитает кол-во свободных метров
|
41
|
+
def self.free_areas_sq
|
42
|
+
1
|
43
|
+
end
|
44
|
+
|
40
45
|
def self.busy_areas
|
41
46
|
self.joins(:astatuses).where(:c80_estate_astatuses => { tag: 'busy'})
|
42
47
|
end
|
43
48
|
|
49
|
+
# посчитает кол-во занятых метров
|
50
|
+
def self.busy_areas_sq
|
51
|
+
1
|
52
|
+
end
|
53
|
+
|
44
54
|
def atype_title
|
45
55
|
res = "-"
|
46
56
|
if atype.present?
|
@@ -93,37 +103,95 @@ module C80Estate
|
|
93
103
|
|
94
104
|
# при создании площади генерится начальное событие
|
95
105
|
def create_initial_sevent
|
96
|
-
Rails.logger.debug "<Area.create_initial_sevent>"
|
106
|
+
Rails.logger.debug "<Area.create_initial_sevent> self.astatuses.count = #{self.astatuses.count}"
|
107
|
+
|
108
|
+
# [**]
|
109
|
+
if self.astatuses.count > 0
|
110
|
+
Rails.logger.debug "<Area.create_initial_sevent> aga: self.astatuses.first.title = #{self.astatuses.first.title}"
|
111
|
+
|
112
|
+
s = Sevent.create!({
|
113
|
+
area_id: self.id,
|
114
|
+
atype_id: self.atype_id,
|
115
|
+
property_id: self.property_id,
|
116
|
+
astatus_id: self.astatus_id,
|
117
|
+
auser_id: self.owner_id, # инициатор события - создатель Площади
|
118
|
+
auser_type: 'AdminUser',
|
119
|
+
created_at: self.created_at
|
120
|
+
})
|
97
121
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
122
|
+
# см [*]
|
123
|
+
# if last_known_sevent == ''
|
124
|
+
# pparams[:created_at] = self.created_at
|
125
|
+
# end
|
126
|
+
#
|
127
|
+
# pparams = {
|
128
|
+
# atype_id: nil,
|
129
|
+
# property_id: self.property_id,
|
130
|
+
# sevent_id: s.id
|
131
|
+
# }
|
132
|
+
|
133
|
+
# генерим запись с общими данными
|
134
|
+
# связываем её с Sevent
|
135
|
+
# чтобы можно было удалить как dependent => destroy
|
136
|
+
# Pstat.create!(pparams)
|
137
|
+
|
138
|
+
end
|
106
139
|
|
107
140
|
end
|
108
141
|
|
109
142
|
def check_and_generate_sevent
|
110
|
-
Rails.logger.debug "<Area.check_and_generate_sevent>"
|
111
143
|
|
112
144
|
# находим последнее известное событие
|
113
145
|
# фиксируем его статус
|
114
|
-
last_known_sevent =
|
146
|
+
last_known_sevent = ""
|
147
|
+
if self.sevents.count > 0
|
148
|
+
last_known_sevent = self.sevents.last.astatus.tag
|
149
|
+
end
|
115
150
|
|
116
151
|
# если статус этого события отличен
|
117
|
-
# от нового статуса - генерим
|
152
|
+
# от нового статуса - генерим события
|
153
|
+
Rails.logger.debug "<Area.check_and_generate_sevent> last_known_sevent = #{last_known_sevent}, self.astatuses.first.tag = #{self.astatuses.first.tag}"
|
154
|
+
|
118
155
|
if last_known_sevent != self.astatuses.first.tag
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
156
|
+
Rails.logger.debug "<Area.check_and_generate_sevent> aga"
|
157
|
+
sparams = {
|
158
|
+
area_id: self.id,
|
159
|
+
atype_id: self.atype_id,
|
160
|
+
property_id: self.property_id,
|
161
|
+
astatus_id: self.astatus_id,
|
162
|
+
auser_id: self.owner_id, # инициатор события - редактор Площади
|
163
|
+
auser_type: 'AdminUser'
|
164
|
+
}
|
165
|
+
|
166
|
+
# если неизвестен статус последнего события,
|
167
|
+
# значит событий изменения статуса площади ещё не было
|
168
|
+
# значит нужно создать первое событие и дату его создания
|
169
|
+
# приравнять дате создания площади [*]
|
170
|
+
# такая штука случается, когда заполняем данными из seed файла,
|
171
|
+
# и при создании не получилось фишка с передачей :astatus_ids => [1] в create!({..})
|
172
|
+
# по-этому и появился этот код. Также по теме код из [**]
|
173
|
+
if last_known_sevent == ''
|
174
|
+
sparams[:created_at] = self.created_at
|
175
|
+
end
|
176
|
+
|
177
|
+
s = Sevent.create!(sparams)
|
178
|
+
|
179
|
+
pparams = {
|
180
|
+
atype_id: nil,
|
181
|
+
property_id: self.property_id,
|
182
|
+
sevent_id: s.id
|
183
|
+
}
|
184
|
+
|
185
|
+
# см [*]
|
186
|
+
if last_known_sevent == ''
|
187
|
+
pparams[:created_at] = self.created_at
|
188
|
+
end
|
189
|
+
|
190
|
+
# генерим запись с общими данными
|
191
|
+
# связываем её с Sevent
|
192
|
+
# чтобы можно было удалить как dependent => destroy
|
193
|
+
Pstat.create!(pparams)
|
194
|
+
|
127
195
|
end
|
128
196
|
|
129
197
|
end
|
@@ -0,0 +1,289 @@
|
|
1
|
+
module C80Estate
|
2
|
+
class Pstat < ActiveRecord::Base
|
3
|
+
|
4
|
+
belongs_to :property
|
5
|
+
belongs_to :atype
|
6
|
+
belongs_to :sevent
|
7
|
+
|
8
|
+
# nil, если это запись с общими данными, а не astatus related запись
|
9
|
+
# (добавлена только для того, чтобы можно было :dependend => :destroy)
|
10
|
+
belongs_to :parent, :class_name => 'C80Estate::Pstat'
|
11
|
+
has_many :pstats, :foreign_key => 'parent_id', :dependent => :destroy
|
12
|
+
|
13
|
+
# рассчитаем коэф-ты занятости
|
14
|
+
before_create :calc_busy_coefs
|
15
|
+
|
16
|
+
# сгенерим atype related записи
|
17
|
+
after_create :generate_atype_pstats
|
18
|
+
|
19
|
+
def self.busy_coef(prop_id: nil, atype_id: nil, start_date: nil, end_date: nil)
|
20
|
+
# start_date: строка вида 2015-12-12
|
21
|
+
|
22
|
+
result = {}
|
23
|
+
|
24
|
+
# если ничего не подано - просто выберем все занятые площади и поделим на все известные площади
|
25
|
+
if prop_id.nil? && atype_id.nil? && start_date.nil? && end_date.nil?
|
26
|
+
|
27
|
+
all_areas_count = Area.all.count
|
28
|
+
free_areas_count = Area.free_areas.count
|
29
|
+
busy_areas_count = Area.busy_areas.count
|
30
|
+
|
31
|
+
ddd = '-'
|
32
|
+
if self.count > 0
|
33
|
+
ddd = Time.at(self.first.created_at).strftime('%Y/%m/%d')
|
34
|
+
end
|
35
|
+
|
36
|
+
result[:busy_coef] = sprintf "%.2f%", busy_areas_count*1.0/all_areas_count*100.0
|
37
|
+
result[:comment] = "<abbr title='Период рассчёта занятости: с момента самого первого известного события до текущего дня'>C #{ddd} по #{Time.now.year}/#{sprintf "%02d", Time.now.month}/#{sprintf "%02d", Time.now.day}</abbr>"
|
38
|
+
result[:abbr] = 'Показана занятость для всех площадей всех объектов недвижимости за весь период'
|
39
|
+
result[:title] = 'Статистика - Все объекты недвижимости'
|
40
|
+
result[:props] = [
|
41
|
+
{tag: 'all_areas_count', val: "Площадей всего: #{all_areas_count}"},
|
42
|
+
{tag: 'free_areas_count', val: "Площадей свободно: #{free_areas_count}"},
|
43
|
+
{tag: 'busy_areas_count', val: "Площадей занято: #{busy_areas_count}"}
|
44
|
+
]
|
45
|
+
|
46
|
+
Rails.logger.debug "<Pstat.busy_coef> busy_areas_count = #{ busy_areas_count }"
|
47
|
+
Rails.logger.debug "<Pstat.busy_coef> all_areas_count = #{ all_areas_count }"
|
48
|
+
Rails.logger.debug "<Pstat.busy_coef> result[:busy_coef] = #{ result[:busy_coef] }"
|
49
|
+
|
50
|
+
# если фильтруем по property
|
51
|
+
elsif prop_id.present?
|
52
|
+
|
53
|
+
# фиксируем property
|
54
|
+
property = Property.find(prop_id)
|
55
|
+
|
56
|
+
# работаем с ней, если только есть площади
|
57
|
+
if property.areas.count > 0
|
58
|
+
|
59
|
+
# обозначим диапазон фильтрации
|
60
|
+
area_created_at = Time.at(property.areas.first.created_at)
|
61
|
+
time_now = Time.now
|
62
|
+
# Rails.logger.debug("area_created_at = #{area_created_at}")
|
63
|
+
# Rails.logger.debug("time_now = #{time_now}")
|
64
|
+
|
65
|
+
# если подана нижняя граница диапазона и она позже, чем время создания самой первой площади объекта,
|
66
|
+
# выравниваем период рассчета коэф-та по этой нижней границе диапазона
|
67
|
+
if start_date.present?
|
68
|
+
start_date_tt = Time.parse(start_date)
|
69
|
+
if start_date_tt > area_created_at
|
70
|
+
used_start_date = start_date_tt
|
71
|
+
# Rails.logger.debug("start_date: используем аргумент: #{start_date_tt}")
|
72
|
+
else
|
73
|
+
used_start_date = area_created_at
|
74
|
+
# Rails.logger.debug("start_date: используем время рождения Площади: #{area_created_at}")
|
75
|
+
end
|
76
|
+
else
|
77
|
+
used_start_date = area_created_at
|
78
|
+
# Rails.logger.debug("start_date: используем время рождения Площади: #{area_created_at}")
|
79
|
+
end
|
80
|
+
used_start_date_str = used_start_date.strftime('%Y/%m/%d')
|
81
|
+
|
82
|
+
if end_date.present?
|
83
|
+
end_date_tt = Time.parse(end_date)
|
84
|
+
if end_date < time_now
|
85
|
+
used_end_date = end_date_tt
|
86
|
+
Rails.logger.debug("end_date: используем аргумент: #{end_date_tt}")
|
87
|
+
else
|
88
|
+
used_end_date = time_now
|
89
|
+
Rails.logger.debug("end_date: используем текущее время")
|
90
|
+
end
|
91
|
+
else
|
92
|
+
used_end_date = time_now
|
93
|
+
Rails.logger.debug("end_date: используем текущее время")
|
94
|
+
end
|
95
|
+
used_end_date_str = used_end_date.strftime('%Y/%m/%d')
|
96
|
+
|
97
|
+
# Rails.logger.debug("start_date = #{start_date}; end_date = #{end_date}; used_start_date = #{used_start_date}; used_end_date = #{used_end_date}")
|
98
|
+
# sevents = self.where(:area_id => area_id).where(:created_at => used_start_date..used_end_date)
|
99
|
+
pstats = self.where(:property_id => prop_id)
|
100
|
+
.where("created_at BETWEEN ? AND ?", used_start_date, used_end_date)
|
101
|
+
|
102
|
+
if atype_id.present?
|
103
|
+
pstats = pstats.where(:atype_id => atype_id)
|
104
|
+
end
|
105
|
+
|
106
|
+
# если в этот промежуток небыло событий - значит промежуток целиком попал в какое-то событие
|
107
|
+
# найдем его
|
108
|
+
# заодно поднимем вспомогательный флаг, который обработаем во view
|
109
|
+
mark_whole = false
|
110
|
+
if pstats.count == 0
|
111
|
+
pstats = [self.where(:property_id => prop_id).where("created_at < ?", used_start_date).last]
|
112
|
+
mark_whole = true
|
113
|
+
# sevents.each do |se|
|
114
|
+
# Rails.logger.debug "\t\t\t #{used_start_date - se.created_at}"
|
115
|
+
# end
|
116
|
+
end
|
117
|
+
|
118
|
+
# если сортируем по типу, то берём последнюю запись,
|
119
|
+
# иначе - берём последнюю запись с общими данными
|
120
|
+
if atype_id.nil?
|
121
|
+
free_areas_atnow = pstats.where(:atype_id => nil).last.free_areas
|
122
|
+
busy_areas_atnow = pstats.where(:atype_id => nil).last.busy_areas
|
123
|
+
else
|
124
|
+
free_areas_atnow = pstats.last.free_areas
|
125
|
+
busy_areas_atnow = pstats.last.busy_areas
|
126
|
+
end
|
127
|
+
|
128
|
+
Rails.logger.debug("\t\t atype_id = #{atype_id}")
|
129
|
+
Rails.logger.debug("\t\t free_areas_atnow = #{free_areas_atnow}")
|
130
|
+
Rails.logger.debug("\t\t busy_areas_atnow = #{busy_areas_atnow}")
|
131
|
+
|
132
|
+
# защищаемся от деления на ноль
|
133
|
+
if free_areas_atnow + busy_areas_atnow == 0
|
134
|
+
bcoef = 0.0
|
135
|
+
else
|
136
|
+
bcoef = busy_areas_atnow*1.0 / (free_areas_atnow + busy_areas_atnow) * 100.0
|
137
|
+
end
|
138
|
+
|
139
|
+
result[:busy_coef] = sprintf "%.2f%", bcoef
|
140
|
+
result[:comment] = "<abbr title='Период рассчёта занятости'>C #{used_start_date_str} по #{used_end_date_str}</abbr>"
|
141
|
+
result[:abbr] = 'Занятость объекта за указанный период'
|
142
|
+
result[:title] = "Статистика - Объект - #{property.title}"
|
143
|
+
result[:graph] = _parse_for_js_radial_graph(free_areas_atnow,busy_areas_atnow)
|
144
|
+
result[:graph_dynamic] = _parse_for_js_dynamic_graph(pstats)
|
145
|
+
|
146
|
+
# if atype_id.present?
|
147
|
+
# result[:title] += " (#{Atype.find(atype_id).title})"
|
148
|
+
# end
|
149
|
+
|
150
|
+
dc_str = property.areas.first.created_at.in_time_zone('Moscow').strftime('%Y/%m/%d')
|
151
|
+
dc_abbr = 'За дату создания объекта недвижимости при рассчетах берётся дата создания первой площади объекта'
|
152
|
+
|
153
|
+
result[:props] = [
|
154
|
+
{tag: 'title', val: "#{property.title}"},
|
155
|
+
{tag: 'born_date', val: "<abbr title='#{dc_abbr}'>Дата создания: #{dc_str}"},
|
156
|
+
{tag: 'all_areas_count', val: "<abbr title='В конце указанного периода'>Площадей всего</abbr>: #{ free_areas_atnow + busy_areas_atnow }"},
|
157
|
+
{tag: 'free_areas_count', val: "<abbr title='В конце указанного периода'>Свободных площадей</abbr>: #{ free_areas_atnow }"},
|
158
|
+
{tag: 'busy_areas_count', val: "<abbr title='В конце указанного периода'>Занятых площадей</abbr>: #{ busy_areas_atnow }"}
|
159
|
+
]
|
160
|
+
|
161
|
+
if atype_id.present?
|
162
|
+
result[:props] << {tag: 'atype_filter', val: "Фильтр по типу площади: #{ Atype.find(atype_id).title }"}
|
163
|
+
end
|
164
|
+
|
165
|
+
else
|
166
|
+
result[:props] = [
|
167
|
+
{tag: 'title', val: "#{property.title} не имеет площадей"}
|
168
|
+
]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
result
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
def atype_title
|
177
|
+
res = "-"
|
178
|
+
if atype.present?
|
179
|
+
res = atype.title
|
180
|
+
end
|
181
|
+
res
|
182
|
+
end
|
183
|
+
|
184
|
+
def property_title
|
185
|
+
res = "-"
|
186
|
+
if property.present?
|
187
|
+
res = property.title
|
188
|
+
end
|
189
|
+
res
|
190
|
+
end
|
191
|
+
|
192
|
+
private
|
193
|
+
|
194
|
+
# Когда создаётся запись, посчитаем коэф-ты
|
195
|
+
def calc_busy_coefs
|
196
|
+
if self.property.areas.count > 0
|
197
|
+
|
198
|
+
# здесь считаем коэф-ты только для `записей с общими данными`
|
199
|
+
if self.atype.nil?
|
200
|
+
|
201
|
+
self.free_areas = self.property.areas.free_areas.count
|
202
|
+
self.busy_areas = self.property.areas.busy_areas.count
|
203
|
+
self.coef_busy = self.busy_areas / (self.free_areas + self.busy_areas) * 100
|
204
|
+
|
205
|
+
self.free_areas_sq = self.property.areas.free_areas_sq
|
206
|
+
self.busy_areas_sq = self.property.areas.busy_areas_sq
|
207
|
+
self.coef_busy_sq = self.busy_areas_sq / (self.free_areas_sq + self.busy_areas_sq) * 100
|
208
|
+
|
209
|
+
# здесь считаем коэф-ты для 'atype related записей'
|
210
|
+
else
|
211
|
+
self.free_areas = self.property.areas.where(:atype_id => self.atype.id).free_areas.count
|
212
|
+
self.busy_areas = self.property.areas.where(:atype_id => self.atype.id).busy_areas.count
|
213
|
+
self.coef_busy = (self.free_areas + self.busy_areas == 0) ? 0:self.busy_areas / (self.free_areas + self.busy_areas) * 100
|
214
|
+
|
215
|
+
self.free_areas_sq = self.property.areas.where(:atype_id => self.atype.id).free_areas_sq
|
216
|
+
self.busy_areas_sq = self.property.areas.where(:atype_id => self.atype.id).busy_areas_sq
|
217
|
+
self.coef_busy_sq = (self.free_areas_sq + self.busy_areas_sq == 0) ? 0:self.busy_areas_sq / (self.free_areas_sq + self.busy_areas_sq) * 100
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# Когда создаётся `запись с общими данными` в таблице 'pstats', автоматически
|
223
|
+
# создаются `atype related записи` в кол-ве N шт с данными по каждому типу площади
|
224
|
+
# с такой же датой created_at
|
225
|
+
def generate_atype_pstats
|
226
|
+
|
227
|
+
# генерим только для `записей с общими данными`
|
228
|
+
if self.atype.nil?
|
229
|
+
|
230
|
+
# перебираем все типы
|
231
|
+
atypes = Atype.all
|
232
|
+
atypes.each do |atype|
|
233
|
+
|
234
|
+
# генерим atype related pstats, связываем их с Родителем
|
235
|
+
Pstat.create!({
|
236
|
+
atype_id: atype.id,
|
237
|
+
property_id: self.property.id,
|
238
|
+
sevent_id: self.sevent.id,
|
239
|
+
created_at: self.created_at,
|
240
|
+
parent_id: self.id
|
241
|
+
})
|
242
|
+
|
243
|
+
end
|
244
|
+
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def self._parse_for_js_radial_graph(free_areas_atnow, busy_areas_atnow)
|
249
|
+
# res = [
|
250
|
+
# ['Year', 'Sales', 'Expenses'],
|
251
|
+
# ['2013', 1000, 400],
|
252
|
+
# ['2014', 1170, 460],
|
253
|
+
# ['2015', 660, 1120],
|
254
|
+
# ['2016/12/12', 1030, 540]
|
255
|
+
#
|
256
|
+
# ]
|
257
|
+
# [
|
258
|
+
# ['', ''],
|
259
|
+
# ['Свободно', 11],
|
260
|
+
# ['Занято', 2]
|
261
|
+
# ]
|
262
|
+
|
263
|
+
res = [['','']]
|
264
|
+
res << ['Свободно', free_areas_atnow]
|
265
|
+
res << ['Занято', busy_areas_atnow]
|
266
|
+
Rails.logger.debug "<_parse_for_js_radial_graph> res: #{res}"
|
267
|
+
res
|
268
|
+
|
269
|
+
end
|
270
|
+
|
271
|
+
def self._parse_for_js_dynamic_graph(pstats)
|
272
|
+
# res = [
|
273
|
+
# ['Year', 'Sales', 'Expenses'],
|
274
|
+
# ['2013', 1000, 400],
|
275
|
+
# ['2014', 1170, 460],
|
276
|
+
# ['2015', 660, 1120],
|
277
|
+
# ['2016/12/12', 1030, 540]
|
278
|
+
# ]
|
279
|
+
|
280
|
+
res = []
|
281
|
+
pstats.each do |pstat|
|
282
|
+
res << [ pstat.created_at.strftime('%Y/%m/%d'), pstat.coef_busy ]
|
283
|
+
end
|
284
|
+
res
|
285
|
+
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
289
|
+
end
|
@@ -5,6 +5,9 @@ module C80Estate
|
|
5
5
|
belongs_to :property
|
6
6
|
belongs_to :astatus
|
7
7
|
belongs_to :auser, :polymorphic => true
|
8
|
+
has_many :pstats, :dependent => :destroy
|
9
|
+
|
10
|
+
after_create :generate_pstat
|
8
11
|
|
9
12
|
=begin
|
10
13
|
def self.all_areas
|
@@ -146,6 +149,10 @@ module C80Estate
|
|
146
149
|
# sevents = self.where(:area_id => area_id).where(:created_at => used_start_date..used_end_date)
|
147
150
|
sevents = self.where(:area_id => area_id).where("created_at BETWEEN ? AND ?", used_start_date, used_end_date)
|
148
151
|
|
152
|
+
# if atype_id.present?
|
153
|
+
# sevents = sevents.where(:atype_id => atype_id)
|
154
|
+
# end
|
155
|
+
|
149
156
|
# если в этот промежуток небыло событий - значит промежуток целиком попал в какое-то событие
|
150
157
|
# найдем его
|
151
158
|
# заодно поднимем вспомогательный флаг, который обработаем во view
|
@@ -198,6 +205,12 @@ module C80Estate
|
|
198
205
|
{ tag: 'property_title', val: "Объект: #{area.property_title}" }
|
199
206
|
]
|
200
207
|
|
208
|
+
# if atype_id.present?
|
209
|
+
# result[:props] << {tag: 'atype_filter', val: "Фильтр по типу площади: #{ Atype.find(atype_id).title }"}
|
210
|
+
# end
|
211
|
+
|
212
|
+
elsif prop_id.present?
|
213
|
+
|
201
214
|
end
|
202
215
|
|
203
216
|
result
|
@@ -364,5 +377,19 @@ module C80Estate
|
|
364
377
|
res
|
365
378
|
end
|
366
379
|
|
380
|
+
protected
|
381
|
+
|
382
|
+
def generate_pstat
|
383
|
+
|
384
|
+
# pparams = {
|
385
|
+
# atype_id: nil,
|
386
|
+
# property_id: self.property_id,
|
387
|
+
# sevent_id: self.id,
|
388
|
+
# created_at: self.created_at
|
389
|
+
# }
|
390
|
+
# Pstat.create!(pparams)
|
391
|
+
|
392
|
+
end
|
393
|
+
|
367
394
|
end
|
368
395
|
end
|
data/config/routes.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
C80Estate::Engine.routes.draw do
|
2
2
|
match '/estate/get_atype_propnames', :to => 'ajax#get_atype_propnames', :via => :post
|
3
3
|
match '/estate/areas_ecoef', :to => 'ajax#areas_ecoef', :via => :post
|
4
|
+
match '/estate/properties_busy_coef', :to => 'ajax#properties_busy_coef', :via => :post
|
4
5
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateC80EstatePstats < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :c80_estate_pstats, :options => 'COLLATE=utf8_unicode_ci' do |t|
|
4
|
+
t.references :property, index: true
|
5
|
+
t.references :atype, index: true
|
6
|
+
t.references :sevent, index: true
|
7
|
+
t.references :parent, index: true
|
8
|
+
t.integer :free_areas
|
9
|
+
t.integer :busy_areas
|
10
|
+
t.integer :coef_busy
|
11
|
+
t.integer :free_areas_sq
|
12
|
+
t.integer :busy_areas_sq
|
13
|
+
t.integer :coef_busy_sq
|
14
|
+
t.timestamps
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/c80_estate/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: c80_estate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0.
|
4
|
+
version: 0.1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- C80609A
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-07-
|
11
|
+
date: 2016-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -70,10 +70,12 @@ files:
|
|
70
70
|
- app/admin/c80_estate/atypes.rb
|
71
71
|
- app/admin/c80_estate/prop_names.rb
|
72
72
|
- app/admin/c80_estate/properties.rb
|
73
|
+
- app/admin/c80_estate/pstats.rb
|
73
74
|
- app/admin/c80_estate/role_types.rb
|
74
75
|
- app/admin/c80_estate/sevents.rb
|
75
76
|
- app/admin/c80_estate/uoms.rb
|
76
77
|
- app/assets/javascript/c80_estate/backend/admin/areas.js
|
78
|
+
- app/assets/javascript/c80_estate/backend/admin/pstats.js
|
77
79
|
- app/assets/javascript/c80_estate/backend/admin/sevents.js
|
78
80
|
- app/assets/javascript/c80_estate/backend/init.js
|
79
81
|
- app/assets/javascript/c80_estate/backend/init_selectpicker.js
|
@@ -81,6 +83,7 @@ files:
|
|
81
83
|
- app/assets/javascript/c80_estate/lib/jalert.js
|
82
84
|
- app/assets/javascript/c80_estate_active_admin.js.coffee
|
83
85
|
- app/assets/stylesheets/c80_estate/backend/admin_areas.scss
|
86
|
+
- app/assets/stylesheets/c80_estate/backend/admin_pstats.scss
|
84
87
|
- app/assets/stylesheets/c80_estate/backend/admin_sevents.scss
|
85
88
|
- app/assets/stylesheets/c80_estate/backend/admin_users.scss
|
86
89
|
- app/assets/stylesheets/c80_estate/backend/common.scss
|
@@ -98,6 +101,7 @@ files:
|
|
98
101
|
- app/models/c80_estate/pphoto.rb
|
99
102
|
- app/models/c80_estate/prop_name.rb
|
100
103
|
- app/models/c80_estate/property.rb
|
104
|
+
- app/models/c80_estate/pstat.rb
|
101
105
|
- app/models/c80_estate/role.rb
|
102
106
|
- app/models/c80_estate/role_type.rb
|
103
107
|
- app/models/c80_estate/sevent.rb
|
@@ -125,6 +129,7 @@ files:
|
|
125
129
|
- db/migrate/20160704050000_create_c80_estate_role_types.rb
|
126
130
|
- db/migrate/20160704063131_create_c80_estate_roles.rb
|
127
131
|
- db/migrate/20160713043333_create_c80_estate_sevents.rb
|
132
|
+
- db/migrate/20160717094647_create_c80_estate_pstats.rb
|
128
133
|
- db/seeds/50_fill_uoms.rb.example
|
129
134
|
- db/seeds/55_fill_prop_names.rb.example
|
130
135
|
- db/seeds/60_fill_atypes.rb.example
|