Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shop Cart implementation #963

Open
wants to merge 3 commits into
base: shop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ gem 'redis', '~>3.2'
gem 'sidekiq'
gem 'sidekiq-scheduler', '~> 2.1.4'
gem 'simple_form'
gem 'font-awesome-rails'

gem 'courses', path: 'components/courses'
gem 'shop', path: 'components/shop'
Expand Down
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ GEM
faraday (1.0.1)
multipart-post (>= 1.2, < 3)
ffi (1.12.2)
font-awesome-rails (4.7.0.7)
railties (>= 3.2, < 7)
formatador (0.2.5)
friendly_id (5.3.0)
activerecord (>= 4.0.0)
Expand Down Expand Up @@ -650,6 +652,7 @@ DEPENDENCIES
ez-settings
factory_bot_rails
faker
font-awesome-rails
friendly_id (~> 5.1)
gibbon (~> 3.0)
groupdate (~> 4.0)
Expand Down
1 change: 1 addition & 0 deletions app/assets/stylesheets/app/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

@import "https://fonts.googleapis.com/css2?family=Oswald&display=swap'";
@import "local_fonts";
@import "font-awesome";

@import "normalize";

Expand Down
25 changes: 25 additions & 0 deletions app/assets/stylesheets/app/base/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,28 @@ q {
.pk-no-display {
display: none !important;
}

.shopping_cart-icon {
display: inline-block;
position: fixed;
left: 1450px;
opacity: 80%;

&:hover {
opacity: 100%;
}
}

.cart_table {
margin: 40px;

table {
border-collapse: collapse;
width: 100%;
}

th, td {
text-align: left;
padding: 8px;
}
}
2 changes: 0 additions & 2 deletions app/helpers/admin/events_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ def event_status_label(event)
class: ['ui label', BG_STATUS_CLASS[event.status.to_sym]]
end

# rubocop:disable Metrics/AbcSize
def event_visitors(event)
requested = event.pending_visit_requests.length
approved = event.approved_visit_requests.length
Expand All @@ -56,7 +55,6 @@ def event_visitors(event)
t('events.index.visitors.visited') => visited
}
end
# rubocop:enable Metrics/AbcSize

def event_verified_user_data(event)
verified = event.verified_visitors.length
Expand Down
1 change: 1 addition & 0 deletions app/views/layouts/application.slim
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ html
link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16"
link rel="manifest" href="/manifest.json"
link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"
link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.13.0/css/all.css"
== render 'layouts/ga/head' if Rails.env.production?

body.pk-main-layout class="#{yield(:main_body_class)}"
Expand Down
8 changes: 8 additions & 0 deletions components/shop/app/controllers/shop/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ module Shop
class BaseController < ApplicationController
before_action :authenticate_user!

helper_method :current_order

def current_order
return unless session[:order_id]

@current_order ||= Shop::Order.find_by(id: session[:order_id])
end

private

def render_form
Expand Down
44 changes: 44 additions & 0 deletions components/shop/app/controllers/shop/order_items_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true

module Shop
class OrderItemsController < BaseController
helper_method :item, :order_items

def create
order_item = ::Shop::OrderItem.new(item_id: item.id, order_id: order_id, price: item.price)
order_item.save

redirect_to shop_items_path
end

def update
OrderItemService.new(order_item).increase_quantity!
redirect_to shop_order_items_path
end

def destroy
OrderItemService.new(order_item).reduce_quantity!
redirect_to shop_order_items_path
end

private

def order_items
@order_items ||= Shop::OrderItem.includes(:item).map do |order_item|
Shop::OrderItemDecorator.new(order_item)
end
end

def order_item
@order_items ||= Shop::OrderItem.find(params[:id])
end

def item
@items ||= Shop::Item.find(params[:item_id])
end

def order_id
session[:order_id] ||= Shop::Order.create.id
end
end
end
4 changes: 4 additions & 0 deletions components/shop/app/decorators/shop/base_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module Shop
class BaseDecorator < SimpleDelegator
end
end
7 changes: 7 additions & 0 deletions components/shop/app/decorators/shop/order_item_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Shop
class OrderItemDecorator < BaseDecorator
def sum
price * quantity
end
end
end
6 changes: 6 additions & 0 deletions components/shop/app/helpers/shop/item_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

module Shop
module ItemHelper
end
end
1 change: 1 addition & 0 deletions components/shop/app/models/shop/item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class Item < ApplicationRecord
self.table_name = 'shop_items'

has_many :item_images
has_many :order_items
accepts_nested_attributes_for :item_images

scope :active, -> { where(published: true) }
Expand Down
26 changes: 26 additions & 0 deletions components/shop/app/models/shop/order.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

# status: shopping_cart, placed, processing, shipping, complete, canceled
# user: optional
# buyer: anonymous user
# shipment_address

module Shop
class Order < ApplicationRecord
self.table_name = 'shop_orders'

enum status: { shopping_cart: 0, placed: 1, processing: 2, shipping: 3, complete: 4, canceled: 5 }

has_many :order_items
has_many :items, through: :order_items

# TODO: OrderDecorator
# def total_sum
# order_items.map(&:price).sum.to_f
# end

# def order_items_count
# order_items.count
# end
end
end
12 changes: 12 additions & 0 deletions components/shop/app/models/shop/order_item.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

module Shop
class OrderItem < ApplicationRecord
self.table_name = 'shop_order_items'

validates_uniqueness_of :item_id

belongs_to :order
belongs_to :item
end
end
21 changes: 21 additions & 0 deletions components/shop/app/services/shop/order_item_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Shop
class OrderItemService
attr_reader :order_item

def initialize(order_item)
@order_item = order_item
end

def increase_quantity!
order_item.increment!(:quantity)
end

def reduce_quantity!
if order_item.quantity > 1
order_item.decrement!(:quantity)
else
order_item.destroy!
end
end
end
end
4 changes: 3 additions & 1 deletion components/shop/app/uploaders/item_image_uploader.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# frozen_string_literal: true

class ItemImageUploader < CarrierWave::Uploader::Base
end
end
15 changes: 14 additions & 1 deletion components/shop/app/views/shop/items/index.slim
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
h2.main-header Shop

- if current_order.present?
span.shopping_cart-icon
= link_to shop_order_items_path do
i.fas.fa-shopping-cart.fa-8x
div.item_counts
span
= current_order.order_items_count

.main
ul.cards
- items.each do |item|
Expand All @@ -9,4 +17,9 @@ h2.main-header Shop
.card_content
h2.card_title = item.name
p.card_text = item.description
button.btn.card_btn Add to cart
- if current_order.present? && current_order.items.include?(item)
= link_to shop_order_items_path do
button.btn.card_btn Added to the cart
- else
= link_to shop_order_items_path(item_id: item.id), method: :post do
button.btn.card_btn Add to cart
32 changes: 32 additions & 0 deletions components/shop/app/views/shop/order_items/index.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
h2.main-header Cart

.cart_table
- if current_order.present? && current_order.order_items.any?
table
thead
tr
th Image
th.company Name
th.company Price
th.count Count
tbody
- order_items.each do |item|
tr
td= image_tag item.item.item_images.first.image_url(:small).to_s, class: 'card_image' if item.item.item_images.first.try(:image_url)
td= item.item.name
td= item.sum
td
div
= link_to shop_order_item_path(item.id), method: :delete do
i.fas.fa-minus

= item.quantity

= link_to shop_order_item_path(item.id), method: :put do
i.fas.fa-plus

.total_sum
h2 Total
h2= current_order.total_sum
- else
h1 Your cart is empty for now
1 change: 1 addition & 0 deletions components/shop/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Rails.application.routes.draw do
namespace :shop do
resources :items, only: %i[index]
resources :order_items, only: %i[index create update destroy]
end

namespace :admin do
Expand Down
10 changes: 10 additions & 0 deletions components/shop/db/migrate/20210611210804_create_orders.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

class CreateOrders < ActiveRecord::Migration[5.2]
def change
create_table :shop_orders do |t|
t.integer :status, default: 0
t.text :shipment_address
end
end
end
12 changes: 12 additions & 0 deletions components/shop/db/migrate/20210611211002_create_order_items.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

class CreateOrderItems < ActiveRecord::Migration[5.2]
def change
create_table :shop_order_items do |t|
t.integer :quantity, default: 1
t.decimal :price, null: false
t.references :item
t.references :order
end
end
end
2 changes: 1 addition & 1 deletion components/shop/shop.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ Gem::Specification.new do |spec|

spec.add_dependency 'rails', '~> 5.2.2', '>= 5.2.2.1'

spec.add_dependency 'carrierwave', '~> 1.2'
spec.add_dependency 'friendly_id'
spec.add_dependency 'kaminari'
spec.add_dependency 'simple_form'
spec.add_dependency 'slim-rails'
spec.add_dependency 'carrierwave', '~> 1.2'

spec.add_development_dependency 'capybara'
spec.add_development_dependency 'faker'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@
*
*= require_tree .
*= require_self
*= require font-awesome
*/
16 changes: 15 additions & 1 deletion components/shop/spec/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20_210_514_113_103) do
ActiveRecord::Schema.define(version: 20_210_611_211_002) do
create_table 'shop_item_images', force: :cascade do |t|
t.string 'image'
t.integer 'item_id'
Expand All @@ -30,4 +30,18 @@
t.datetime 'created_at', null: false
t.datetime 'updated_at', null: false
end

create_table 'shop_order_items', force: :cascade do |t|
t.integer 'quantity'
t.decimal 'price', null: false
t.integer 'item_id'
t.integer 'order_id'
t.index ['item_id'], name: 'index_shop_order_items_on_item_id'
t.index ['order_id'], name: 'index_shop_order_items_on_order_id'
end

create_table 'shop_orders', force: :cascade do |t|
t.integer 'status', default: 0
t.text 'shipment_address'
end
end
7 changes: 7 additions & 0 deletions components/shop/spec/factories/order_factory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

FactoryBot.define do
factory :order, class: Shop::Order do
shipment_address { 'Lviv, Pivorak street' }
end
end
7 changes: 7 additions & 0 deletions components/shop/spec/factories/order_item_factory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

FactoryBot.define do
factory :order_item, class: Shop::OrderItem do
price { 12 }
end
end
Loading