c80_estate 0.1.0.26 → 0.1.0.27

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 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