Class: Beecart::Cart

Inherits:
Object
  • Object
show all
Defined in:
lib/beecart/cart.rb

Overview

カートに入れた商品をRedisサーバー上に保存させるためのラッパー

商品情報以外に

  • 顧客情報

    • 送り先住所

    • 受取先住所

    • カード情報

  • カート作成日時

  • カート更新日時

などの情報も保存することが可能。

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cart_id = nil) ⇒ Cart

Returns a new instance of Cart.



30
31
32
33
34
# File 'lib/beecart/cart.rb', line 30

def initialize(cart_id=nil)
  @redis = Redis.new(Beecart.config.redis)
  @key   = cart_id.nil? ? SecureRandom.hex : cart_id
  @data  = data
end

Instance Attribute Details

#dataHash

保存されているデーターをredisから取り出す。

Returns:

  • (Hash)


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/beecart/cart.rb', line 26

class Cart

  attr_reader :key

  def initialize(cart_id=nil)
    @redis = Redis.new(Beecart.config.redis)
    @key   = cart_id.nil? ? SecureRandom.hex : cart_id
    @data  = data
  end

  # 保存されているデーターをredisから取り出す。
  #
  # @return [Hash]
  def data
    if @data
      @data
    else
      load_data(@redis.get(@key))
    end
  end

  # カート内のitemsを返却
  #
  # @return [Hash]
  def items
    data[:items]
  end

  # カート内の商品の合計金額を計算する
  #
  # @return [Integer] 税抜き合計金額
  def total_price
    data[:items].inject(0) do |res, (key, item)|
      res += item[:price].to_i * item[:quantity].to_i
      res.to_i
    end
  end

  # カート内の商品の税込み合計金額を計算する
  #
  # @return [Integer] 税込み合計金額
  def total_price_with_tax
    data[:items].inject(0) do |res, (key, item)|
      res += item[:price].to_i * item[:quantity].to_i * Beecart.config.tax_rate
      res.ceil.to_i
    end
  end

  # 指定された商品を追加する
  #
  # @param [Hash] item_info 追加する商品の情報
  # @option item_info [Integer] :price 商品の値段
  # @option item_info [Integer] :quantity (0) 購入希望個数
  def add_item(item_info={ quantity: 0})

    unless item_info.has_key?(:price)
      raise Error,"Price needs to be passed when adding a item to cart."
    end

    unless item_info.has_key?(:quantity)
      raise Error, "Quantity needs to be passed when adding a item to cart."
    end

    @data[:items][rand_key] = item_info

    dump_data
  end

  # 購入データを追加する
  #
  # @param [String] key 追加するデータの識別子
  # @param [Hash] data 追加するデータ
  # @return [Boolean]
  def append_info(key, data)
    if send(key.to_s + '_validate', data)
      @data[key.to_sym] = data
      dump_data
    else
      false
    end
  end

  # 指定されたkeyのアイテムを削除する
  #
  # @param [String] key 削除するアイテムのレコード
  def remove_item(key)
    @data[:items].delete(key.to_sym)

    dump_data
  end

  # 指定されたkeyにあるデータのquantityを変更する
  #
  # @param [String] key
  # @param [Integer] quantity
  # @return [Boolean]
  def change_quantity_of key, quantity
    @data[:items][key][:quantity] = quantity

    dump_data
  end

  # Redisから削除
  def destroy
    @redis.del(@key)
  end

  # 仮計上(与信)をとる
  #
  # @param  [Hash] payment_info 支払情報
  # @return [WebPay::Charge]
  def authorize payment_info={}
    gateway.authorize total_price_with_tax, payment_info
  end

  # 本計上を取る
  #
  # @param  [Hash] payment_info 支払情報
  # @return [WebPay::Charge]
  def charge payment_info={}
    gateway.charge total_price_with_tax, payment_info
  end

  private

  def gateway name=nil
    klass = name.nil? ?
      gateway_class_name(Beecart.config.default_gateway).constantize :
      gateway_class_name(name).constantize

    klass.new
  end

  def gateway_class_name name
    ["Beecart::Gateway::",name.to_s.camelize,"Gateway"].join('')
  end

  # Redis内から取ってきたデータをデシリアイズして返却。
  # またdataがnilの場合はdataのひな形を返却
  #
  # @param [Hash, nil]
  def load_data(data)
    if data.nil?
      {
        items: {},
        user_id: nil,
        shipping_address: {},
        billing_address: {},
        credit_card: {},
        shipping_instruction: {},
        created_at: Time.now.to_s,
        updated_at: Time.now.to_s
      }
    else
      symbolize(MessagePack.unpack(data))
    end
  end

  # Redis内のデータを書き換える
  def dump_data
    @data[:updated_at] = Time.now.to_s
    @redis.set(@key, @data.to_msgpack)
    @redis.expire(@key, Beecart.config.expire_time)
  end

  # ランダムな文字列を生成
  def rand_key
    (0...8).map { (65 + rand(26)).chr }.join.to_sym
  end

  # HashのKeyをシンボルにして返却
  # @return シンボルにされたHash
  def symbolize hash
    hash.inject({}) do |res,(key, val)|
      res[key.to_sym] = val.is_a?(Hash) ? symbolize(val) : val
      res
    end
  end
end

#keyString (readonly)

Returns カートを識別するためのランダムな文字列.

Returns:

  • (String)

    カートを識別するためのランダムな文字列



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/beecart/cart.rb', line 26

class Cart

  attr_reader :key

  def initialize(cart_id=nil)
    @redis = Redis.new(Beecart.config.redis)
    @key   = cart_id.nil? ? SecureRandom.hex : cart_id
    @data  = data
  end

  # 保存されているデーターをredisから取り出す。
  #
  # @return [Hash]
  def data
    if @data
      @data
    else
      load_data(@redis.get(@key))
    end
  end

  # カート内のitemsを返却
  #
  # @return [Hash]
  def items
    data[:items]
  end

  # カート内の商品の合計金額を計算する
  #
  # @return [Integer] 税抜き合計金額
  def total_price
    data[:items].inject(0) do |res, (key, item)|
      res += item[:price].to_i * item[:quantity].to_i
      res.to_i
    end
  end

  # カート内の商品の税込み合計金額を計算する
  #
  # @return [Integer] 税込み合計金額
  def total_price_with_tax
    data[:items].inject(0) do |res, (key, item)|
      res += item[:price].to_i * item[:quantity].to_i * Beecart.config.tax_rate
      res.ceil.to_i
    end
  end

  # 指定された商品を追加する
  #
  # @param [Hash] item_info 追加する商品の情報
  # @option item_info [Integer] :price 商品の値段
  # @option item_info [Integer] :quantity (0) 購入希望個数
  def add_item(item_info={ quantity: 0})

    unless item_info.has_key?(:price)
      raise Error,"Price needs to be passed when adding a item to cart."
    end

    unless item_info.has_key?(:quantity)
      raise Error, "Quantity needs to be passed when adding a item to cart."
    end

    @data[:items][rand_key] = item_info

    dump_data
  end

  # 購入データを追加する
  #
  # @param [String] key 追加するデータの識別子
  # @param [Hash] data 追加するデータ
  # @return [Boolean]
  def append_info(key, data)
    if send(key.to_s + '_validate', data)
      @data[key.to_sym] = data
      dump_data
    else
      false
    end
  end

  # 指定されたkeyのアイテムを削除する
  #
  # @param [String] key 削除するアイテムのレコード
  def remove_item(key)
    @data[:items].delete(key.to_sym)

    dump_data
  end

  # 指定されたkeyにあるデータのquantityを変更する
  #
  # @param [String] key
  # @param [Integer] quantity
  # @return [Boolean]
  def change_quantity_of key, quantity
    @data[:items][key][:quantity] = quantity

    dump_data
  end

  # Redisから削除
  def destroy
    @redis.del(@key)
  end

  # 仮計上(与信)をとる
  #
  # @param  [Hash] payment_info 支払情報
  # @return [WebPay::Charge]
  def authorize payment_info={}
    gateway.authorize total_price_with_tax, payment_info
  end

  # 本計上を取る
  #
  # @param  [Hash] payment_info 支払情報
  # @return [WebPay::Charge]
  def charge payment_info={}
    gateway.charge total_price_with_tax, payment_info
  end

  private

  def gateway name=nil
    klass = name.nil? ?
      gateway_class_name(Beecart.config.default_gateway).constantize :
      gateway_class_name(name).constantize

    klass.new
  end

  def gateway_class_name name
    ["Beecart::Gateway::",name.to_s.camelize,"Gateway"].join('')
  end

  # Redis内から取ってきたデータをデシリアイズして返却。
  # またdataがnilの場合はdataのひな形を返却
  #
  # @param [Hash, nil]
  def load_data(data)
    if data.nil?
      {
        items: {},
        user_id: nil,
        shipping_address: {},
        billing_address: {},
        credit_card: {},
        shipping_instruction: {},
        created_at: Time.now.to_s,
        updated_at: Time.now.to_s
      }
    else
      symbolize(MessagePack.unpack(data))
    end
  end

  # Redis内のデータを書き換える
  def dump_data
    @data[:updated_at] = Time.now.to_s
    @redis.set(@key, @data.to_msgpack)
    @redis.expire(@key, Beecart.config.expire_time)
  end

  # ランダムな文字列を生成
  def rand_key
    (0...8).map { (65 + rand(26)).chr }.join.to_sym
  end

  # HashのKeyをシンボルにして返却
  # @return シンボルにされたHash
  def symbolize hash
    hash.inject({}) do |res,(key, val)|
      res[key.to_sym] = val.is_a?(Hash) ? symbolize(val) : val
      res
    end
  end
end

#redisObject (readonly)

Returns redisとのコネクションを持ったオブジェクト.

Returns:

  • (Object)

    redisとのコネクションを持ったオブジェクト



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/beecart/cart.rb', line 26

class Cart

  attr_reader :key

  def initialize(cart_id=nil)
    @redis = Redis.new(Beecart.config.redis)
    @key   = cart_id.nil? ? SecureRandom.hex : cart_id
    @data  = data
  end

  # 保存されているデーターをredisから取り出す。
  #
  # @return [Hash]
  def data
    if @data
      @data
    else
      load_data(@redis.get(@key))
    end
  end

  # カート内のitemsを返却
  #
  # @return [Hash]
  def items
    data[:items]
  end

  # カート内の商品の合計金額を計算する
  #
  # @return [Integer] 税抜き合計金額
  def total_price
    data[:items].inject(0) do |res, (key, item)|
      res += item[:price].to_i * item[:quantity].to_i
      res.to_i
    end
  end

  # カート内の商品の税込み合計金額を計算する
  #
  # @return [Integer] 税込み合計金額
  def total_price_with_tax
    data[:items].inject(0) do |res, (key, item)|
      res += item[:price].to_i * item[:quantity].to_i * Beecart.config.tax_rate
      res.ceil.to_i
    end
  end

  # 指定された商品を追加する
  #
  # @param [Hash] item_info 追加する商品の情報
  # @option item_info [Integer] :price 商品の値段
  # @option item_info [Integer] :quantity (0) 購入希望個数
  def add_item(item_info={ quantity: 0})

    unless item_info.has_key?(:price)
      raise Error,"Price needs to be passed when adding a item to cart."
    end

    unless item_info.has_key?(:quantity)
      raise Error, "Quantity needs to be passed when adding a item to cart."
    end

    @data[:items][rand_key] = item_info

    dump_data
  end

  # 購入データを追加する
  #
  # @param [String] key 追加するデータの識別子
  # @param [Hash] data 追加するデータ
  # @return [Boolean]
  def append_info(key, data)
    if send(key.to_s + '_validate', data)
      @data[key.to_sym] = data
      dump_data
    else
      false
    end
  end

  # 指定されたkeyのアイテムを削除する
  #
  # @param [String] key 削除するアイテムのレコード
  def remove_item(key)
    @data[:items].delete(key.to_sym)

    dump_data
  end

  # 指定されたkeyにあるデータのquantityを変更する
  #
  # @param [String] key
  # @param [Integer] quantity
  # @return [Boolean]
  def change_quantity_of key, quantity
    @data[:items][key][:quantity] = quantity

    dump_data
  end

  # Redisから削除
  def destroy
    @redis.del(@key)
  end

  # 仮計上(与信)をとる
  #
  # @param  [Hash] payment_info 支払情報
  # @return [WebPay::Charge]
  def authorize payment_info={}
    gateway.authorize total_price_with_tax, payment_info
  end

  # 本計上を取る
  #
  # @param  [Hash] payment_info 支払情報
  # @return [WebPay::Charge]
  def charge payment_info={}
    gateway.charge total_price_with_tax, payment_info
  end

  private

  def gateway name=nil
    klass = name.nil? ?
      gateway_class_name(Beecart.config.default_gateway).constantize :
      gateway_class_name(name).constantize

    klass.new
  end

  def gateway_class_name name
    ["Beecart::Gateway::",name.to_s.camelize,"Gateway"].join('')
  end

  # Redis内から取ってきたデータをデシリアイズして返却。
  # またdataがnilの場合はdataのひな形を返却
  #
  # @param [Hash, nil]
  def load_data(data)
    if data.nil?
      {
        items: {},
        user_id: nil,
        shipping_address: {},
        billing_address: {},
        credit_card: {},
        shipping_instruction: {},
        created_at: Time.now.to_s,
        updated_at: Time.now.to_s
      }
    else
      symbolize(MessagePack.unpack(data))
    end
  end

  # Redis内のデータを書き換える
  def dump_data
    @data[:updated_at] = Time.now.to_s
    @redis.set(@key, @data.to_msgpack)
    @redis.expire(@key, Beecart.config.expire_time)
  end

  # ランダムな文字列を生成
  def rand_key
    (0...8).map { (65 + rand(26)).chr }.join.to_sym
  end

  # HashのKeyをシンボルにして返却
  # @return シンボルにされたHash
  def symbolize hash
    hash.inject({}) do |res,(key, val)|
      res[key.to_sym] = val.is_a?(Hash) ? symbolize(val) : val
      res
    end
  end
end

Instance Method Details

#add_item(item_info = { quantity: 0}) ⇒ Object

指定された商品を追加する

Parameters:

  • item_info (Hash) (defaults to: { quantity: 0})

    追加する商品の情報

Options Hash (item_info):

  • :price (Integer)

    商品の値段

  • :quantity (Integer) — default: 0

    購入希望個数



79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/beecart/cart.rb', line 79

def add_item(item_info={ quantity: 0})

  unless item_info.has_key?(:price)
    raise Error,"Price needs to be passed when adding a item to cart."
  end

  unless item_info.has_key?(:quantity)
    raise Error, "Quantity needs to be passed when adding a item to cart."
  end

  @data[:items][rand_key] = item_info

  dump_data
end

#append_info(key, data) ⇒ Boolean

購入データを追加する

Parameters:

  • key (String)

    追加するデータの識別子

  • data (Hash)

    追加するデータ

Returns:

  • (Boolean)


99
100
101
102
103
104
105
106
# File 'lib/beecart/cart.rb', line 99

def append_info(key, data)
  if send(key.to_s + '_validate', data)
    @data[key.to_sym] = data
    dump_data
  else
    false
  end
end

#authorize(payment_info = {}) ⇒ WebPay::Charge

仮計上(与信)をとる

Parameters:

  • payment_info (Hash) (defaults to: {})

    支払情報

Returns:

  • (WebPay::Charge)


137
138
139
# File 'lib/beecart/cart.rb', line 137

def authorize payment_info={}
  gateway.authorize total_price_with_tax, payment_info
end

#change_quantity_of(key, quantity) ⇒ Boolean

指定されたkeyにあるデータのquantityを変更する

Parameters:

  • key (String)
  • quantity (Integer)

Returns:

  • (Boolean)


122
123
124
125
126
# File 'lib/beecart/cart.rb', line 122

def change_quantity_of key, quantity
  @data[:items][key][:quantity] = quantity

  dump_data
end

#charge(payment_info = {}) ⇒ WebPay::Charge

本計上を取る

Parameters:

  • payment_info (Hash) (defaults to: {})

    支払情報

Returns:

  • (WebPay::Charge)


145
146
147
# File 'lib/beecart/cart.rb', line 145

def charge payment_info={}
  gateway.charge total_price_with_tax, payment_info
end

#destroyObject

Redisから削除



129
130
131
# File 'lib/beecart/cart.rb', line 129

def destroy
  @redis.del(@key)
end

#itemsHash

カート内のitemsを返却

Returns:

  • (Hash)


50
51
52
# File 'lib/beecart/cart.rb', line 50

def items
  data[:items]
end

#remove_item(key) ⇒ Object

指定されたkeyのアイテムを削除する

Parameters:

  • key (String)

    削除するアイテムのレコード



111
112
113
114
115
# File 'lib/beecart/cart.rb', line 111

def remove_item(key)
  @data[:items].delete(key.to_sym)

  dump_data
end

#total_priceInteger

カート内の商品の合計金額を計算する

Returns:

  • (Integer)

    税抜き合計金額



57
58
59
60
61
62
# File 'lib/beecart/cart.rb', line 57

def total_price
  data[:items].inject(0) do |res, (key, item)|
    res += item[:price].to_i * item[:quantity].to_i
    res.to_i
  end
end

#total_price_with_taxInteger

カート内の商品の税込み合計金額を計算する

Returns:

  • (Integer)

    税込み合計金額



67
68
69
70
71
72
# File 'lib/beecart/cart.rb', line 67

def total_price_with_tax
  data[:items].inject(0) do |res, (key, item)|
    res += item[:price].to_i * item[:quantity].to_i * Beecart.config.tax_rate
    res.ceil.to_i
  end
end