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,2 @@
1
+ Rails.application.routes.draw do
2
+ end
@@ -0,0 +1,30 @@
1
+ class RshopAutozapGenerator < Rails::Generators::Base
2
+ include Rails::Generators::Migration
3
+ source_root File.expand_path("../templates_autozap", __FILE__)
4
+
5
+ def self.next_migration_number(dirname)
6
+ Time.now.strftime("%Y%m%d%H%M%S")
7
+ end
8
+
9
+ def create_all_migrations
10
+ migration_template "migration.rb", File.join('db/migrate', "create_rshop_autozap_tables.rb")
11
+ end
12
+
13
+ def create_model_files
14
+ [:auto_mark, :auto_model, :auto_category, :auto_subcategory, :product].each do |name|
15
+ copy_file "app/models/rshop/#{name}.rb"
16
+ end
17
+ end
18
+
19
+ def create_admin_files
20
+ [:auto_mark, :auto_model, :auto_category, :auto_subcategory, :product].each do |name|
21
+ copy_file "app/admin/rshop/#{name}.rb"
22
+ end
23
+ end
24
+
25
+ def create_views_files
26
+ %w(_filters.html.slim).each do |name|
27
+ copy_file "app/views/rshop/auto/#{name}"
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,38 @@
1
+ class RshopGenerator < Rails::Generators::Base
2
+ include Rails::Generators::Migration
3
+ source_root File.expand_path("../templates", __FILE__)
4
+
5
+ def self.next_migration_number(dirname)
6
+ Time.now.strftime("%Y%m%d%H%M%S")
7
+ end
8
+
9
+ # def create_initializer_file
10
+ # copy_file "config/initializers/cms.rb"
11
+ # end
12
+ #
13
+ def create_all_migrations
14
+ migration_template "migration.rb", File.join('db/migrate', "create_rshop_tables.rb")
15
+ end
16
+
17
+ def create_cw_uploaders_files
18
+ ['rshop_base_image_uploader.rb', 'rshop_brand_uploader.rb', 'rshop_album_image_uploader.rb'].each do |name|
19
+ copy_file "app/uploaders/#{name}"
20
+ end
21
+ end
22
+
23
+ def create_model_files
24
+ [:product, :brand, :album, :album_image, :address, :delivery, :payment, :order, :order_item].each do |name|
25
+ copy_file "app/models/rshop/#{name}.rb"
26
+ end
27
+ end
28
+
29
+ def create_admin_files
30
+ copy_file "app/admin/dashboard.rb"
31
+ [:product, :brand, :payment, :delivery, :order].each do |name|
32
+ copy_file "app/admin/rshop/#{name}.rb"
33
+ end
34
+ end
35
+
36
+ def create_locales_files
37
+ end
38
+ end
@@ -0,0 +1,30 @@
1
+ class RshopPriceLogGenerator < Rails::Generators::Base
2
+ include Rails::Generators::Migration
3
+ source_root File.expand_path("../templates_price_log", __FILE__)
4
+
5
+ def self.next_migration_number(dirname)
6
+ Time.now.strftime("%Y%m%d%H%M%S")
7
+ end
8
+
9
+ def create_all_migrations
10
+ migration_template "migration.rb", File.join('db/migrate', "create_rshop_price_log_tables.rb")
11
+ end
12
+
13
+ def create_model_files
14
+ [:price_log].each do |name|
15
+ copy_file "app/models/rshop/#{name}.rb"
16
+ end
17
+ end
18
+ #
19
+ # def create_admin_files
20
+ # [:auto_mark, :auto_model, :auto_category, :auto_subcategory, :product].each do |name|
21
+ # copy_file "app/admin/rshop/#{name}.rb"
22
+ # end
23
+ # end
24
+ #
25
+ # def create_views_files
26
+ # %w(_filters.html.slim).each do |name|
27
+ # copy_file "app/views/rshop/auto/#{name}"
28
+ # end
29
+ # end
30
+ end
@@ -0,0 +1,17 @@
1
+ class RshopViewsGenerator < Rails::Generators::Base
2
+ source_root File.expand_path("../../../", __FILE__)
3
+
4
+ def create_views_files
5
+ %w(_list.html.slim all.html.slim index.html.slim show.html.slim).each do |name|
6
+ copy_file "app/views/rshop/products/#{name}"
7
+ end
8
+
9
+ %w(show.html.slim).each do |name|
10
+ copy_file "app/views/rshop/cart/#{name}"
11
+ end
12
+
13
+ %w(show.html.slim).each do |name|
14
+ copy_file "app/views/rshop/checkout/#{name}"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,37 @@
1
+ class DashboardHelper
2
+ # fix error in migration
3
+ def self.get_orders
4
+ Rshop::Order.in_q.all
5
+ rescue
6
+ []
7
+ end
8
+ end
9
+
10
+ ActiveAdmin.register_page "Dashboard" do
11
+
12
+ menu priority: 1, label: proc{ I18n.t("active_admin.dashboard") }
13
+
14
+ orders = DashboardHelper.get_orders
15
+
16
+ content title: proc{ I18n.t("active_admin.dashboard") } do
17
+ div class: "blank_slate_container", id: "dashboard_default_message" do
18
+ span class: "blank_slate" do
19
+ if orders.count > 0
20
+ h2 "Заказы к обработке (#{orders.count}шт.)"
21
+ ul do
22
+ orders.each do |order|
23
+ li do
24
+ a href: admin_rshop_order_path(order) do
25
+ "##{order.id} на #{order.cost}грн"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ else
31
+ h2 "В ожидании новых заказов"
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,24 @@
1
+ ActiveAdmin.register Rshop::Brand do
2
+ permit_params :name, :description, :category_id,:image, :image_cache, :remove_image, :n, :slug
3
+
4
+ form do |f|
5
+ f.inputs do
6
+ f.input :name
7
+ f.input :n
8
+ f.input :slug
9
+ f.inputs "" do
10
+ f.cktext_area :description, :ckeditor => {:language => 'ru'}
11
+ end
12
+ f.inputs "" do
13
+ f.input :image, as: :file, :hint => f.object.image.default? ? '' : f.template.image_tag(f.object.image.url(:list))
14
+ f.input :image_cache, as: :hidden
15
+ f.input :remove_image, as: :boolean
16
+ end
17
+
18
+ f.actions
19
+ end
20
+ end
21
+
22
+ filter :name
23
+
24
+ end
@@ -0,0 +1,4 @@
1
+ ActiveAdmin.register Rshop::Delivery do
2
+ permit_params :name
3
+ config.filters = false
4
+ end
@@ -0,0 +1,55 @@
1
+ ActiveAdmin.register Rshop::Order do
2
+ actions :all, :except => [:new]
3
+ permit_params :status
4
+ # scope_to :current_user
5
+
6
+ form do |f|
7
+ f.inputs do
8
+ f.input :status, as: :radio, collection: Rshop::Order.status_options.invert
9
+ end
10
+ f.actions
11
+ end
12
+
13
+ index do
14
+ selectable_column
15
+ column :id
16
+ column :status do |o|
17
+ o.status_title
18
+ end
19
+ column :payment_and_delivery do |o|
20
+ "#{o.payment.try(:name)}, #{o.delivery.try(:name)}"
21
+ end
22
+ column :cost do |o|
23
+ "#{o.cost} грн"
24
+ end
25
+ column :updated_at
26
+ actions
27
+ end
28
+
29
+ show do |order|
30
+ attributes_table do
31
+ row :user
32
+ row :status do
33
+ order.status_title
34
+ end
35
+ row :payment
36
+ row :delivery
37
+ row :comments
38
+ row :order_items do
39
+ render 'rshop/admin/order/order_items', order_items: order.order_items
40
+ end
41
+ row :cost do
42
+ number_to_currency (order.cost)
43
+ end
44
+ row :address do
45
+ render 'rshop/admin/order/address', address: order.address
46
+ end
47
+ end
48
+ active_admin_comments
49
+ end
50
+
51
+ filter :status, label: I18n.t("activerecord.attributes.rshop/order.status"), as: :select, collection: Rshop::Order.status_options.invert
52
+ filter :payment
53
+ filter :delivery
54
+ filter :id
55
+ end
@@ -0,0 +1,4 @@
1
+ ActiveAdmin.register Rshop::Payment do
2
+ permit_params :name
3
+ config.filters = false
4
+ end
@@ -0,0 +1,61 @@
1
+ ActiveAdmin.register Rshop::Product do
2
+ permit_params :name, :price, :description, :code, :is_promotion, :slug, :is_published, :in_stock,
3
+ :category_id, :rshop_brand_id, :description_short,
4
+ album_attributes: [:id, :name, images_attributes: [:id, :image, :image_cache, :_destroy]],
5
+ category_ids: [], tag_ids: []
6
+
7
+ filter :brand
8
+ # filter :categories
9
+ filter :name
10
+ filter :code
11
+ filter :product
12
+
13
+ form do |f|
14
+ f.inputs do
15
+ f.input :name
16
+ f.input :price, as: :string, hint: I18n.t("activerecord.attributes.rshop/product.price_hint")
17
+ f.input :code
18
+ f.input :slug
19
+ f.input :is_promotion
20
+ f.input :is_published
21
+ f.input :in_stock
22
+
23
+ f.inputs I18n.t("activerecord.attributes.rshop/product.categories") do
24
+ # f.input :category, collection: Category.for_products.map{|u| [u.to_s_admin_selection, u.id]}, :prompt => false
25
+ f.input :brand
26
+ # f.input :categories, as: :select, multiple: true, collection: Category.for_products.map{|u| [u.to_s_admin_selection, u.id]}
27
+ # f.input :tags, as: :select, multiple: true
28
+ end
29
+
30
+ f.inputs I18n.t("activerecord.attributes.rshop/product.description") do
31
+ f.cktext_area :description, :ckeditor => {:language => 'ru'}
32
+ end
33
+ f.input :description_short, input_html: {rows: 3}
34
+
35
+ f.inputs I18n.t("activerecord.attributes.rshop/product.album"), :for => [:album, f.object.album ], label: false do |af|
36
+ af.has_many :images, allow_destroy: true, label: false, new_record: true do |imgf|
37
+ imgf.input :image, as: :file, label: false, :hint => imgf.object.image.default? ? '' : imgf.template.image_tag(imgf.object.image.url(:list))
38
+ imgf.input :image_cache, as: :hidden
39
+ end
40
+ end
41
+ end
42
+ f.actions
43
+ end
44
+
45
+ index do
46
+ selectable_column
47
+ column :name, sortable: :name do |o|
48
+ "#{o.name}"
49
+ end
50
+ # column :ctb
51
+ column :code
52
+ column :price
53
+ column :is_promotion
54
+ column :is_published
55
+ column :created_at
56
+ column :updated_at
57
+
58
+ actions
59
+ end
60
+
61
+ end
@@ -0,0 +1,11 @@
1
+ class Rshop::Address < ActiveRecord::Base
2
+ self.table_name = 'rshop_addresses'
3
+ belongs_to :addressable, polymorphic: true, touch: true
4
+ attr_accessor :validate_saving
5
+
6
+ validates :phone, :address, presence: true, if: :validate_saving
7
+
8
+ def validate_saving?
9
+ !!@validate_saving
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class Rshop::Album < ActiveRecord::Base
2
+ self.table_name = 'rshop_albums'
3
+ has_many :images, dependent: :destroy, class_name: Rshop::AlbumImage, foreign_key: :rshop_album_id
4
+ belongs_to :albumizable, polymorphic: true, touch: true
5
+
6
+ accepts_nested_attributes_for :images, :allow_destroy => true
7
+
8
+ def has_images?
9
+ images[0].present?
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ class Rshop::AlbumImage < ActiveRecord::Base
2
+ self.table_name = 'rshop_album_images'
3
+ belongs_to :album, touch: true, class_name: Rshop::Album, foreign_key: :rshop_album_id
4
+ mount_uploader :image, ::RshopAlbumImageUploader
5
+
6
+ delegate :url, to: :image
7
+ end
@@ -0,0 +1,24 @@
1
+ class Rshop::Brand < ActiveRecord::Base
2
+ self.table_name = 'rshop_brands'
3
+ extend FriendlyId
4
+ friendly_id :name, use: [:slugged, :finders]
5
+
6
+ has_many :products
7
+ mount_uploader :image, ::RshopBrandUploader
8
+
9
+ validates :name, presence: true
10
+
11
+ scope :by_category, -> category do
12
+ where(category_id: category.id)
13
+ end
14
+
15
+ scope :from_products, -> products do
16
+ joins(:products).where('products.id IN (?)', products.pluck(:id)).distinct
17
+ end
18
+
19
+ protected
20
+
21
+ def should_generate_new_friendly_id?
22
+ !slug.present?
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ class Rshop::Delivery < ActiveRecord::Base
2
+ self.table_name = 'rshop_deliveries'
3
+ end
@@ -0,0 +1,65 @@
1
+ class Rshop::Order < ActiveRecord::Base
2
+ self.table_name = 'rshop_orders'
3
+ STATUS_IN_BASKET = 1
4
+ STATUS_IN_Q = 2
5
+ STATUS_SOLD = 3
6
+ STATUS_REJECTED = 4
7
+
8
+ belongs_to :user, touch: true
9
+ belongs_to :payment, touch: true, class_name: Rshop::Payment, foreign_key: :rshop_payment_id
10
+ belongs_to :delivery, touch: true, class_name: Rshop::Delivery, foreign_key: :rshop_delivery_id
11
+ has_one :address, as: :addressable, dependent: :destroy, class_name: Rshop::Address
12
+ has_many :order_items, dependent: :destroy, class_name: Rshop::OrderItem, foreign_key: :rshop_order_id
13
+
14
+ accepts_nested_attributes_for :order_items, allow_destroy: true
15
+ accepts_nested_attributes_for :address
16
+
17
+ validates :payment, :delivery, presence: true, if: :validate_saving?
18
+
19
+ after_initialize :init
20
+
21
+ scope :in_q, -> {where(status: STATUS_IN_Q)}
22
+
23
+ def validate_saving val = true
24
+ self.address = Rshop::Address.new if self.address.nil?
25
+ address.validate_saving = @validate_saving = val
26
+ end
27
+
28
+ def validate_saving?
29
+ !!@validate_saving
30
+ end
31
+
32
+ def cost
33
+ self.order_items.inject(0) { |sum, oi| sum + oi.cost }
34
+ end
35
+
36
+ def has_items?
37
+ self.order_items.count > 0
38
+ end
39
+
40
+ def products_count
41
+ self.order_items.inject (0) { |sum, oi| sum + oi.qty }
42
+ end
43
+
44
+ def status_title
45
+ Rshop::Order.status_options[self.status]
46
+ end
47
+
48
+ def self.status_options
49
+ {
50
+ STATUS_IN_BASKET => I18n.t("rshop.order.status_#{STATUS_IN_BASKET}"),
51
+ STATUS_IN_Q => I18n.t("rshop.order.status_#{STATUS_IN_Q}"),
52
+ STATUS_SOLD => I18n.t("rshop.order.status_#{STATUS_SOLD}"),
53
+ STATUS_REJECTED => I18n.t("rshop.order.status_#{STATUS_REJECTED}"),
54
+ }
55
+ end
56
+
57
+ protected
58
+
59
+ def init
60
+ self.status ||= STATUS_IN_BASKET
61
+ unless persisted?
62
+ self.address = Rshop::Address.new if self.address.nil?
63
+ end
64
+ end
65
+ end