c80_estate 0.1.0.26 → 0.1.0.27

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
  SHA1:
3
- metadata.gz: 3a8c4fa72c7d1c0dbb270f3241e6e10ff3f20243
4
- data.tar.gz: 1d373ad7afcea3386d764acdf7cd79fbd13d3656
3
+ metadata.gz: 186988e51e84d02566e306dad6bd211623c76def
4
+ data.tar.gz: b14d9a239cb9905b2d772a8a718944acd434a9c6
5
5
  SHA512:
6
- metadata.gz: d849c3101f5909bedc902b60b399350cbfe2ac09a176c53dfe196bc21e954ca65e14b7ca8570e9b4f8e7e3e13c2bd2bffe2849334aab0e6d79fad6a4a2a3b76e
7
- data.tar.gz: dddbbb52e77094e1bc6c57b8899104cbfc2ce335999cc0219b30e89572b5ec3b48e335b2bf4f2b80731876e356797957c54a6dcb48a340ec7b9d4c8eebd03b1a
6
+ metadata.gz: cfd7e1d00a68415b299011611d8a9bb0400006b63b9ab15e1ba3b40df10f9e9cd67eff45079386b8a1575e91533fa332ded19a807ede05329003f5a892f6d1bd
7
+ data.tar.gz: 3d69dc9df0d4b2d148cce2b7c5e88a3d56288ff1d59580002f35f4a8830704f91934e86f22b62725185bcc8a0cc4029c8331b659da22235422e2717b39fc9365
@@ -151,7 +151,13 @@ ActiveAdmin.register C80Estate::Area, as: 'Area' do
151
151
  "#{area.price_value.to_s(:rounded, :precision => 2)} руб"
152
152
  end
153
153
  column '<abbr title="Стоимость всей площади в месяц. Число PxS, где P - цена за м.кв. в месяц, S - метраж площади в м.кв.">Цена площади</abbr>'.html_safe do |area|
154
- "#{area.power_price_value.to_s(:rounded, :precision => 2)} руб"
154
+ klass = ''
155
+ title = 'Цена за площадь рассчитана'
156
+ if area.is_locked_area_price?
157
+ klass = 'locked'
158
+ title = 'Явно указана цена за площадь, цена за метр рассчитана от этого числа'
159
+ end
160
+ "<span title='#{title}' class='#{klass}'>#{area.power_price_value.to_s(:rounded, :precision => 2)} руб</span>".html_safe
155
161
  end
156
162
  column 'Метраж' do |area|
157
163
  "#{area.square_value.to_s(:rounded, :precision => 2)} м<sup>2</sup>".html_safe
@@ -195,11 +195,11 @@ var jsinit = {
195
195
  $iselprop.attr("disabled", true); // NOTE:: но в момент нажатия кнопки "Отправить" мы "разлачиваем" селект, чтобы параметры формы "правильно" отправлялись;
196
196
 
197
197
  // в input "производитель" - ставим "-1" и прячем его от пользователя
198
- if (ielem["id"] == 36) {
199
- $iinputprop.val("-1");
200
- $ifs.css("display",'none');
201
- }
202
-
198
+ //if (ielem["id"] == 36) {
199
+ // $iinputprop.val("-1");
200
+ // $ifs.css("display",'none');
201
+ //}
202
+ $ifs.find("> ol").addClass('v_' + ielem["id"]);
203
203
  }
204
204
 
205
205
  fLoadingHide();
@@ -309,6 +309,7 @@ var fEdit = function () {
309
309
  //console.log(this);
310
310
  return $(this).val() == ielem["id"]; //return $(this).text() == ielem["title"];
311
311
  }).prop('selected', true);
312
+ //$ifs.addClass('v_'+ielem["id"]);
312
313
  $iselprop.attr("disabled", true); // NOTE:: но в момент нажатия кнопки "Отправить" мы "разлачиваем" селект, чтобы параметры формы "правильно" отправлялись
313
314
 
314
315
  }
@@ -338,22 +339,26 @@ var fEdit = function () {
338
339
  return t;
339
340
  });
340
341
 
342
+ // находим опцию id=36 селекта "имя свойства"
343
+ var $opt = $iselprop.find("option").filter(function () {
344
+ var $t = $(this);
345
+ //return $t.val() == 36 && $t.prop('selected');
346
+ return $t.val() == ielem["id"] && $t.prop('selected');
347
+ });
348
+ // из этой опции добираемся до fieldset, который её содержит
349
+ var $fieldset = $opt.parent().parent().parent();
350
+
351
+ //console.log($fieldset);
352
+
341
353
  // в input "производитель" - ставим "-1" и прячем весь fieldset от пользователя
342
- if (ielem["id"] == 36) {
343
- // находим опцию id=36 селекта "имя свойства"
344
- var $opt = $iselprop.find("option").filter(function () {
345
- var $t = $(this);
346
- return $t.val() == 36 && $t.prop('selected');
347
- });
348
- // из этой опции добираемся до fieldset, который её содержит
349
- var $fieldset = $opt.parent().parent().parent();
354
+ //if (ielem["id"] == 36) {
350
355
  // а затем уже находим input
351
- $fieldset.find("input").val("-1");
356
+ //$fieldset.find("input").val("-1");
352
357
  // прячем
353
- $fieldset.css('display','none');
354
-
355
- }
358
+ //$fieldset.css('display','none');
359
+ //}
356
360
 
361
+ $fieldset.addClass('v_'+ielem["id"]);
357
362
  }
358
363
 
359
364
  fLoadingHide();
@@ -41,6 +41,11 @@ var fPstatsIndex = function () {
41
41
 
42
42
  var $ajax_div, $ajax_div2;
43
43
 
44
+ // здесь живут средние арендные ставки: по всем, и по занятым
45
+ var $div_row_average_prices,
46
+ $p_average_price,
47
+ $p_average_price_busy;
48
+
44
49
  var fBuild = function () {
45
50
 
46
51
  // зафиксируем html элементы
@@ -57,6 +62,17 @@ var fPstatsIndex = function () {
57
62
  // построим компонент "над таблицей"
58
63
  $div_index_adds = $("<div class='index_adds_like_pstats'></div>");
59
64
 
65
+ // строка со средними ценами
66
+ $div_row_average_prices = $("<div id='div_row_average_prices'></div>").appendTo($div_index_adds);
67
+ var $div_average_price = $('<div class="average_price"></div>').appendTo($div_row_average_prices);
68
+ $p_average_price = $('<p class="val"></p>').appendTo($div_average_price);
69
+ var $average_price_comment = $('<p class="abbr"><abbr title="Суммируем все средние ставки всех объектов и делим на кол-во объектов. Если в фильтрах указан тип - то вычисления проводятся относительно указанного типа.">Средняя ставка</abbr></p>').appendTo($div_average_price);
70
+
71
+ var $div_average_price_busy = $('<div class="average_price_busy"></div>').appendTo($div_row_average_prices);
72
+ $p_average_price_busy = $('<p class="val"></p>').appendTo($div_average_price_busy);
73
+ var $average_price_comment_busy = $('<p class="abbr"><abbr title="Суммируем все средние ставки по занятым всех объектов и делим на кол-во объектов. Если в фильтрах указан тип - то вычисления проводятся относительно указанного типа.">Средняя ставка по занятым</abbr></p>').appendTo($div_average_price_busy);
74
+
75
+ // коэф-ты занятости
60
76
  $div_busy_coef = $("<div id='coef'></div>").appendTo($div_index_adds);
61
77
  $p_busy_coef = $("<p class='val'></p>").appendTo($div_busy_coef);
62
78
  $p_busy_coef_mess = $("<p class='title'><abbr class='abbr_busy_coef' title='TITLE'>Занятость</abbr></p>").appendTo($div_busy_coef);
@@ -164,7 +180,15 @@ var fPstatsIndex = function () {
164
180
  fDrawChartRadialSq(data["graph_radial_sq"]);
165
181
  }
166
182
 
167
- $h2_page_title.text(data["title"]);
183
+ if (data["average_price"] != undefined && data["average_price_busy"] != undefined) {
184
+ $p_average_price.text(data["average_price"]);
185
+ $p_average_price_busy.text(data["average_price_busy"]);
186
+ $div_row_average_prices.css('opacity','1.0');
187
+ } else {
188
+ $div_row_average_prices.css('display','none');
189
+ }
190
+
191
+ $h2_page_title.html(data["title"]);
168
192
  $h2_page_title.css('opacity', '1.0');
169
193
  $(document).attr('title', data["title"]);
170
194
 
@@ -109,9 +109,24 @@ body.admin_areas {
109
109
  .fieldset_item_props {
110
110
  background-color: white !important;
111
111
  box-shadow: none !important;
112
+
112
113
  legend {
113
114
  display: none !important;
114
115
  }
116
+
117
+ fieldset.has_many_fields {
118
+ background-color: transparent !important;
119
+ box-shadow: none !important;
120
+ }
121
+
122
+ ol.v_1, ol.v_9, ol.v_14 {
123
+ li.input.optional {
124
+ input {
125
+ background-color: rgba(255, 200, 127, 0.26) !important;
126
+ }
127
+ }
128
+ }
129
+
115
130
  }
116
131
 
117
132
  }
@@ -160,6 +175,10 @@ body.admin_areas {
160
175
 
161
176
  }
162
177
 
178
+ span.locked {
179
+ font-weight: bold;
180
+ }
181
+
163
182
  }
164
183
 
165
184
  &.show {
@@ -20,4 +20,13 @@
20
20
  a.canvasjs-chart-credit {
21
21
  display: none !important;
22
22
  opacity: 0 !important;
23
+ }
24
+
25
+ h2#page_title {
26
+ span.h2_title_span {
27
+ font-size: 34px;
28
+ font-weight: 300;
29
+ color: #d8d7d7;
30
+ border-bottom: 2px dotted #d8d7d7;
31
+ }
23
32
  }
@@ -127,5 +127,60 @@ div.index_adds_like_pstats {
127
127
 
128
128
  }
129
129
 
130
+ &#div_row_average_prices {
131
+ width:100%;
132
+ clear: both;
133
+ border: none;
134
+ height: auto;
135
+ margin-bottom: 15px;
136
+ padding: 0;
137
+ opacity: 0;
138
+ -webkit-transition: opacity .2s ease-in;
139
+ -moz-transition: opacity .2s ease-in;
140
+ -ms-transition: opacity .2s ease-in;
141
+ -o-transition: opacity .2s ease-in;
142
+ transition: opacity .2s ease-in;
143
+
144
+ > div {
145
+ border: none !important;
146
+ border-radius: 3px;
147
+ float: left;
148
+ padding: 10px;
149
+ color: white !important;
150
+
151
+ &.average_price {
152
+ width: calc(50% - 8px);
153
+ margin-right: 8px;
154
+ background: #A0DBE3;
155
+ }
156
+
157
+ &.average_price_busy {
158
+ width: calc(50% - 19px);
159
+ margin-left: 7px;
160
+ background: #F7B6B0;
161
+ }
162
+
163
+ > p {
164
+ float: left;
165
+ width: 50%;
166
+ white-space: nowrap;
167
+ font-size: 24px;
168
+ margin:0;
169
+
170
+ &.val {
171
+ padding: 0 0 0 15px;
172
+ font-weight: bold;
173
+ }
174
+
175
+ &.abbr {
176
+ margin-top: -4px;
177
+ abbr {
178
+ border-bottom: 1px dotted white;
179
+ }
180
+ }
181
+ }
182
+ }
183
+ }
184
+
130
185
  }
131
186
  }
@@ -23,7 +23,7 @@ module C80Estate
23
23
 
24
24
  area.atype.prop_names.each do |atype_propname|
25
25
  title = atype_propname.title
26
- if atype_propname.id == 1 || atype_propname.id == 9
26
+ if atype_propname.id == 1 || atype_propname.id == 9 || atype_propname.id == 14
27
27
  next
28
28
  end
29
29
  # value = prop.value
@@ -259,12 +259,41 @@ module C80Estate
259
259
  sevents.last.auser.email
260
260
  end
261
261
 
262
+ # выдать цену за м.кв. в месяц
262
263
  def price_value
264
+
263
265
  res = 0.0
264
- p = item_props.where(:prop_name_id => 1)
265
- if p.count > 0
266
- res = p.first.value.to_f
266
+ mark_use_usual_price = false
267
+
268
+ # если указана "цена за площадь",
269
+ # то цену за м кв. в месяц высчитываем
270
+ pa = item_props.where(:prop_name_id => 14)
271
+ if pa.count > 0
272
+ pa_val = pa.first.value.to_f
273
+
274
+ if pa_val == 0
275
+ # если руками было проставлено 0 - т.е. свойство как бы было удалено, выключено
276
+ mark_use_usual_price = true
277
+ else
278
+ if square_value != 0
279
+ # результат получаем только тогда, когда указана площадь и когда указана цена за площадь
280
+ res = pa_val / square_value
281
+ else
282
+ # если не указана площадь - то берём обычную цену
283
+ mark_use_usual_price = true
284
+ end
285
+ end
286
+ else
287
+ mark_use_usual_price = true
267
288
  end
289
+
290
+ if mark_use_usual_price
291
+ p = item_props.where(:prop_name_id => 1)
292
+ if p.count > 0
293
+ res = p.first.value.to_f
294
+ end
295
+ end
296
+
268
297
  res
269
298
  end
270
299
 
@@ -290,6 +319,19 @@ module C80Estate
290
319
  url
291
320
  end
292
321
 
322
+ # вернёт true, если вручную указана цена за всю площадь
323
+ def is_locked_area_price?
324
+ res = false
325
+ pa = item_props.where(:prop_name_id => 14)
326
+ if pa.count > 0
327
+ pa_val = pa.first.value.to_f
328
+ if pa_val > 0
329
+ res = true
330
+ end
331
+ end
332
+ res
333
+ end
334
+
293
335
  ransacker :item_prop_price_val,
294
336
  formatter: proc { |price_range| # 10,156
295
337
  results = C80Estate::Area.where_price_range(price_range).map(&:id)
@@ -4,13 +4,13 @@ module C80Estate
4
4
  belongs_to :owner, :polymorphic => true
5
5
  belongs_to :assigned_person, :polymorphic => true
6
6
  # has_many :item_props, :dependent => :destroy
7
- has_many :pphotos, :dependent => :destroy # одна или несколько фоток
7
+ has_many :pphotos, :dependent => :destroy # одна или несколько фоток
8
8
  accepts_nested_attributes_for :pphotos,
9
9
  :reject_if => lambda { |attributes|
10
10
  !attributes.present?
11
11
  },
12
12
  :allow_destroy => true
13
- has_many :plogos, :dependent => :destroy # одна или несколько фоток
13
+ has_many :plogos, :dependent => :destroy # одна или несколько фоток
14
14
  accepts_nested_attributes_for :plogos,
15
15
  :reject_if => lambda { |attributes|
16
16
  !attributes.present?
@@ -41,46 +41,77 @@ module C80Estate
41
41
  ac
42
42
  end
43
43
 
44
- # применим для коллекций
45
- # def self.average_price
46
- #
47
- # areas_counter = 0
48
- # price_sum = 0
49
- #
50
- # self.all.each do |prop|
51
- # prop.areas.all.each do |area|
52
- # price_sum += area.price_value
53
- # areas_counter += 1
54
- # end
55
- # end
56
- #
57
- # if areas_counter != 0
58
- # price_sum*1.0 / areas_counter
59
- # else
60
- # 0
61
- # end
62
- # end
63
-
64
- def average_price
44
+ # посчитает среднее значение средних цен по коллекции
45
+ def self.average_price(atype_id: nil)
46
+
47
+ res = 0.0
48
+ sum = 0.0
49
+
50
+ c = self.all.count
51
+ if c > 0
52
+ self.all.each do |prop|
53
+ sum += prop.average_price(atype_id:atype_id)
54
+ end
55
+ res = sum / c
56
+ end
57
+
58
+ res
59
+ end
60
+
61
+ # посчитает среднее значение средних цен ЗАНЯТЫХ ПЛОЩАДЕЙ по коллекции
62
+ # можно указать тип
63
+ def self.average_price_busy(atype_id: nil)
64
+
65
+ res = 0.0
66
+ sum = 0.0
67
+
68
+ c = self.all.count
69
+ if c > 0
70
+ self.all.each do |prop|
71
+ sum += prop.average_price_busy(atype_id:atype_id)
72
+ end
73
+ res = sum / c
74
+ end
75
+
76
+ res
77
+ end
78
+
79
+ def average_price(atype_id: nil)
80
+
81
+ if atype_id.nil?
82
+ ars = areas.all
83
+ else
84
+ ars = areas.where_atype(atype_id)
85
+ end
86
+
65
87
  price_sum = 0.0
66
- areas.all.each do |area|
88
+
89
+ ars.each do |area|
67
90
  price_sum += area.price_value
68
91
  end
69
92
 
70
- if areas.all.count != 0
71
- price_sum*1.0 / areas.all.count
93
+ if ars.count != 0
94
+ price_sum*1.0 / ars.count
72
95
  else
73
96
  0.0
74
97
  end
75
98
 
76
99
  end
77
100
 
78
- def average_price_busy
101
+ # рассчитать среднюю цену среди занятых у конкретного объекта
102
+ # можно указать дополнительно тип
103
+ def average_price_busy(atype_id: nil)
104
+
105
+ if atype_id.nil?
106
+ ars = areas.all
107
+ else
108
+ ars = areas.where_atype(atype_id)
109
+ end
79
110
 
80
111
  busy_areas_count = 0
81
112
  price_sum = 0.0
82
113
 
83
- areas.all.each do |area|
114
+ ars.each do |area|
84
115
  if area.is_busy?
85
116
  busy_areas_count += 1
86
117
  price_sum += area.price_value
@@ -137,6 +137,8 @@ module C80Estate
137
137
 
138
138
  # common
139
139
 
140
+ result[:average_price] = "#{Property.all.average_price.to_s(:rounded, :precision => 2)} руб" #'123,50 руб'
141
+ result[:average_price_busy] = "#{Property.all.average_price_busy.to_s(:rounded, :precision => 2)} руб" # '73,50 руб'
140
142
  result[:title] = 'Статистика - Все объекты недвижимости'
141
143
  # Rails.logger.debug "result ============= #{result}"
142
144
 
@@ -301,8 +303,12 @@ module C80Estate
301
303
  result[:raw_props_sq][:busy_areas_atnow_sq] = busy_areas_atnow_sq
302
304
 
303
305
  # common
304
-
306
+ result[:average_price] = "#{property.average_price(atype_id:atype_id).to_s(:rounded, :precision => 2)} руб" #'123,50 руб'
307
+ result[:average_price_busy] = "#{property.average_price_busy(atype_id:atype_id).to_s(:rounded, :precision => 2)} руб" #'73,50 руб'
305
308
  result[:title] = "Статистика - Объект - #{property.title}"
309
+ if atype_id.present?
310
+ result[:title] += " <span class='h2_title_span'>// фильтр по типу: #{Atype.find(atype_id).title}</span>"
311
+ end
306
312
  # result[:graph] = _parse_for_js_radial_graph(free_areas_atnow,busy_areas_atnow)
307
313
 
308
314
 
@@ -390,14 +396,19 @@ module C80Estate
390
396
 
391
397
  # Занятость
392
398
 
393
- tt = _calc_free_busy_areas(pstats)
394
-
395
- free_areas_atnow = tt[:sum_free_areas] #*1.0/all_props.count #pstats.last.free_areas
396
- busy_areas_atnow = tt[:sum_busy_areas] #*1.0/all_props.count #pstats.last.busy_areas
397
-
399
+ =begin
400
+ # tt = _calc_free_busy_areas(pstats)
401
+ #
402
+ # free_areas_atnow = tt[:sum_free_areas] #*1.0/all_props.count #pstats.last.free_areas
403
+ # busy_areas_atnow = tt[:sum_busy_areas] #*1.0/all_props.count #pstats.last.busy_areas
404
+ #
398
405
  # Rails.logger.debug("\t\t atype_id = #{atype_id}")
399
406
  # Rails.logger.debug("\t\t free_areas_atnow = #{free_areas_atnow}")
400
407
  # Rails.logger.debug("\t\t busy_areas_atnow = #{busy_areas_atnow}")
408
+ =end
409
+
410
+ free_areas_atnow = pstats.last.free_areas
411
+ busy_areas_atnow = pstats.last.busy_areas
401
412
 
402
413
  # защищаемся от деления на ноль
403
414
  if free_areas_atnow + busy_areas_atnow == 0
@@ -456,8 +467,9 @@ module C80Estate
456
467
  result[:raw_props_sq][:busy_areas_atnow_sq] = busy_areas_atnow_sq
457
468
 
458
469
  # common
459
-
460
- result[:title] = "Статистика - Объекты - Фильтр по типу площади '#{ Atype.find(atype_id).title }'"
470
+ result[:average_price] = "#{Property.all.average_price(atype_id: atype_id).to_s(:rounded, :precision => 2)} руб" #'123,50 руб'
471
+ result[:average_price_busy] = "#{Property.all.average_price_busy(atype_id: atype_id).to_s(:rounded, :precision => 2)} руб" # '73,50 руб'
472
+ result[:title] = "Статистика - Все объекты <span class='h2_title_span'>// фильтр по типу: #{Atype.find(atype_id).title}</span>"
461
473
 
462
474
  # if atype_id.present?
463
475
  # result[:title] += " (#{Atype.find(atype_id).title})"
@@ -1,3 +1,3 @@
1
1
  module C80Estate
2
- VERSION = '0.1.0.26'
2
+ VERSION = '0.1.0.27'
3
3
  end
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.26
4
+ version: 0.1.0.27
5
5
  platform: ruby
6
6
  authors:
7
7
  - C80609A
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-08-03 00:00:00.000000000 Z
11
+ date: 2016-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler