Commit 73f9c6f4 by ivan Lan

Add code about stock & Add validation uniq of buyer in Cart

parent 843c69a7
......@@ -30,6 +30,7 @@ module Shotengai
belongs_to :buyer, polymorphic: true, optional: true
default_scope { where(status: 'cart') }
validates_uniqueness_of :buyer_id, scope: [:buyer_type]
#
# class Order < Shotengai::Order
......
......@@ -2,47 +2,48 @@ module Shotengai
module Controller
module Customer
class ProductSnapshotsController < Shotengai::Controller::Base
self.resources = ProductSnapshot
self.template_dir = 'shotengai/customer/snapshots/'
# self.resources = ProductSnapshot
# self.template_dir = 'shotengai/customer/snapshots/'
before_action :buyer_auth
before_action :edit_only_unpaid, except: [:index, :show, :create]
default_query do |resource, params|
# /orders/:order_id/snapshots
# /series/:series_id/snapshots
resource.where(
params[:order_id] && { shotengai_order_id: params[:order_id] }
).where(
params[:series_id] && { shotengai_series_id: params[:series_id] }
)
end
# before_action :buyer_auth
# before_action :edit_only_unpaid, except: [:index, :show, :create]
# default_query do |resource, params|
# # /orders/:order_id/snapshots
# # /series/:series_id/snapshots
# p 'come here'
# resource.where(
# params[:order_id] && { shotengai_order_id: params[:order_id] }
# ).where(
# params[:series_id] && { shotengai_series_id: params[:series_id] }
# )
# end
index_query do |resource, params|
params[:in_cart] ? resource.in_cart : resource.in_order
end
# index_query do |resource, params|
# params[:in_cart] ? resource.in_cart : resource.in_order
# end
# 不指定 order 时,默认创建在 cart 中
# TODO: WARNING: snapshots
def create
order_or_cart = Shotengai::Order.find_by_id(params[:order_id]) || @buyer.order_cart
@resource = order_or_cart.product_snapshots.create!(resource_params)
respond_with @resource, template: "#{@@template_dir}/show", status: 201
end
# # 不指定 order 时,默认创建在 cart 中
# # TODO: WARNING: snapshots
# def create
# order_or_cart = Shotengai::Order.find_by_id(params[:order_id]) || @buyer.order_cart
# @resource = order_or_cart.product_snapshots.create!(resource_params)
# respond_with @resource, template: "#{@@template_dir}/show", status: 201
# end
private
def buyer_auth
@buyer = params[:buyer_type].constantize.find(params[:buyer_id])
end
# private
# def buyer_auth
# @buyer = params[:buyer_type].constantize.find(params[:buyer_id])
# end
def resource_params
params.require(resource_key).permit(
:count, :shotengai_series_id
)
end
# def resource_params
# params.require(resource_key).permit(
# :count, :shotengai_series_id
# )
# end
def edit_only_unpaid
raise Shotengai::WebError.new('订单已支付,不可修改。', '-1', 403) unless @resource.order.unpaid?
end
# def edit_only_unpaid
# raise Shotengai::WebError.new('订单已支付,不可修改。', '-1', 403) unless @resource.order.unpaid?
# end
end
end
end
......
......@@ -40,7 +40,7 @@ module Shotengai
state :unpaid, initial: true
state :paid, :delivering, :received, :canceled, :evaluated
event :pay, before: [:fill_snapshot, :set_pay_time] do
event :pay, before: [:fill_snapshot, :cut_stock, :set_pay_time] do
transitions from: :unpaid, to: :paid
end
......@@ -77,6 +77,12 @@ module Shotengai
}
end
def cut_stock
ActiveRecord::Base.transaction {
self.snapshots.each(&:cut_stock)
}
end
def set_pay_time
self.update!(pay_time: Time.now)
end
......
......@@ -6,7 +6,7 @@ module Shotengai
# id :integer not null, primary key
# original_price :decimal(9, 2)
# price :decimal(9, 2)
# stock :integer
# stock :integer default(-1)
# spec :json
# type :string(255)
# meta :json
......@@ -32,10 +32,13 @@ module Shotengai
# where(spec->'$.\"颜色\"' = ? and spec->'$.\"大小\"' = ? ,红色,S)
scope :query_spec_with_product, ->(val, product) {
return none unless val.keys.sort == product.spec.keys.sort
if val.keys.sort == product.spec.keys.sort
keys = []; values = []
val.map { |k, v| keys << "spec->'$.\"#{k}\"' = ? "; values << v }
where(keys.join(' and '), *values)
else
self.none
end
}
class << self
......@@ -56,8 +59,7 @@ module Shotengai
end
def cut_stock count
self.stock -= count
self.save!
self.stock.eql?(-1) || self.update!(stock: self.stock - count)
end
private
......@@ -71,7 +73,9 @@ module Shotengai
end
def uniq_spec
errors.add(:spec, 'Non uniq spec for the product.') if self.class.query_spec_with_product(self.spec, self.product).any?
if self.class.query_spec_with_product(self.spec, self.product).where.not(id: self.id).any?
errors.add(:spec, 'Non uniq spec for the product.')
end
end
def validate_stock
......
......@@ -72,6 +72,7 @@ module Shotengai
# 订单支付后 存储当时信息快照
def copy_info
# cut_stock
self.update!(
original_price: series.original_price,
price: series.price,
......@@ -83,6 +84,10 @@ module Shotengai
)
end
def cut_stock
self.series.cut_stock
end
def meta
read_attribute(:meta) || series.product.meta.merge(series.meta)
end
......
......@@ -5,7 +5,7 @@
# id :integer not null, primary key
# original_price :decimal(9, 2)
# price :decimal(9, 2)
# stock :integer
# stock :integer default(-1)
# spec :json
# type :string(255)
# meta :json
......@@ -18,7 +18,7 @@ FactoryGirl.define do
factory :test_series, class: 'TestGoodSeries' do
original_price 100
price 80
stock 10
# stock 10
spec {
{
"颜色" => "红色",
......@@ -41,7 +41,7 @@ FactoryGirl.define do
spec {
{
"颜色" => "红色",
"大小" => "S",
"大小" => "L",
}
}
# type
......
......@@ -67,20 +67,36 @@ RSpec.describe 'Shotengai Models' do
it 'validate' do
expect(@series.spec.class).to eq(Hash)
# 非法关键字
expect{
expect {
@series.update!(spec: {"颜色" => "红色", "大小" => 1111 })
}.to raise_error(ActiveRecord::RecordInvalid)
# 关键字缺失
# require 'irb'
# binding.irb
expect{
@series.update!(spec: {"颜色" => "红色"})
}.to raise_error(ActiveRecord::RecordInvalid)
# uniq validate about spec
expect {
TestGoodSeries.create!(
FactoryGirl.attribute_for(:test_series).merge(
FactoryGirl.attributes_for(:test_series).merge(
{test_good: @good}
)
)
}.to raise_error(ActiveRecord::RecordInvalid)
end
it 'About Stock' do
# 默认为 -1 (无限库存)
@series.cut_stock(1000)
expect(@series.reload.stock).to eq(-1)
# 非无限库存
@series.update!(stock: 10)
@series.cut_stock(10)
expect(@series.reload.stock).to eq(0)
expect {
@series.cut_stock(20)
}.to raise_error(ActiveRecord::RecordInvalid)
end
it 'Associations' do
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment