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

CI確認用 #9

Closed
wants to merge 12 commits into from
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ Layout/LineLength:
Hc/RailsSpecificActionName:
Exclude:
- app/controllers/users/omniauth_callbacks_controller.rb
- app/controllers/promotion_codes_controller.rb
3 changes: 2 additions & 1 deletion app/controllers/admin/orders_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ def index
def show
@order = Order.find(params[:id])
@ordered_cart_products = @order.cart.cart_products.order(created_at: :desc)
@total = @ordered_cart_products.inject(0) { |total, cart_product| total + cart_product.subtotal }
@promotion_code = @order.cart.promotion_code
@total = @order.cart.calc_total
end
end
end
10 changes: 3 additions & 7 deletions app/controllers/cart_products_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
class CartProductsController < ApplicationController
before_action :set_cart

def index
@cart_products = Cart.find(@cart.id).cart_products.order(created_at: :desc)
@total = @cart_products.inject(0) { |total, cart_product| total + cart_product.subtotal }
end

def create
product_id = params[:product_id]
quantity = params[:quantity].to_i
Expand All @@ -23,7 +18,8 @@ def create
end

def destroy
CartProduct.find(params[:id]).destroy
redirect_to request.referer
cart_product = CartProduct.find(params[:id])
cart_product.destroy
redirect_to request.referer, flash: { success: "#{cart_product.product.name}を削除しました。" }
end
end
13 changes: 10 additions & 3 deletions app/controllers/orders_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

class OrdersController < ApplicationController
before_action :set_cart
before_action :set_promotion_code, only: %i[index create]
before_action :set_cart_products, only: %i[index create]

def index
Expand All @@ -14,14 +15,16 @@ def create

error_messages = @cart.set_validate_error_messages
if error_messages.size.positive?
flash.now['danger'] = error_messages.join('<br/>')
flash.now[:danger] = error_messages.join('<br/>')
render :index
return
end

if @order.save
session[:cart_id] = nil
flash[:success] = '購入ありがとうございます'
flash[:success] = '購入ありがとうございます。'
# Modelのselfはシリアライズされるためメール送信はコントローラに記載
OrderMailer.complete(order: @order).deliver_later
redirect_to products_path
else
render :index
Expand All @@ -35,8 +38,12 @@ def order_params
credit_name credit_number credit_expiration credit_cvv])
end

def set_promotion_code
@promotion_code = @cart.promotion_code
end

def set_cart_products
@cart_products = @cart.cart_products.order(created_at: :desc)
@total = @cart_products.inject(0) { |total, cart_product| total + cart_product.subtotal }
@total = @cart.calc_total
end
end
33 changes: 33 additions & 0 deletions app/controllers/promotion_codes_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

class PromotionCodesController < ApplicationController
before_action :set_cart

def register
if params[:code].empty?
redirect_to request.referer, flash: { danger: 'コードを入力してください' }
return
end

code = params[:code]
promotion_code = PromotionCode.find_by(code:, order_id: nil)

if promotion_code
Cart.update(@cart.id, promotion_code_id: promotion_code.id)
redirect_to request.referer, flash: { success: 'プロモーションコードを登録しました。' }
else
redirect_to request.referer, flash: { danger: '入力したコードが間違っているか、すでに使用済です。' }
end
end

def cancel
Cart.update(@cart.id, promotion_code_id: nil)
redirect_to request.referer, flash: { success: 'プロモーションコードを解除しました。' }
end

private

def promotion_code_params
params.require(:promotion_code).permit(%i[code])
end
end
3 changes: 2 additions & 1 deletion app/mailers/order_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ def complete(order:)
@order = order
recipient = @order.email
@ordered_cart_products = @order.cart.cart_products.order(created_at: :desc)
@total = @ordered_cart_products.inject(0) { |total, cart_product| total + cart_product.subtotal }
@promotion_code = @order.cart.promotion_code
@total = @order.cart.calc_total
mail(to: recipient, subject: '注文内容ご確認')
end
end
30 changes: 23 additions & 7 deletions app/models/cart.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,13 @@
class Cart < ApplicationRecord
has_many :cart_products, dependent: :destroy
has_many :products, through: :cart_products
belongs_to :promotion_code, optional: true

def set_validate_error_messages
messages = []
messages << 'カートに商品が入っていません。' if cart_products.empty?

cart_products
.select { |cart_product| cart_product.quantity > cart_product.product.stock }
.map do |cart_product|
product = cart_product.product
messages << "#{product.name}が注文可能数を超えています。最大注文可能数:#{product.stock}個"
end
messages << 'プロモーションコードがすでに使用済です。' if promotion_code&.order_id.present?
set_out_of_stock_messages(messages:)

messages
end
Expand All @@ -24,4 +20,24 @@ def decrease_product_stock
Product.update(cart_product.product.id, stock: cart_product.product.stock - quantity)
end
end

def calc_total
total = cart_products.inject(0) { |result, cart_product| result + cart_product.subtotal }
if promotion_code
total -= promotion_code.discount
total = 0 if total.negative?
end
total
end

private

def set_out_of_stock_messages(messages:)
cart_products
.select { |cart_product| cart_product.quantity > cart_product.product.stock }
.map do |cart_product|
product = cart_product.product
messages << "#{product.name}が注文可能数を超えています。最大注文可能数:#{product.stock}個"
end
end
end
14 changes: 13 additions & 1 deletion app/models/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ class Order < ApplicationRecord

before_create do
cart.decrease_product_stock
OrderMailer.complete(order: @order).deliver_later
end

after_create do
update_promotion_code
end

private

def update_promotion_code
promotion_code = cart.promotion_code
return unless promotion_code && promotion_code.order_id.nil?

PromotionCode.update(promotion_code.id, order_id: id)
end
end
6 changes: 6 additions & 0 deletions app/models/promotion_code.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

class PromotionCode < ApplicationRecord
belongs_to :order, optional: true
has_many :carts, dependent: :nullify
end
2 changes: 1 addition & 1 deletion app/views/admin/orders/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<p class="lead">名義:<%= @order.credit_name %></p>
<p class="lead">有効期限:<%= @order.credit_expiration %></p>
</div>
<%= render 'shared/ordered_cart_products', :ordered_cart_products => @ordered_cart_products, :total => @total %>
<%= render 'shared/ordered_cart_products', :ordered_cart_products => @ordered_cart_products, :total => @total, :promotion_code => @promotion_code %>
</div>
<!-- Footer-->
<footer class="py-5 bg-dark">
Expand Down
2 changes: 1 addition & 1 deletion app/views/order_mailer/complete.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
<h1 class="display-5 fw-bolder"><%= "#{@order.last_name} #{@order.first_name}様" %></h1>
<p>ご購入ありがとうございます。購入明細をお送りいたしますので、下記内容にてご確認ください。</p>
</div>
<%= render 'shared/ordered_cart_products', :ordered_cart_products => @ordered_cart_products, :total => @total %>
<%= render 'shared/ordered_cart_products', :ordered_cart_products => @ordered_cart_products, :total => @total, :promotion_code => @promotion_code %>
</div>
34 changes: 18 additions & 16 deletions app/views/orders/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,31 @@
</div>
</li>
<% end %>
<li class="list-group-item d-flex justify-content-between bg-body-tertiary">
<div class="text-success">
<h6 class="my-0">プロモコード</h6>
<small>DF97M2D</small>
</div>
<div>
<span class="text-success">−0円</span>
<%= link_to orders_path, data: {"turbo-method": :delete }, class: "btn btn-outline-danger" do %>
<i class="bi-trash"></i>
<% end %>
</div>
</li>
<% if @promotion_code %>
<li class="list-group-item d-flex justify-content-between bg-body-tertiary">
<div class="text-success">
<h6 class="my-0">プロモコード</h6>
<small><%= @promotion_code.code %></small>
</div>
<div>
<span class="text-success">-<%= convert_to_jpy(@promotion_code.discount)%></span>
<%= link_to cancel_promotion_code_path, data: {"turbo-method": :post }, class: "btn btn-outline-danger" do %>
<i class="bi-trash"></i>
<% end %>
</div>
</li>
<% end %>
<li class="list-group-item d-flex justify-content-between">
<span>お支払い金額</span>
<strong><%= convert_to_jpy(@total) %></strong>
</li>
</ul>
<form class="card p-2">
<%= form_with url: register_promotion_code_path, method: :post, data: { turbo: false }, class: "card p-2" do |f| %>
<div class="input-group">
<input type="text" class="form-control" placeholder="プロモコードを入力">
<button class="btn btn-secondary">利用する</button>
<%= f.text_field :code, class: "form-control", placeholder: "プロモコードを入力" %>
<button class="btn btn-secondary" type="submit">利用する</button>
</div>
</form>
<% end %>
</div>
<div class="col-md-7 col-lg-6">
<h4 class="mb-3">お届け先情報</h4>
Expand Down
11 changes: 10 additions & 1 deletion app/views/shared/_ordered_cart_products.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,20 @@
<td class="text-end"><%= convert_to_jpy(cart_product.subtotal) %></td>
</tr>
<% end %>
<% if promotion_code %>
<tr>
<th scope="row" class="text-success">プロモーションコード</th>
<td class="text-success">コード:<%= promotion_code.code %></td>
<td class="text-end text-success">-<%= convert_to_jpy(promotion_code.discount) %></td>
<td class="text-end text-success">1</td>
<td class="text-end text-success">-<%= convert_to_jpy(promotion_code.discount) %></td>
</tr>
<% end %>
<tr>
<th></th>
<td></td>
<td></td>
<td><strong>合計金額</strong></td>
<td class="text-end"><strong>合計金額</strong></td>
<td class="text-end"><%= convert_to_jpy(total) %></td>
</tr>
</tbody>
Expand Down
3 changes: 3 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
resources :orders, only: %i[index create]
root 'products#index'

post 'register_promotion_code', to: 'promotion_codes#register'
post 'cancel_promotion_code', to: 'promotion_codes#cancel'

# ルーティングが存在しないパスへアクセスしたとき、ルートへリダイレクトする。
# この際、'rails/active_storage'が含まれているパスはリダイレクト対象外にする
get '*path', to: redirect('/'), constraints: ->(req) { req.path.exclude? 'rails/active_storage' }
Expand Down
13 changes: 13 additions & 0 deletions db/migrate/20230912091841_create_promotion_codes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

class CreatePromotionCodes < ActiveRecord::Migration[7.0]
def change
create_table :promotion_codes do |t|
t.string :code, null: false
t.integer :discount, null: false
t.references :order, null: true, foreign_key: true

t.timestamps
end
end
end
7 changes: 7 additions & 0 deletions db/migrate/20230912130015_add_references_to_carts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class AddReferencesToCarts < ActiveRecord::Migration[7.0]
def change
add_reference :carts, :promotion_code, null: true, foreign_key: true
end
end
15 changes: 14 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions lib/tasks/promotion_code.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

namespace :promotion_code do
task generate: :environment do
10.times do
code = SecureRandom.alphanumeric(7)
discount = rand(1..10) * 100
PromotionCode.create(code:, discount:)
puts "コード #{code} で#{discount}円割引"
end
end
end
7 changes: 7 additions & 0 deletions spec/models/promotion_code_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe PromotionCode, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end
9 changes: 9 additions & 0 deletions spec/requests/promotion_codes_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe 'PromotionCodes', type: :request do
describe 'GET /index' do
pending "add some examples (or delete) #{__FILE__}"
end
end
Loading