rshop 0.1.0
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 +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +1 -0
- data/app/controllers/ajax/rshop/products_controller.rb +12 -0
- data/app/controllers/rshop/.keep +0 -0
- data/app/controllers/rshop/auto_products_controller.rb +38 -0
- data/app/controllers/rshop/brands_controller.rb +9 -0
- data/app/controllers/rshop/cart_controller.rb +61 -0
- data/app/controllers/rshop/checkout_controller.rb +69 -0
- data/app/controllers/rshop/products_controller.rb +13 -0
- data/app/controllers/rshop/stock_requests_controller.rb +17 -0
- data/app/mailers/order_mailer.rb +13 -0
- data/app/views/order_mailer/feedback.html.slim +3 -0
- data/app/views/order_mailer/new_order.html.slim +33 -0
- data/app/views/rshop/address/_address_form.html.slim +27 -0
- data/app/views/rshop/admin/order/_address.html.slim +13 -0
- data/app/views/rshop/admin/order/_order_items.html.slim +7 -0
- data/app/views/rshop/brands/index.html.slim +6 -0
- data/app/views/rshop/brands/show.html.slim +4 -0
- data/app/views/rshop/cart/show.html.slim +74 -0
- data/app/views/rshop/checkout/form.html.slim +65 -0
- data/app/views/rshop/checkout/ty.html.slim +22 -0
- data/app/views/rshop/products/_list.html.slim +27 -0
- data/app/views/rshop/products/all.html.slim +1 -0
- data/app/views/rshop/products/index.html.slim +0 -0
- data/app/views/rshop/products/show.html.slim +67 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/config/locales/rshop.ru.yml +141 -0
- data/config/locales/rshop_autozap.ru.yml +88 -0
- data/config/routes.rb +2 -0
- data/lib/generators/rshop_autozap_generator.rb +30 -0
- data/lib/generators/rshop_generator.rb +38 -0
- data/lib/generators/rshop_price_log_generator.rb +30 -0
- data/lib/generators/rshop_views_generator.rb +17 -0
- data/lib/generators/templates/app/admin/dashboard.rb +37 -0
- data/lib/generators/templates/app/admin/rshop/brand.rb +24 -0
- data/lib/generators/templates/app/admin/rshop/delivery.rb +4 -0
- data/lib/generators/templates/app/admin/rshop/order.rb +55 -0
- data/lib/generators/templates/app/admin/rshop/payment.rb +4 -0
- data/lib/generators/templates/app/admin/rshop/product.rb +61 -0
- data/lib/generators/templates/app/controllers/rshop/.keep +0 -0
- data/lib/generators/templates/app/models/rshop/address.rb +11 -0
- data/lib/generators/templates/app/models/rshop/album.rb +11 -0
- data/lib/generators/templates/app/models/rshop/album_image.rb +7 -0
- data/lib/generators/templates/app/models/rshop/brand.rb +24 -0
- data/lib/generators/templates/app/models/rshop/delivery.rb +3 -0
- data/lib/generators/templates/app/models/rshop/order.rb +65 -0
- data/lib/generators/templates/app/models/rshop/order_item.rb +9 -0
- data/lib/generators/templates/app/models/rshop/payment.rb +3 -0
- data/lib/generators/templates/app/models/rshop/product.rb +88 -0
- data/lib/generators/templates/app/uploaders/rshop_album_image_uploader.rb +49 -0
- data/lib/generators/templates/app/uploaders/rshop_base_image_uploader.rb +63 -0
- data/lib/generators/templates/app/uploaders/rshop_brand_uploader.rb +7 -0
- data/lib/generators/templates/migration.rb +95 -0
- data/lib/generators/templates_autozap/app/admin/rshop/auto_category.rb +16 -0
- data/lib/generators/templates_autozap/app/admin/rshop/auto_mark.rb +15 -0
- data/lib/generators/templates_autozap/app/admin/rshop/auto_model.rb +16 -0
- data/lib/generators/templates_autozap/app/admin/rshop/auto_subcategory.rb +14 -0
- data/lib/generators/templates_autozap/app/admin/rshop/product.rb +66 -0
- data/lib/generators/templates_autozap/app/controllers/rshop/.keep +0 -0
- data/lib/generators/templates_autozap/app/models/rshop/auto_category.rb +15 -0
- data/lib/generators/templates_autozap/app/models/rshop/auto_mark.rb +11 -0
- data/lib/generators/templates_autozap/app/models/rshop/auto_model.rb +13 -0
- data/lib/generators/templates_autozap/app/models/rshop/auto_subcategory.rb +12 -0
- data/lib/generators/templates_autozap/app/models/rshop/product.rb +94 -0
- data/lib/generators/templates_autozap/app/views/rshop/auto/_filters.html.slim +18 -0
- data/lib/generators/templates_autozap/migration.rb +51 -0
- data/lib/generators/templates_price_log/app/models/rshop/price_log.rb +5 -0
- data/lib/generators/templates_price_log/migration.rb +11 -0
- data/lib/rshop.rb +47 -0
- data/lib/rshop/application_controller.rb +51 -0
- data/lib/rshop/auto_application_controller.rb +43 -0
- data/lib/rshop/price_adjustable_product.rb +30 -0
- data/lib/rshop/price_loggable_product.rb +19 -0
- data/lib/rshop/version.rb +3 -0
- data/rshop.gemspec +32 -0
- metadata +156 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 6ef6b28d414f9fea6d5c074b3b9b8334c889cd23
|
|
4
|
+
data.tar.gz: 4c279dfcaacc4fc5a285cc871c5cdaaa2bfe2a61
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 0b5dcacbb4ed1cd8ee06fdc74053fea0792b8f9e1d8b037f029b5c03843462a16b41fbea5eae1c1b2a7844b6c11a04409bbe43bc20f61a2f88cfb4e695558988
|
|
7
|
+
data.tar.gz: e51429e1a9792017964f9300601103850d72821a582b93a08a98c80e3ffaa9a70a509cc80f1b4a6db9ef0c2d85e55daf04af3024a951a9cff1b4f2852f7f1cba
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2015 ruslan.palagin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Rshop
|
|
2
|
+
|
|
3
|
+
Simple ecommerce solution for rails 4+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
1. Add this line to your application's Gemfile:
|
|
9
|
+
|
|
10
|
+
```ruby
|
|
11
|
+
gem 'rshop'
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
And then execute:
|
|
15
|
+
$ bundle install
|
|
16
|
+
|
|
17
|
+
2. Generate migrations, models and admin panel
|
|
18
|
+
$ rails g rshop
|
|
19
|
+
|
|
20
|
+
3. Run migrations
|
|
21
|
+
$ rake db:migrate
|
|
22
|
+
|
|
23
|
+
4. Put into routes.rb
|
|
24
|
+
```ruby
|
|
25
|
+
Rshop::Router.routes(self)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
Check new routes and extend existing code to match your requirements
|
|
31
|
+
$ rake routes
|
|
32
|
+
|
|
33
|
+
## Contributing
|
|
34
|
+
|
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/r1dd1ck777/rshop.
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
## License
|
|
39
|
+
|
|
40
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
|
41
|
+
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class Ajax::Rshop::ProductsController < ApplicationController
|
|
2
|
+
def search
|
|
3
|
+
products = Rshop::Product.frontend.where("name LIKE ?", "%#{params[:q]}%").limit(10)
|
|
4
|
+
arr = products.map{|product| {id: product.name, text: product.name} }
|
|
5
|
+
|
|
6
|
+
render text: {items: arr, page: current_page}.to_json
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def current_page
|
|
10
|
+
params[:page] ? params[:page] : 1
|
|
11
|
+
end
|
|
12
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
class Rshop::AutoProductsController < ApplicationController
|
|
2
|
+
def filter
|
|
3
|
+
qb = Rshop::Product.all
|
|
4
|
+
|
|
5
|
+
if params[:mark].present?
|
|
6
|
+
qb = qb.joins(:mark).where("#{Rshop::AutoMark.table_name}.name LIKE ?", "%#{params[:mark]}%")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
if params[:model].present?
|
|
10
|
+
qb = qb.joins(:model).where("#{Rshop::AutoModel.table_name}.name LIKE ?", "%#{params[:model]}%")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if params[:category].present?
|
|
14
|
+
qb = qb.joins(:category).where("#{Rshop::AutoCategory.table_name}.name LIKE ?", "%#{params[:category]}%")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
if params[:subcategory].present?
|
|
18
|
+
qb = qb.joins(:subcategory).where("#{Rshop::AutoSubcategory.table_name}.name LIKE ?", "%#{params[:subcategory]}%")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
set_auto_filters mark: params[:mark], model: params[:model], category: params[:category],
|
|
22
|
+
subcategory: params[:subcategory]
|
|
23
|
+
@products = qb.page(params[:page]).per(20)
|
|
24
|
+
|
|
25
|
+
render 'rshop/products/index'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def search
|
|
29
|
+
@product = Rshop::Product.find_by name: params[:q]
|
|
30
|
+
|
|
31
|
+
if @product
|
|
32
|
+
render 'rshop/products/show'
|
|
33
|
+
else
|
|
34
|
+
@products = Rshop::Product.search(params[:q]).page(params[:page]).per(20)
|
|
35
|
+
render 'rshop/products/index'
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
class Rshop::CartController < ::ApplicationController
|
|
2
|
+
after_action :check_cart_is_empty
|
|
3
|
+
|
|
4
|
+
def create_item
|
|
5
|
+
upsert_cart
|
|
6
|
+
|
|
7
|
+
product = Rshop::Product.find params[:product_id]
|
|
8
|
+
|
|
9
|
+
qty = order_item_params[:qty].to_i
|
|
10
|
+
qty = qty > 0 ? qty : 1
|
|
11
|
+
@cart.order_items.create! product: product,
|
|
12
|
+
qty: qty
|
|
13
|
+
@cart.save!
|
|
14
|
+
cart_counter product, qty
|
|
15
|
+
|
|
16
|
+
redirect_to root_path, flash: { success: t("rshop.cart_item.created", name: "\"#{product.name}\" (#{qty}шт.)") }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def delete_item
|
|
20
|
+
order_item = @cart.order_items.find(params[:id])
|
|
21
|
+
product = order_item.product
|
|
22
|
+
order_item.destroy!
|
|
23
|
+
|
|
24
|
+
redirect_to request.headers['referer'], flash: { info: t("rshop.cart_item.deleted", name: "\"#{product.name}\" (#{order_item.qty}шт.)") }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def delete
|
|
28
|
+
@cart.order_items.destroy_all
|
|
29
|
+
|
|
30
|
+
redirect_to cart_path, flash: { warning: ("rshop.cart.flushed") }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def update
|
|
34
|
+
@cart.update_attributes cart_params
|
|
35
|
+
|
|
36
|
+
redirect_to params[:buy_action].nil? ? cart_path : checkout_form_path
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def show
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
protected
|
|
43
|
+
|
|
44
|
+
def cart_counter product, qty
|
|
45
|
+
product.cart_count = product.cart_count + qty
|
|
46
|
+
product.save
|
|
47
|
+
rescue
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def cart_params
|
|
51
|
+
params.require(:rshop_order).permit(order_items_attributes: order_item_params_list)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def order_item_params
|
|
55
|
+
params.permit(order_item_params_list)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def order_item_params_list
|
|
59
|
+
[:qty, :id]
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
class Rshop::CheckoutController < ApplicationController
|
|
2
|
+
before_action :check_cart, except: [:ty]
|
|
3
|
+
|
|
4
|
+
def form
|
|
5
|
+
store_location_for :user, checkout_form_path
|
|
6
|
+
@cart.address = current_user.address.dup if user_signed_in?
|
|
7
|
+
@cart.validate_saving
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def save
|
|
11
|
+
@cart.attributes = address_params
|
|
12
|
+
|
|
13
|
+
@cart.status = Rshop::Order::STATUS_IN_Q
|
|
14
|
+
@cart.validate_saving
|
|
15
|
+
if @cart.save
|
|
16
|
+
sold_counter @cart
|
|
17
|
+
OrderMailer.new_order(@cart).deliver
|
|
18
|
+
set_cart_id nil
|
|
19
|
+
session[:last_cart_id] = @cart.id
|
|
20
|
+
merge_address current_user, @cart.address if current_user
|
|
21
|
+
|
|
22
|
+
redirect_to checkout_ty_path
|
|
23
|
+
else
|
|
24
|
+
|
|
25
|
+
render 'rshop/checkout/form'
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def ty
|
|
30
|
+
if session[:last_cart_id].present?
|
|
31
|
+
# use @order to track it in google analytics
|
|
32
|
+
@order = Rshop::Order.find session[:last_cart_id]
|
|
33
|
+
session[:last_cart_id] = nil
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
protected
|
|
38
|
+
|
|
39
|
+
def sold_counter order
|
|
40
|
+
order.order_items.each do |oi|
|
|
41
|
+
product = oi.product
|
|
42
|
+
product.sold_count = product.sold_count + qty
|
|
43
|
+
product.save
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
rescue
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def merge_address user, address
|
|
50
|
+
[:phone, :address, :username, :email].each do |attr|
|
|
51
|
+
user.address.send("#{attr}=", address.send(attr)) unless user.address.send(attr).present?
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
user.save
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def check_cart
|
|
58
|
+
redirect_to root_path if @cart.nil?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def address_params
|
|
62
|
+
params.require(:rshop_order)
|
|
63
|
+
.permit(
|
|
64
|
+
:rshop_payment_id, :rshop_delivery_id, :comments,
|
|
65
|
+
address_attributes: [
|
|
66
|
+
:phone, :address, :username, :email
|
|
67
|
+
])
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class Rshop::ProductsController < ApplicationController
|
|
2
|
+
def show
|
|
3
|
+
@product = Rshop::Product.frontend.find params[:slug]
|
|
4
|
+
@product.views_count = @product.views_count + 1
|
|
5
|
+
@product.save
|
|
6
|
+
# @category = @product.category
|
|
7
|
+
# apply_meta_tags @product
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def all
|
|
11
|
+
@products = Rshop::Product.frontend.page(params[:page]).per(20)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class Rshop::StockRequestsController < ApplicationController
|
|
2
|
+
def create
|
|
3
|
+
@req = Rshop::StockRequest.new get_params
|
|
4
|
+
|
|
5
|
+
if @req.save
|
|
6
|
+
product = Rshop::Product.find @req.rshop_product_id
|
|
7
|
+
redirect_to :back, flash: { success: t('rshop.stock_request.created', name: product.name) }
|
|
8
|
+
else
|
|
9
|
+
render :create
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
protected
|
|
14
|
+
def get_params
|
|
15
|
+
params.require(:rshop_stock_request).permit(:contact, :rshop_product_id, :comment)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class OrderMailer < ActionMailer::Base
|
|
2
|
+
def new_order(order)
|
|
3
|
+
@order = order
|
|
4
|
+
admin_emails = AdminUser.pluck(:email)
|
|
5
|
+
mail(to: admin_emails, subject: "Новый заказ #{order.id}")
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def feedback(feedback)
|
|
9
|
+
@feedback = feedback
|
|
10
|
+
admin_emails = AdminUser.pluck(:email)
|
|
11
|
+
mail(to: admin_emails, subject: "Вопрос от пользователя #{feedback.username}")
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
h4
|
|
2
|
+
= link_to "Заказ № #{@order.id}", admin_rshop_order_path(@order)
|
|
3
|
+
|
|
4
|
+
h4 Товары
|
|
5
|
+
= render 'rshop/admin/order/order_items', order_items: @order.order_items
|
|
6
|
+
|
|
7
|
+
h4 О заказе
|
|
8
|
+
ul
|
|
9
|
+
li Способ оплаты: #{@order.delivery.name}
|
|
10
|
+
li Способ доставки: #{@order.payment.name}
|
|
11
|
+
li Комментарии к заказу: #{@order.comments}
|
|
12
|
+
|
|
13
|
+
h4 Пользователь
|
|
14
|
+
ul
|
|
15
|
+
- if @order.user.present?
|
|
16
|
+
- user = @order.user
|
|
17
|
+
li
|
|
18
|
+
b id: #{user.id}
|
|
19
|
+
li Имя: #{user.try(:full_name)}
|
|
20
|
+
li email: #{user.email}
|
|
21
|
+
|
|
22
|
+
- else
|
|
23
|
+
li
|
|
24
|
+
b Гость
|
|
25
|
+
- if @order.address.username.present?
|
|
26
|
+
li Имя: #{@order.address.username}
|
|
27
|
+
|
|
28
|
+
h4 Адрес
|
|
29
|
+
ul
|
|
30
|
+
- @order.user.present?
|
|
31
|
+
li email: #{@order.user.email}
|
|
32
|
+
|
|
33
|
+
= render 'rshop/admin/order/address', address: @order.address
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
- address = f.object
|
|
2
|
+
/- is_user_edit = defined?(is_user_edit) ? is_user_edit : false
|
|
3
|
+
|
|
4
|
+
.form-group
|
|
5
|
+
= f.label :phone, class: 'form-label', required: address.validate_saving?
|
|
6
|
+
span
|
|
7
|
+
= f.full_error :phone
|
|
8
|
+
= f.input_field :phone, class: 'form-control'
|
|
9
|
+
|
|
10
|
+
.form-group
|
|
11
|
+
= f.label :address, class: 'form-label', required: address.validate_saving?
|
|
12
|
+
span
|
|
13
|
+
= f.full_error :address
|
|
14
|
+
= f.input_field :address, class: 'form-control'
|
|
15
|
+
|
|
16
|
+
.form-group
|
|
17
|
+
= f.label :username, class: 'form-label'
|
|
18
|
+
span
|
|
19
|
+
= f.full_error :username
|
|
20
|
+
= f.input_field :username, class: 'form-control'
|
|
21
|
+
|
|
22
|
+
.form-group
|
|
23
|
+
= f.label :email, class: 'form-label'
|
|
24
|
+
span
|
|
25
|
+
= f.full_error :email
|
|
26
|
+
= f.input_field :email, class: 'form-control'
|
|
27
|
+
|