This repository has been archived by the owner on Jan 6, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1294e25
commit 9ce5008
Showing
22 changed files
with
484 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
class Api::V1::OrdersController < ApplicationController | ||
def index | ||
@orders = Order.all | ||
render json: @orders | ||
end | ||
|
||
def create | ||
@order = Order.new(order_params) | ||
|
||
if @order.save | ||
render json: { | ||
message: 'Order Successfully Placed!', | ||
order: @order | ||
} | ||
else | ||
render json: { | ||
message: 'Failed to place order.', | ||
errors: [] | ||
}, status: :bad_request | ||
end | ||
end | ||
|
||
def prices | ||
@order = Order.new(order_params) | ||
prices = OrderPriceService.new.calculate_prices(@order) | ||
render json: prices | ||
end | ||
|
||
private | ||
|
||
def order_params | ||
params.require(:order).permit( | ||
order_items_attributes: %i[product_id quantity] | ||
) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
class Api::V1::ProductsController < ApplicationController | ||
def index | ||
products = ProductService.new.available_products | ||
products = Product.all | ||
render json: products | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
class Order < ApplicationRecord | ||
validates :shipping_price, numericality: { greater_than_or_equal_to: 0 } | ||
validates :total_price, numericality: { greater_than: 0 } | ||
|
||
has_many :order_items, dependent: :destroy, autosave: true | ||
accepts_nested_attributes_for :order_items, reject_if: :all_blank | ||
|
||
before_validation :update_prices | ||
before_validation :ensure_items_present | ||
|
||
def as_json(_options) | ||
super( | ||
include: { | ||
order_items: { | ||
only: %i[product_id quantity], | ||
methods: %i[product_name unit_price] | ||
} | ||
} | ||
) | ||
end | ||
|
||
private | ||
|
||
def update_prices | ||
prices = OrderPriceService.new.calculate_prices(self) | ||
self.shipping_price = prices[:shipping_price] | ||
self.total_price = prices[:total_price] | ||
true | ||
end | ||
|
||
def ensure_items_present | ||
errors.add(:order_items, 'must contain at least 1 item') unless total_qty.positive? | ||
end | ||
|
||
def total_qty | ||
order_items.map(&:quantity).sum | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
class OrderItem < ApplicationRecord | ||
belongs_to :order | ||
belongs_to :product | ||
|
||
default_scope { includes(:product) } | ||
|
||
validates :order, :product, presence: true | ||
validates :quantity, numericality: { greater_than: 0, only_integer: true } | ||
|
||
delegate :name, to: :product, prefix: :product | ||
delegate :unit_price, to: :product | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
class Product < ApplicationRecord | ||
validates :name, presence: true | ||
validates :unit_price, numericality: { greater_than: 0 } | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
class OrderPriceService | ||
def calculate_prices(order) | ||
total_qty = 0 | ||
shipping_price = 30 | ||
total_price = 0 | ||
|
||
order.order_items.each do |item| | ||
total_qty += item.quantity | ||
total_price += item.quantity * item.unit_price | ||
end | ||
|
||
shipping_price = 0 if total_qty >= 10 | ||
total_price *= 0.9 if total_qty > 20 | ||
|
||
{ | ||
total_price: total_price + shipping_price, | ||
shipping_price: shipping_price | ||
} | ||
end | ||
end |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
class CreateOrders < ActiveRecord::Migration[6.0] | ||
def change | ||
create_table :orders do |t| | ||
t.integer :shipping_price, null: false | ||
t.float :total_price, null: false | ||
|
||
t.timestamps | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
class CreateProducts < ActiveRecord::Migration[6.0] | ||
def change | ||
create_table :products do |t| | ||
t.string :name, null: false | ||
t.float :unit_price, null: false | ||
|
||
t.timestamps | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
class CreateOrderItems < ActiveRecord::Migration[6.0] | ||
def change | ||
create_table :order_items do |t| | ||
t.references :order, null: false, foreign_key: true | ||
t.references :product, null: false, foreign_key: true | ||
t.integer :quantity, null: false | ||
|
||
t.timestamps | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
# This file should contain all the record creation needed to seed the database with its default values. | ||
# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup). | ||
# | ||
# Examples: | ||
# | ||
# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) | ||
# Character.create(name: 'Luke', movie: movies.first) | ||
# In lieu of a CMS for managing products, we will just seed the db | ||
Product.create( | ||
[ | ||
{ name: 'High Quality', unit_price: 20 }, | ||
{ name: 'Premium', unit_price: 30 } | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
class Api::V1::OrdersControllerTest < ActionDispatch::IntegrationTest | ||
test 'should return expected orders in json format' do | ||
expected = Order.all | ||
get api_v1_orders_path | ||
assert_response :ok | ||
assert_equal expected.to_json, @response.body | ||
end | ||
|
||
test 'should create order' do | ||
assert_difference 'Order.count', 1 do | ||
post api_v1_orders_path, params: { | ||
order_items_attributes: [ | ||
{ product_id: products(:one).id, quantity: 1 } | ||
] | ||
}, as: :json | ||
end | ||
assert_includes @response.body, products(:one).name | ||
assert_response :ok | ||
end | ||
|
||
test 'should not create order without items' do | ||
assert_no_difference 'Order.count', 1 do | ||
post api_v1_orders_path, params: { order_items_attributes: [] }, as: :json | ||
end | ||
assert_response :bad_request | ||
end | ||
|
||
test 'should calculate price' do | ||
expected = { 'shipping_price' => 30, 'total_price' => 40 } | ||
post api_v1_orders_calculate_price_path, params: { | ||
order_items_attributes: [ | ||
{ product_id: products(:one).id, quantity: 1 } | ||
] | ||
}, as: :json | ||
json = JSON.parse(@response.body) | ||
assert_equal expected['shipping_price'], json['shipping_price'] | ||
assert_equal expected['total_price'], json['total_price'] | ||
assert_response :ok | ||
end | ||
|
||
test 'should calculate price with no items' do | ||
expected = { 'shipping_price' => 30, 'total_price' => 30 } | ||
post api_v1_orders_calculate_price_path, params: { | ||
order_items_attributes: [] | ||
}, as: :json | ||
json = JSON.parse(@response.body) | ||
assert_equal expected['shipping_price'], json['shipping_price'] | ||
assert_equal expected['total_price'], json['total_price'] | ||
assert_response :ok | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html | ||
item_one: | ||
product: one | ||
order: order_one | ||
quantity: 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html | ||
order_one: | ||
shipping_price: 30 | ||
total_price: 50 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html | ||
one: | ||
name: "Test Product" | ||
unit_price: 10 | ||
|
||
two: | ||
name: "Test Product 2" | ||
unit_price: 5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
require 'test_helper' | ||
|
||
class OrderItemTest < ActiveSupport::TestCase | ||
def setup | ||
@order = Order.new | ||
@product = products(:one) | ||
@order_item = @order.order_items.build( | ||
product: @product, | ||
quantity: 1 | ||
) | ||
end | ||
|
||
test 'should be valid' do | ||
assert @order_item.valid? | ||
end | ||
|
||
test 'should have order' do | ||
@order_item.order = nil | ||
assert_not @order_item.valid? | ||
end | ||
|
||
test 'should have product' do | ||
@order_item.product = nil | ||
assert_not @order_item.valid? | ||
end | ||
|
||
test 'should have quantity' do | ||
@order_item.quantity = nil | ||
assert_not @order_item.valid? | ||
end | ||
|
||
test 'should have positive quantity' do | ||
@order_item.quantity = 0 | ||
assert_not @order_item.valid? | ||
@order_item.quantity = -10 | ||
assert_not @order_item.valid? | ||
end | ||
end |
Oops, something went wrong.