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.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +4 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +41 -0
  7. data/Rakefile +1 -0
  8. data/app/controllers/ajax/rshop/products_controller.rb +12 -0
  9. data/app/controllers/rshop/.keep +0 -0
  10. data/app/controllers/rshop/auto_products_controller.rb +38 -0
  11. data/app/controllers/rshop/brands_controller.rb +9 -0
  12. data/app/controllers/rshop/cart_controller.rb +61 -0
  13. data/app/controllers/rshop/checkout_controller.rb +69 -0
  14. data/app/controllers/rshop/products_controller.rb +13 -0
  15. data/app/controllers/rshop/stock_requests_controller.rb +17 -0
  16. data/app/mailers/order_mailer.rb +13 -0
  17. data/app/views/order_mailer/feedback.html.slim +3 -0
  18. data/app/views/order_mailer/new_order.html.slim +33 -0
  19. data/app/views/rshop/address/_address_form.html.slim +27 -0
  20. data/app/views/rshop/admin/order/_address.html.slim +13 -0
  21. data/app/views/rshop/admin/order/_order_items.html.slim +7 -0
  22. data/app/views/rshop/brands/index.html.slim +6 -0
  23. data/app/views/rshop/brands/show.html.slim +4 -0
  24. data/app/views/rshop/cart/show.html.slim +74 -0
  25. data/app/views/rshop/checkout/form.html.slim +65 -0
  26. data/app/views/rshop/checkout/ty.html.slim +22 -0
  27. data/app/views/rshop/products/_list.html.slim +27 -0
  28. data/app/views/rshop/products/all.html.slim +1 -0
  29. data/app/views/rshop/products/index.html.slim +0 -0
  30. data/app/views/rshop/products/show.html.slim +67 -0
  31. data/bin/console +14 -0
  32. data/bin/setup +7 -0
  33. data/config/locales/rshop.ru.yml +141 -0
  34. data/config/locales/rshop_autozap.ru.yml +88 -0
  35. data/config/routes.rb +2 -0
  36. data/lib/generators/rshop_autozap_generator.rb +30 -0
  37. data/lib/generators/rshop_generator.rb +38 -0
  38. data/lib/generators/rshop_price_log_generator.rb +30 -0
  39. data/lib/generators/rshop_views_generator.rb +17 -0
  40. data/lib/generators/templates/app/admin/dashboard.rb +37 -0
  41. data/lib/generators/templates/app/admin/rshop/brand.rb +24 -0
  42. data/lib/generators/templates/app/admin/rshop/delivery.rb +4 -0
  43. data/lib/generators/templates/app/admin/rshop/order.rb +55 -0
  44. data/lib/generators/templates/app/admin/rshop/payment.rb +4 -0
  45. data/lib/generators/templates/app/admin/rshop/product.rb +61 -0
  46. data/lib/generators/templates/app/controllers/rshop/.keep +0 -0
  47. data/lib/generators/templates/app/models/rshop/address.rb +11 -0
  48. data/lib/generators/templates/app/models/rshop/album.rb +11 -0
  49. data/lib/generators/templates/app/models/rshop/album_image.rb +7 -0
  50. data/lib/generators/templates/app/models/rshop/brand.rb +24 -0
  51. data/lib/generators/templates/app/models/rshop/delivery.rb +3 -0
  52. data/lib/generators/templates/app/models/rshop/order.rb +65 -0
  53. data/lib/generators/templates/app/models/rshop/order_item.rb +9 -0
  54. data/lib/generators/templates/app/models/rshop/payment.rb +3 -0
  55. data/lib/generators/templates/app/models/rshop/product.rb +88 -0
  56. data/lib/generators/templates/app/uploaders/rshop_album_image_uploader.rb +49 -0
  57. data/lib/generators/templates/app/uploaders/rshop_base_image_uploader.rb +63 -0
  58. data/lib/generators/templates/app/uploaders/rshop_brand_uploader.rb +7 -0
  59. data/lib/generators/templates/migration.rb +95 -0
  60. data/lib/generators/templates_autozap/app/admin/rshop/auto_category.rb +16 -0
  61. data/lib/generators/templates_autozap/app/admin/rshop/auto_mark.rb +15 -0
  62. data/lib/generators/templates_autozap/app/admin/rshop/auto_model.rb +16 -0
  63. data/lib/generators/templates_autozap/app/admin/rshop/auto_subcategory.rb +14 -0
  64. data/lib/generators/templates_autozap/app/admin/rshop/product.rb +66 -0
  65. data/lib/generators/templates_autozap/app/controllers/rshop/.keep +0 -0
  66. data/lib/generators/templates_autozap/app/models/rshop/auto_category.rb +15 -0
  67. data/lib/generators/templates_autozap/app/models/rshop/auto_mark.rb +11 -0
  68. data/lib/generators/templates_autozap/app/models/rshop/auto_model.rb +13 -0
  69. data/lib/generators/templates_autozap/app/models/rshop/auto_subcategory.rb +12 -0
  70. data/lib/generators/templates_autozap/app/models/rshop/product.rb +94 -0
  71. data/lib/generators/templates_autozap/app/views/rshop/auto/_filters.html.slim +18 -0
  72. data/lib/generators/templates_autozap/migration.rb +51 -0
  73. data/lib/generators/templates_price_log/app/models/rshop/price_log.rb +5 -0
  74. data/lib/generators/templates_price_log/migration.rb +11 -0
  75. data/lib/rshop.rb +47 -0
  76. data/lib/rshop/application_controller.rb +51 -0
  77. data/lib/rshop/auto_application_controller.rb +43 -0
  78. data/lib/rshop/price_adjustable_product.rb +30 -0
  79. data/lib/rshop/price_loggable_product.rb +19 -0
  80. data/lib/rshop/version.rb +3 -0
  81. data/rshop.gemspec +32 -0
  82. metadata +156 -0
@@ -0,0 +1,15 @@
1
+ class Rshop::AutoCategory < ActiveRecord::Base
2
+ self.table_name = 'rshop_auto_categories'
3
+ extend FriendlyId
4
+ friendly_id :name, use: [:slugged, :finders]
5
+ has_and_belongs_to_many :models, class_name: Rshop::AutoModel, join_table: :rshop_auto_models_to_categories,
6
+ foreign_key: :rshop_auto_category_id, association_foreign_key: :rshop_auto_model_id
7
+ has_and_belongs_to_many :subcategories, class_name: Rshop::AutoSubcategory, join_table: :rshop_auto_categories_to_subcategories,
8
+ foreign_key: :rshop_auto_category_id, association_foreign_key: :rshop_auto_subcategory_id
9
+
10
+
11
+ protected
12
+ def should_generate_new_friendly_id?
13
+ !slug.present?
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ class Rshop::AutoMark < ActiveRecord::Base
2
+ self.table_name = 'rshop_auto_marks'
3
+ extend FriendlyId
4
+ friendly_id :name, use: [:slugged, :finders]
5
+ has_many :models, dependent: :destroy, class_name: Rshop::AutoModel, foreign_key: :rshop_auto_mark_id
6
+
7
+ protected
8
+ def should_generate_new_friendly_id?
9
+ !slug.present?
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ class Rshop::AutoModel < ActiveRecord::Base
2
+ self.table_name = 'rshop_auto_models'
3
+ extend FriendlyId
4
+ friendly_id :name, use: [:slugged, :finders]
5
+ belongs_to :mark, class_name: Rshop::AutoMark, foreign_key: :rshop_auto_mark_id, touch: true
6
+ has_and_belongs_to_many :categories, class_name: Rshop::AutoCategory, join_table: :rshop_auto_models_to_categories,
7
+ foreign_key: :rshop_auto_model_id, association_foreign_key: :rshop_auto_category_id
8
+
9
+ protected
10
+ def should_generate_new_friendly_id?
11
+ !slug.present?
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ class Rshop::AutoSubcategory < ActiveRecord::Base
2
+ self.table_name = 'rshop_auto_subcategories'
3
+ extend FriendlyId
4
+ friendly_id :name, use: [:slugged, :finders]
5
+ has_and_belongs_to_many :categories, class_name: Rshop::AutoCategory, join_table: :rshop_auto_categories_to_subcategories,
6
+ foreign_key: :rshop_auto_subcategory_id, association_foreign_key: :rshop_auto_category_id
7
+
8
+ protected
9
+ def should_generate_new_friendly_id?
10
+ !slug.present?
11
+ end
12
+ end
@@ -0,0 +1,94 @@
1
+ class Rshop::Product < ActiveRecord::Base
2
+ self.table_name = 'rshop_products'
3
+ # ctb - cart to buy
4
+ # ctc - click to cart
5
+ extend FriendlyId
6
+ friendly_id :name, use: [:slugged, :finders]
7
+
8
+ has_one :album, as: :albumizable, dependent: :destroy, class_name: Rshop::Album
9
+ belongs_to :brand, touch: true, class_name: Rshop::Brand, foreign_key: :rshop_brand_id
10
+
11
+ belongs_to :mark, touch: true, class_name: Rshop::AutoMark, foreign_key: :rshop_auro_mark_id
12
+ belongs_to :model, touch: true, class_name: Rshop::AutoModel, foreign_key: :rshop_auto_model_id
13
+ belongs_to :category, touch: true, class_name: Rshop::AutoCategory, foreign_key: :rshop_auto_category_id
14
+ belongs_to :subcategory, touch: true, class_name: Rshop::AutoSubcategory, foreign_key: :rshop_auto_subcategory_id
15
+
16
+ accepts_nested_attributes_for :album, allow_destroy: true
17
+ after_initialize :init
18
+ before_save :calc_ctb, :calc_ctc
19
+
20
+ validates :name, :price, presence: true
21
+ validates :mark, :model, :category, :subcategory, presence: true
22
+
23
+ default_scope -> { where(is_published: true).order("cart_count desc").order('is_promotion desc') }
24
+
25
+ scope :order_by_smth, -> order_by do
26
+ order(order_by)
27
+ end
28
+
29
+ def get_name_font
30
+ case name.length
31
+ when 0..24
32
+ 'name-xs'
33
+ when 25..45
34
+ 'name-sm'
35
+ when 46..60
36
+ 'name-md'
37
+ else
38
+ 'name-lg'
39
+ end
40
+ end
41
+
42
+ def image_url variant = nil
43
+ image = self.album.images.first
44
+ path = image.try(:url, variant)
45
+ path ? path : Rshop::AlbumImage.new.url(variant)
46
+ end
47
+
48
+ protected
49
+
50
+ def calc_ctb
51
+ if cart_count + sold_count <= 0
52
+ self.ctb = 0
53
+ return
54
+ end
55
+
56
+ if sold_count == 0
57
+ self.sold_count = 1
58
+ end
59
+ self.ctb = sold_count / cart_count
60
+
61
+ rescue StandardError => e
62
+ p e.to_s
63
+ end
64
+
65
+ def calc_ctc
66
+ if views_count + cart_count <= 0
67
+ self.ctc = 0
68
+ return
69
+ end
70
+
71
+ if views_count == 0
72
+ self.views_count = 1
73
+ end
74
+ self.ctc = cart_count / views_count
75
+
76
+ rescue StandardError => e
77
+ p e.to_s
78
+ end
79
+
80
+ def remove_from_category category
81
+ category.products.delete self
82
+ end
83
+
84
+ def should_generate_new_friendly_id?
85
+ !slug.present?
86
+ end
87
+
88
+ def init
89
+ unless self.persisted?
90
+ self.in_stock = true
91
+ self.album = Rshop::Album.new if self.album.nil?
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,18 @@
1
+ form.search-form ng-controller="filtersController" method="get" action=filter_path
2
+ .form-group
3
+ select.form-control name="mark" ng-model="mark" ng-options="mark.name for mark in marks track by mark.name"
4
+ option value="" Выберите марку
5
+ .form-group
6
+ select.form-control name="model" ng-model="model" ng-disabled="!mark" disabled="disabled" ng-options="model.name for model in models track by model.name"
7
+ option value="" Выберите модель
8
+ .form-group
9
+ select.form-control name="category" ng-model="category" ng-disabled="!model" disabled="disabled" ng-options="category.name for category in categories track by category.name"
10
+ option value="" Выберите категорию
11
+ .form-group
12
+ select.form-control name="subcategory" ng-model="subcategory" ng-disabled="!category" disabled="disabled" ng-options="subcategory.name for subcategory in subcategories track by subcategory.name"
13
+ option value="" Выберите подкатегорию
14
+ .text-center
15
+ button.btn.btn-info.btn-sm type="submit" ng-disabled="!mark" disabled="disabled"
16
+ i.fa.l.fa-search
17
+ span Поиск
18
+ input type="hidden" name="sort" value="#{params[:sort] ? params[:sort] : 'name asc'}"
@@ -0,0 +1,51 @@
1
+ class CreateRshopAutozapTables < ActiveRecord::Migration
2
+ def change
3
+ create_table :rshop_auto_marks do |t|
4
+ t.string :name
5
+ t.string :slug
6
+
7
+ t.timestamps
8
+ end
9
+
10
+ create_table :rshop_auto_models do |t|
11
+ t.string :name
12
+ t.string :slug
13
+ t.belongs_to :rshop_auto_mark
14
+
15
+ t.timestamps
16
+ end
17
+
18
+ create_table :rshop_auto_models_to_categories do |t|
19
+ t.belongs_to :rshop_auto_model
20
+ t.belongs_to :rshop_auto_category
21
+
22
+ t.timestamps
23
+ end
24
+
25
+ create_table :rshop_auto_categories do |t|
26
+ t.string :name
27
+ t.string :slug
28
+
29
+ t.timestamps
30
+ end
31
+
32
+ create_table :rshop_auto_categories_to_subcategories do |t|
33
+ t.belongs_to :rshop_auto_category
34
+ t.belongs_to :rshop_auto_subcategory
35
+
36
+ t.timestamps
37
+ end
38
+
39
+ create_table :rshop_auto_subcategories do |t|
40
+ t.string :name
41
+ t.string :slug
42
+
43
+ t.timestamps
44
+ end
45
+
46
+ add_column :rshop_products, :rshop_auro_mark_id, :integer
47
+ add_column :rshop_products, :rshop_auto_model_id, :integer
48
+ add_column :rshop_products, :rshop_auto_category_id, :integer
49
+ add_column :rshop_products, :rshop_auto_subcategory_id, :integer
50
+ end
51
+ end
@@ -0,0 +1,5 @@
1
+ class Rshop::PriceLog < ActiveRecord::Base
2
+ self.table_name = 'rshop_price_logs'
3
+ belongs_to :product, class_name: Rshop::Product, foreign_key: :rshop_product_id
4
+ validates :price, presence: true
5
+ end
@@ -0,0 +1,11 @@
1
+ class CreateRshopAutozapTables < ActiveRecord::Migration
2
+ def change
3
+ create_table :rshop_price_logs do |t|
4
+ t.decimal :price, :precision => 6, :scale => 2, default: 0
5
+ t.belongs_to :rshop_product, index: true
6
+ t.boolean :in_stock
7
+
8
+ t.timestamps null: false
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,47 @@
1
+ require "rshop/version"
2
+
3
+ module Rshop
4
+ autoload :ApplicationController, 'rshop/application_controller'
5
+ autoload :AutoApplicationController, 'rshop/auto_application_controller'
6
+ autoload :PriceLoggableProduct, 'rshop/price_loggable_product'
7
+ autoload :PriceAdjustableProduct, 'rshop/price_adjustable_product'
8
+
9
+ class Engine < Rails::Engine
10
+ end
11
+
12
+ class Router
13
+ def self.routes router
14
+ router.instance_exec do
15
+ namespace :ajax do
16
+ namespace :rshop do
17
+ get 'products/search' => 'products#search', as: :products_search
18
+ end
19
+ end
20
+
21
+ scope :cart do
22
+ post 'items' => 'rshop/cart#create_item', as: :cart_items
23
+ delete 'items/:id' => 'rshop/cart#delete_item', as: :cart_item
24
+ get '' => 'rshop/cart#show', as: :cart
25
+ patch '' => 'rshop/cart#update'
26
+ delete '' => 'rshop/cart#delete'
27
+ end
28
+
29
+ scope :checkout do
30
+ patch 'save' => 'rshop/checkout#save', as: :checkout_save
31
+ get 'form' => 'rshop/checkout#form', as: :checkout_form
32
+ get 'ty' => 'rshop/checkout#ty', as: :checkout_ty
33
+ end
34
+
35
+ get 'products' => 'rshop/products#all', as: :products
36
+ get 'p-:slug' => 'rshop/products#show', as: :product
37
+
38
+ get 'brands' => 'rshop/brands#index', as: :brands
39
+ get 'b-:slug' => 'rshop/brands#show', as: :brand
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ ActiveSupport.on_load :action_controller do
46
+ include Rshop::ApplicationController
47
+ end
@@ -0,0 +1,51 @@
1
+ module Rshop
2
+ module ApplicationController
3
+ def self.included(base)
4
+ base.class_eval do
5
+ # extend Base
6
+ include ClassMethods
7
+ before_filter :setup_cart
8
+ end
9
+ end
10
+
11
+ module ClassMethods
12
+ # cart
13
+ def get_cart
14
+ id = get_cart_id
15
+ order = (Rshop::Order.find(id) rescue nil) unless id.nil?
16
+ set_cart_id nil if order.nil?
17
+ order
18
+ end
19
+
20
+ def get_cart_id
21
+ session[:cart_id]
22
+ end
23
+
24
+ def set_cart_id cart_id
25
+ session[:cart_id] = cart_id
26
+ cart_id
27
+ end
28
+
29
+ # cart other
30
+ def upsert_cart
31
+ @cart = new_cart if @cart.nil?
32
+ @cart
33
+ end
34
+
35
+ def new_cart
36
+ order = Rshop::Order.create!(user: current_user)
37
+ set_cart_id order.id
38
+ order
39
+ end
40
+
41
+ def check_cart_is_empty
42
+ @cart.destroy! unless @cart.nil? || @cart.has_items?
43
+ end
44
+
45
+ protected
46
+ def setup_cart
47
+ @cart = get_cart
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,43 @@
1
+ module Rshop
2
+ module AutoApplicationController
3
+ def self.included(base)
4
+ base.class_eval do
5
+ include ClassMethods
6
+ before_action :json_filters
7
+ end
8
+ end
9
+
10
+ module ClassMethods
11
+ def json_filters
12
+ return unless defined?(Rshop::AutoMark)
13
+
14
+ # @filters_json = Rails.cache.fetch("@filters_json<touch_filters_cache>v2", expires_in: 1.hour) do
15
+ marks = Rshop::AutoMark.all.order('name asc').includes(models: :categories)
16
+ @filters_json = marks.to_json(
17
+ only: [:id, :name],
18
+ include:{
19
+ models: {
20
+ only: [:id, :name],
21
+ include: {
22
+ :categories => {
23
+ only: [:id, :name],
24
+ include: {
25
+ subcategories: {
26
+ only: [:id, :name],
27
+ }
28
+ }
29
+ }
30
+ }
31
+ },
32
+ }
33
+ )
34
+ # end
35
+ end
36
+
37
+ def set_auto_filters options = {}
38
+ # form = Hash [:mark, :model, :category, :subcategory].map{ |name| [options[name] ? options[name] : :null] }
39
+ @auto_filters_json = options.to_json
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,30 @@
1
+ module Rshop::PriceAdjustableProduct
2
+ def self.extended(model_class)
3
+ model_class.class_eval do
4
+ include InstanceMethods
5
+ before_save :apply_adjustment
6
+ end
7
+ end
8
+
9
+ module InstanceMethods
10
+ def apply_adjustment
11
+ return nil unless adj_opt_price > 0 && (adj_percent > 0 || adj_val > 0)
12
+ self.price = (adj_opt_price + ((adj_opt_price / 100) * adj_percent) + adj_val).round(2)
13
+ end
14
+
15
+ def adj_opt_price
16
+ val = read_attribute :adj_opt_price
17
+ val.present? ? val : 0
18
+ end
19
+
20
+ def adj_percent
21
+ val = read_attribute :adj_percent
22
+ val.present? ? val : 0
23
+ end
24
+
25
+ def adj_val
26
+ val = read_attribute :adj_val
27
+ val.present? ? val : 0
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,19 @@
1
+ module Rshop::PriceLoggableProduct
2
+ def self.extended(model_class)
3
+ model_class.class_eval do
4
+ has_many :price_logs, class_name: Rshop::PriceLog, foreign_key: :rshop_product_id
5
+ include InstanceMethods
6
+ before_save :add_price_log
7
+ end
8
+ end
9
+
10
+ module InstanceMethods
11
+ def add_price_log
12
+ if price_changed? || in_stock_changed?
13
+ price_logs.where('created_at >= ?', Time.now.strftime('%F'))
14
+ .where('created_at < ?', (Time.now + 1.day).strftime('%F')).destroy_all
15
+ price_logs.create(price: price, in_stock: in_stock)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module Rshop
2
+ VERSION = "0.1.0"
3
+ end