c80_catoffers 0.1.0.3 → 0.1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/admin/c80_catoffers/csamples.rb +69 -0
- data/app/admin/c80_catoffers/csprops.rb +41 -0
- data/app/assets/javascripts/c80_catoffers/offer_full_desc.js +52 -47
- data/app/assets/javascripts/c80_catoffers/offers_ajax.js +89 -0
- data/app/assets/stylesheets/c80_catoffers/offer_full_desc.scss +3 -2
- data/app/assets/stylesheets/c80_catoffers/offer_list_grouped.scss +23 -0
- data/app/assets/stylesheets/c80_catoffers/offer_list_widget.scss +19 -15
- data/app/assets/stylesheets/c80_catoffers/will_paginate.scss +65 -0
- data/app/controllers/c80_catoffers/application_controller.rb +25 -0
- data/app/helpers/c80_catoffers/app_helper.rb +47 -4
- data/app/helpers/c80_catoffers/csamples_helper.rb +52 -0
- data/app/helpers/c80_catoffers/inner/modal_helper.rb +16 -0
- data/app/helpers/c80_catoffers/price_helper.rb +17 -0
- data/app/helpers/c80_catoffers/urls_helper.rb +7 -3
- data/app/models/c80_catoffers/crow.rb +22 -0
- data/app/models/c80_catoffers/csample.rb +40 -0
- data/app/models/c80_catoffers/csprop.rb +5 -0
- data/app/models/c80_catoffers/offer.rb +7 -0
- data/app/uploaders/c80_catoffers/csphoto_uploader.rb +49 -0
- data/app/views/c80_catoffers/_bs_modal.html.erb +18 -0
- data/app/views/c80_catoffers/_csamples_widget.html.erb +43 -0
- data/app/views/c80_catoffers/_offers_list_grouped.html.erb +5 -2
- data/app/views/c80_catoffers/_offers_list_widget.html.erb +54 -48
- data/app/views/c80_catoffers/_offers_page.html.erb +23 -0
- data/app/views/c80_catoffers/_popup_price.html.erb +2 -0
- data/app/views/c80_catoffers/application/fake_main.html.erb +0 -0
- data/app/views/c80_catoffers/application/offers_guru.js.erb +10 -0
- data/app/views/c80_catoffers/application/price_me.js.erb +19 -0
- data/config/locales/ru.yml +6 -0
- data/config/routes.rb +3 -9
- data/db/migrate/20161105123939_c80_catoffers_add_per_page_to_props.rb +5 -0
- data/db/migrate/20161106154221_create_c80_catoffers_csamples.rb +13 -0
- data/db/migrate/20161106191544_create_c80_catoffers_crows.rb +13 -0
- data/db/migrate/20161107115555_c80_catoffers_create_csprops.rb +7 -0
- data/db/migrate/20161107123333_c80_catoffers_create_join_table_csprops_csamples.rb +11 -0
- data/db/seeds/c80_catoffers_01_fill_props.rb +2 -1
- data/lib/c80_catoffers/version.rb +1 -1
- metadata +27 -2
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'c80_lazy_images'
|
2
|
+
|
3
|
+
module C80Catoffers
|
4
|
+
class ApplicationController < ActionController::Base
|
5
|
+
|
6
|
+
helper C80LazyImages::Engine.helpers
|
7
|
+
|
8
|
+
def offers_guru
|
9
|
+
respond_to do |format|
|
10
|
+
format.js
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def fake_main
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
def price_me
|
19
|
+
respond_to do |format|
|
20
|
+
format.js
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -44,7 +44,7 @@ module C80Catoffers
|
|
44
44
|
a = []
|
45
45
|
|
46
46
|
# создадим подмассивы
|
47
|
-
cols_count.times do
|
47
|
+
cols_count.times do
|
48
48
|
a << []
|
49
49
|
end
|
50
50
|
|
@@ -115,7 +115,7 @@ module C80Catoffers
|
|
115
115
|
# Rails.logger.debug "[TRACE] <render_offers_list_iconed>"
|
116
116
|
|
117
117
|
# свойства модуля
|
118
|
-
p = Prop.first
|
118
|
+
# p = Prop.first
|
119
119
|
|
120
120
|
# список категорий, которые надо вывести в виджете (со слотами)
|
121
121
|
list = _get_widgeted_offers_with_slots
|
@@ -138,7 +138,13 @@ module C80Catoffers
|
|
138
138
|
# Построить линейный слотованный список предложений, каждое предложение
|
139
139
|
# в списке и представить в виде блока с указанным ВЕРТИКАЛЬНЫМ списком свойств +list_of_props+
|
140
140
|
#
|
141
|
-
def render_offers_widget(p_list_of_props, style='default', thumb_size='thumb_md')
|
141
|
+
def render_offers_widget(p_list_of_props, style='default', thumb_size='thumb_md', h3_title=' ')
|
142
|
+
|
143
|
+
# Rails.logger.debug "[TRACE] h3_title = '#{h3_title}'"
|
144
|
+
|
145
|
+
if h3_title == ' '
|
146
|
+
h3_title = I18n.t('c80_catoffers.offer_list_widget.h3_title')
|
147
|
+
end
|
142
148
|
|
143
149
|
# соберём слотованный список предложений
|
144
150
|
list_offers = _get_widgeted_offers_with_slots
|
@@ -158,6 +164,44 @@ module C80Catoffers
|
|
158
164
|
css_wh = _calc_css_for_list_widget(thumb_size)
|
159
165
|
|
160
166
|
render :partial => 'c80_catoffers/offers_list_widget',
|
167
|
+
:locals => {
|
168
|
+
list_props: p_list_of_props,
|
169
|
+
css_style_for_block: style,
|
170
|
+
list_offers: list_offers,
|
171
|
+
list_of_values_lists: list_of_values,
|
172
|
+
css_for_a: css_wh[:a_lazy_wrapper],
|
173
|
+
css_for_title: css_wh[:title],
|
174
|
+
h3_title: h3_title
|
175
|
+
}
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
## Потроить ajax-линейный список Предложений [на странице "наши услуги", например]
|
180
|
+
# каждое предложение
|
181
|
+
# в списке и представить в виде блока с указанным ВЕРТИКАЛЬНЫМ списком свойств +p_list_of_props+
|
182
|
+
def render_offers_page(p_list_of_props, style='default', thumb_size='thumb_md', page=1)
|
183
|
+
|
184
|
+
per_page = Prop.first.per_page
|
185
|
+
|
186
|
+
#
|
187
|
+
list_offers = C80Catoffers::Offer.paginate(:page => page, :per_page => per_page)
|
188
|
+
|
189
|
+
# релевантный список списков значений указанных характеристик слотованного списка предложений
|
190
|
+
list_of_values = []
|
191
|
+
|
192
|
+
# обойдём список Предложений и для каждого Предложения соберём релевантный список значений свойств
|
193
|
+
list_offers.each do |offer|
|
194
|
+
|
195
|
+
# соберём и обработаем значения нужных характеристик каждого Предложения
|
196
|
+
vals = _proccess_list_of_props(p_list_of_props, offer)
|
197
|
+
list_of_values << vals
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
# чтобы вёрстка не прыгала - зафиксируем размер картинки
|
202
|
+
css_wh = _calc_css_for_list_widget(thumb_size)
|
203
|
+
|
204
|
+
render :partial => 'c80_catoffers/offers_page',
|
161
205
|
:locals => {
|
162
206
|
list_props: p_list_of_props,
|
163
207
|
css_style_for_block: style,
|
@@ -166,7 +210,6 @@ module C80Catoffers
|
|
166
210
|
css_for_a: css_wh[:a_lazy_wrapper],
|
167
211
|
css_for_title: css_wh[:title]
|
168
212
|
}
|
169
|
-
|
170
213
|
end
|
171
214
|
|
172
215
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module C80Catoffers
|
2
|
+
module CsamplesHelper
|
3
|
+
|
4
|
+
def render_samples_widget
|
5
|
+
|
6
|
+
# сформируем первый список - список Примеров
|
7
|
+
samples_list = Csample.all_widgeted.def_order
|
8
|
+
|
9
|
+
#-> чтобы вёрстка не прыгала - зафиксируем размер КАЖДОЙ картинки (картинки могут быть разной ШИРИНЫ)
|
10
|
+
|
11
|
+
# обойдём список Примеров и составим СООТВЕТСТВУЮЩИЙ список aux-css-стилей
|
12
|
+
aux_css_list = []
|
13
|
+
samples_list.each do |csample|
|
14
|
+
aux_css_list << _calc_aux_css(csample)
|
15
|
+
end
|
16
|
+
|
17
|
+
render :partial => 'c80_catoffers/csamples_widget',
|
18
|
+
:locals => {
|
19
|
+
list: samples_list,
|
20
|
+
aux_css_list: aux_css_list
|
21
|
+
}
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Спец-метод узкого назначения - формирует вспомогательный css стиль для ВЕРТИКАЛЬНОГО списка элементов,
|
28
|
+
# фиксирует габариты ссылки-конейнера,
|
29
|
+
# в которую помещена картинка
|
30
|
+
def _calc_aux_css(csample)
|
31
|
+
|
32
|
+
w = 0
|
33
|
+
h = 0
|
34
|
+
img = csample.csphoto_img
|
35
|
+
|
36
|
+
if img.present?
|
37
|
+
w = img['width']
|
38
|
+
h = img['height']
|
39
|
+
end
|
40
|
+
|
41
|
+
res = {
|
42
|
+
:a_lazy_wrapper => "width:#{w}px;height:#{h}px",
|
43
|
+
:common_width => "width:#{w}px;"
|
44
|
+
}
|
45
|
+
|
46
|
+
# Rails.logger.debug "[TRACE] <_calc_css_for_list_iconed> #{res}"
|
47
|
+
res
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module C80Catoffers
|
2
|
+
module Inner
|
3
|
+
module ModalHelper
|
4
|
+
|
5
|
+
def _render_bs_modal(content='', title='')
|
6
|
+
render :partial => 'c80_catoffers/bs_modal',
|
7
|
+
:locals => {
|
8
|
+
title: title,
|
9
|
+
content: content,
|
10
|
+
close_label: 'Закрыть'
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module C80Catoffers
|
2
|
+
module PriceHelper
|
3
|
+
|
4
|
+
def render_price
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
def render_popup_price
|
9
|
+
render :partial => 'c80_catoffers/popup_price',
|
10
|
+
:locals => {
|
11
|
+
title: 'Прайс',
|
12
|
+
content: render_offers_list_grouped
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -1,13 +1,17 @@
|
|
1
1
|
module C80Catoffers
|
2
2
|
module UrlsHelper
|
3
3
|
|
4
|
+
def root_url_fake
|
5
|
+
'/'
|
6
|
+
end
|
7
|
+
|
4
8
|
def my_url_for_offer(offer)
|
5
9
|
|
6
10
|
s = ''
|
7
11
|
if offer.has_category?
|
8
|
-
s = "#{
|
12
|
+
s = "#{root_url_fake}#{offer.category.slug}/#{offer.slug}"
|
9
13
|
else
|
10
|
-
s = "#{
|
14
|
+
s = "#{root_url_fake}offers/#{offer.slug}" # TODO_MY:: хардкод в урле [аналогично в routes.rb]
|
11
15
|
end
|
12
16
|
|
13
17
|
s
|
@@ -15,7 +19,7 @@ module C80Catoffers
|
|
15
19
|
end
|
16
20
|
|
17
21
|
def my_url_for_category(category)
|
18
|
-
"#{
|
22
|
+
"#{root_url_fake}categories/#{category.slug}"
|
19
23
|
end
|
20
24
|
|
21
25
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class C80Catoffers::Crow < ActiveRecord::Base
|
2
|
+
belongs_to :csample
|
3
|
+
belongs_to :offer
|
4
|
+
scope :def_order, -> {order(:ord => :asc)}
|
5
|
+
|
6
|
+
def offer_price_integer
|
7
|
+
res = 0
|
8
|
+
if self.offer.present?
|
9
|
+
res = self.offer.price_integer
|
10
|
+
end
|
11
|
+
res
|
12
|
+
end
|
13
|
+
|
14
|
+
def offer_title
|
15
|
+
res = ''
|
16
|
+
if self.offer.present?
|
17
|
+
res = self.offer.title
|
18
|
+
end
|
19
|
+
res
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module C80Catoffers
|
2
|
+
class Csample < ActiveRecord::Base
|
3
|
+
has_many :crows, :dependent => :destroy
|
4
|
+
accepts_nested_attributes_for :crows,
|
5
|
+
:reject_if => lambda { |attributes|
|
6
|
+
!attributes.present?
|
7
|
+
},
|
8
|
+
:allow_destroy => true
|
9
|
+
has_and_belongs_to_many :csprops
|
10
|
+
mount_uploader :csphoto, CsphotoUploader
|
11
|
+
|
12
|
+
scope :def_order, -> {order(:ord => :asc)}
|
13
|
+
|
14
|
+
after_update :recalc_summ_price
|
15
|
+
after_create :recalc_summ_price
|
16
|
+
|
17
|
+
def recalc_summ_price
|
18
|
+
|
19
|
+
sum = crows.all
|
20
|
+
.map { |crow| crow.offer_price_integer.to_i }
|
21
|
+
.inject(0) { |s, x| s + x }
|
22
|
+
|
23
|
+
Rails.logger.debug "[TRACE] <C80Catoffers.recalc_summ_price> sum = #{sum}"
|
24
|
+
|
25
|
+
self.update_column(:summ_price, sum)
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
# выдать список тех Примеров, которые должны выводиться в виджете
|
30
|
+
def self.all_widgeted
|
31
|
+
self.joins(:csprops)
|
32
|
+
end
|
33
|
+
|
34
|
+
def csphoto_img
|
35
|
+
self.csphoto.present? ? MiniMagick::Image.open(self.csphoto.path):nil
|
36
|
+
# [img["width"],img["height"]]
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -15,6 +15,8 @@ module C80Catoffers
|
|
15
15
|
has_and_belongs_to_many :categories
|
16
16
|
has_and_belongs_to_many :props
|
17
17
|
|
18
|
+
has_many :crows, :dependent => :destroy
|
19
|
+
|
18
20
|
extend FriendlyId
|
19
21
|
friendly_id :title, use: :slugged
|
20
22
|
def normalize_friendly_id(input)
|
@@ -68,6 +70,11 @@ module C80Catoffers
|
|
68
70
|
res
|
69
71
|
end
|
70
72
|
|
73
|
+
def price_integer
|
74
|
+
d = self.price.match '\d+'
|
75
|
+
d.present? ? d[0].to_i : 0
|
76
|
+
end
|
77
|
+
|
71
78
|
end
|
72
79
|
|
73
80
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module C80Catoffers
|
2
|
+
|
3
|
+
# грузит картинку услуги
|
4
|
+
class CsphotoUploader < BaseFileUploader
|
5
|
+
|
6
|
+
process :resize_to_limit => [1024,768]
|
7
|
+
|
8
|
+
version :thumb_big_one do
|
9
|
+
Proc.new {
|
10
|
+
p = C80Catoffers::Prop.first
|
11
|
+
process :resize_to_fill => [p.big_one_width, p.big_one_height]
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
version :thumb_preview do
|
16
|
+
Proc.new {
|
17
|
+
p = C80Catoffers::Prop.first
|
18
|
+
process :resize_to_fill => [p.preview_width, p.preview_height]
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
version :thumb_sm do
|
23
|
+
Proc.new {
|
24
|
+
p = C80Catoffers::Prop.first
|
25
|
+
process :resize_to_fill => [p.thumb_sm_width, p.thumb_sm_height]
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
version :thumb_md do
|
30
|
+
Proc.new {
|
31
|
+
p = C80Catoffers::Prop.first
|
32
|
+
process :resize_to_fill => [p.thumb_md_width, p.thumb_md_height]
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
version :thumb_lg do
|
37
|
+
Proc.new {
|
38
|
+
p = C80Catoffers::Prop.first
|
39
|
+
process :resize_to_fill => [p.thumb_lg_width, p.thumb_lg_height]
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def store_dir
|
44
|
+
'uploads/csimages'
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<!-- Modal -->
|
2
|
+
<div class="modal fade" id="c80_catoffers_bs_modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
|
3
|
+
<div class="modal-dialog" role="document">
|
4
|
+
<div class="modal-content">
|
5
|
+
<div class="modal-header">
|
6
|
+
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
7
|
+
<h4 class="modal-title" id="myModalLabel"><%= title %></h4>
|
8
|
+
</div>
|
9
|
+
<div class="modal-body">
|
10
|
+
<%= content.html_safe %>
|
11
|
+
</div>
|
12
|
+
<div class="modal-footer">
|
13
|
+
<button type="button" class="btn btn-default" data-dismiss="modal"><%= close_label %></button>
|
14
|
+
<!--<button type="button" class="btn btn-primary">Save changes</button>-->
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
</div>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<div class="csamples_widget clearfix">
|
2
|
+
<h3><%= I18n.t('c80_catoffers.csamples_widget.h3_title') %></h3>
|
3
|
+
|
4
|
+
<% list.each_with_index do |csample, i| %>
|
5
|
+
<% aux_css = aux_css_list[i] %>
|
6
|
+
|
7
|
+
<div class="csample index_<%=i%>">
|
8
|
+
|
9
|
+
<div class="header clearfix">
|
10
|
+
<h4><%= csample.title.html_safe %></h4>
|
11
|
+
<span><%= csample.sub_title %></span>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<div class="csphoto">
|
15
|
+
<%= render_image_link_lazy({
|
16
|
+
:alt_image => csample.title,
|
17
|
+
:image => csample.csphoto,
|
18
|
+
:a_href => '',
|
19
|
+
:a_class => '',
|
20
|
+
:a_css_style => aux_css[:a_lazy_wrapper],
|
21
|
+
:a_rel => 'nofollow'
|
22
|
+
}) %>
|
23
|
+
</div>
|
24
|
+
|
25
|
+
<div class="offers" style="<%= aux_css[:common_width] %>">
|
26
|
+
<ul>
|
27
|
+
<% csample.crows.each do |crow| %>
|
28
|
+
<li>
|
29
|
+
<%= crow.offer_title %> - <%= crow.offer_price_integer %> р.
|
30
|
+
</li>
|
31
|
+
<% end %>
|
32
|
+
</ul>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div class="summ_price" style="<%= aux_css[:common_width] %>">
|
36
|
+
<span class="dt">Итого:</span>
|
37
|
+
<span class="dd"><%= csample.summ_price %></span> руб.
|
38
|
+
</div>
|
39
|
+
|
40
|
+
</div>
|
41
|
+
|
42
|
+
<% end %>
|
43
|
+
</div>
|
@@ -11,14 +11,17 @@
|
|
11
11
|
<% obj[:offers].each do |offer| %>
|
12
12
|
<li>
|
13
13
|
<%= link_to offer.title, my_url_for_offer(offer), title: offer.title %>
|
14
|
+
<div class="offer_price"><%= offer.price %></div>
|
14
15
|
</li>
|
15
16
|
<% end %>
|
16
17
|
</ul>
|
17
18
|
</li>
|
18
19
|
<% else %>
|
19
|
-
<% obj[:offers].
|
20
|
-
|
20
|
+
<% obj[:offers].each_with_index do |offer, index| %>
|
21
|
+
<% k = index % 2 == 0 ? 'odd':'even' %>
|
22
|
+
<li class="<%=k%>">
|
21
23
|
<%= link_to offer.title, my_url_for_offer(offer), title: offer.title %>
|
24
|
+
<div class="offer_price"><%= offer.price %></div>
|
22
25
|
</li>
|
23
26
|
<% end %>
|
24
27
|
<% end %>
|