Skip to content

Commit fedb812

Browse files
authored
Merge pull request #42 from gomicorp/hotfix/kpi
핫픽스 : KPI 로직 추가
2 parents 166c0c0 + 4c76b98 commit fedb812

File tree

3 files changed

+200
-39
lines changed

3 files changed

+200
-39
lines changed

app/models/cart.rb

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,41 @@ def initialize(cart)
66
@items = cart.items
77
end
88

9-
def price_sum
10-
items.map(&:price_sum).sum
9+
# def price_sum
10+
# items.map(&:price_sum).sum
11+
# end
12+
13+
# 품목 단위 수량 합계
14+
def unit_count
15+
items.map(&:unit_count_sum).sum
16+
end
17+
18+
# 정가 합계
19+
def base_price
20+
items.map(&:base_price).sum
1121
end
1222

23+
# 정가 총 합계
24+
def base_price_sum
25+
items.map(&:base_price_sum).sum
26+
end
27+
28+
# 변동가 합계
29+
# 일반적인 경우, 음수값을 가짐
1330
def discount_amount
14-
items.map(&:discount_amount).sum
31+
items.map(&:price_change_sum).sum
1532
end
1633

1734
def delivery_amount
1835
cart.delivery_amount.to_i
1936
end
2037

2138
def final_result_price
22-
price_sum - discount_amount + delivery_amount
39+
base_price_sum + discount_amount + delivery_amount
2340
end
2441
end
2542

43+
2644
class Cart < ApplicationRecord
2745
# 신규(desk) 입금대기(pay) 결제완료(paid) 배송준비(ship_ready) 배송중(ship_ing) 취소요청(cancel-request) 반품요청(refund-request) 환불실패 보관함(complete)
2846

@@ -38,35 +56,48 @@ class Cart < ApplicationRecord
3856
enum order_status: ORDER_STATUSES
3957

4058
belongs_to :user
41-
has_many :items, class_name: CartItem.name, dependent: :destroy
59+
has_many :items, class_name: 'CartItem', dependent: :destroy
4260
has_one :order_info, dependent: :nullify
4361

4462
delegate :ordered_at, to: :order_info, allow_nil: true
4563
delegate :delivery_amount, to: :order_info, allow_nil: true
4664

4765
scope :active, -> { where(active: true) }
66+
scope :sold, -> { where(order_status: SOLD_STATUSES) }
4867

4968
def self.current
5069
@_current = find_or_create_by(order_status: 0, current: true)
5170
end
5271

53-
def price_sum
54-
calculator.price_sum # 총 상품 가격
72+
# 품목 단위 수량 합계
73+
def unit_count
74+
calculator.unit_count
5575
end
5676

57-
alias_method :_delivery_amount, :delivery_amount
58-
def delivery_amount
59-
_delivery_amount || ShipInfo.fee_table('normal') # 배송비
77+
# 총 정가 합계
78+
def base_price_sum
79+
calculator.base_price_sum
6080
end
6181

82+
# 총 할인 가격
6283
def discount_amount
63-
calculator.discount_amount # 총 할인 가격
84+
calculator.discount_amount
85+
end
86+
87+
alias_method :_delivery_amount, :delivery_amount
88+
def delivery_amount
89+
_delivery_amount || ShipInfo.fee_table(unit_count < 3 ? 'express' : 'bulk_express') # 배송비
6490
end
6591

92+
# 총 합계 (최종 결제액)
6693
def final_price
67-
calculator.final_result_price # 총 합계
94+
calculator.final_result_price
6895
end
6996

97+
# def price_sum
98+
# calculator.price_sum # 총 상품 가격
99+
# end
100+
70101
def sender_name
71102
user.name
72103
end

app/models/cart_item.rb

Lines changed: 113 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,55 +5,141 @@ class CartItem < ApplicationRecord
55

66
resettable_counter_for :barcodes
77

8-
belongs_to :cart
9-
belongs_to :product
10-
belongs_to :product_option
11-
has_many :cart_item_barcodes
12-
has_many :item_barcodes, class_name: 'ProductItemBarcode', through: :cart_item_barcodes
13-
has_one :cancelled_tag, class_name: 'CartItemCancelledTag'
14-
15-
168
##========================================
179
# LEGACY
10+
belongs_to :product, optional: true
1811
has_many :barcodes, dependent: :nullify
1912
has_many :product_options, -> { distinct }, through: :barcodes
2013
##========================================
2114

22-
delegate :order_info, to: :cart, allow_nil: true
15+
belongs_to :cart
16+
belongs_to :product_option
17+
delegate :product_page, to: :product_option
18+
delegate :unit_count, to: :product_option
19+
has_many :bridges, through: :product_option
2320

24-
def _barcode_count
25-
@_barcode_count ||= barcodes.length
26-
end
21+
has_many :cart_item_barcodes, dependent: :destroy
22+
has_many :product_item_barcodes, class_name: 'ProductItemBarcode', through: :cart_item_barcodes
23+
has_one :cancelled_tag, class_name: 'CartItemCancelledTag'
24+
25+
has_one :order_info, through: :cart
2726

28-
def unit_price
29-
_barcode_count.zero? ? 0 : barcodes.first&.price.to_i
27+
scope :cancelled, -> { where(cancelled_tag: CartItemCancelledTag.all) }
28+
scope :not_cancelled, -> { where.not(cancelled_tag: CartItemCancelledTag.all) }
29+
30+
scope :eager_resources, -> { includes(:cancelled_tag, cart: { order_info: :payment }) }
31+
scope :cancelled_at, ->(range) { includes(:cancelled_tag).where(cancelled_tag: CartItemCancelledTag.where(cancelled_at: range)) }
32+
scope :ordered_at, ->(range) { includes(cart: :order_info).where(cart: Cart.sold.where(order_info: OrderInfo.where(ordered_at: range))) }
33+
scope :paid_at, ->(range) { eager_resources.not_cancelled.where(carts: { order_infos: { payments: { paid: true, paid_at: range } } }) }
34+
# delegate :order_info, to: :cart, allow_nil: true
35+
#
36+
# def _barcode_count
37+
# @_barcode_count ||= barcodes.length
38+
# end
39+
40+
# 단위 정가 & 합계
41+
delegate :base_price, to: :product_option
42+
def base_price_sum
43+
option_count * product_option.base_price
3044
end
3145

32-
def price_sum
33-
_barcode_count * unit_price
46+
# 구성 품목 수량 & 합계
47+
# A.K.A. EA (e.g. 10 EA)
48+
# 몇 개의 ProductItem 재고단위로 구성되었는가.
49+
delegate :unit_count, to: :product_option
50+
def unit_count_sum
51+
option_count * unit_count
3452
end
3553

36-
def discount_amount
37-
0
54+
# 단위 변동가 & 합계
55+
# 일반적인 경우, 음수값을 가짐
56+
delegate :price_change, to: :product_option
57+
def price_change_sum
58+
option_count * price_change
3859
end
3960

61+
# 합산 가격
4062
def result_price
41-
price_sum - discount_amount
63+
base_price_sum + price_change_sum
64+
end
65+
66+
# def unit_price
67+
# option_count.zero? ? 0 : product_option.retail_price
68+
# end
69+
70+
# def price_sum
71+
# option_count * product_option.base_price
72+
# end
73+
74+
# # 할인 가액
75+
# def discount_amount
76+
# option_count * product_option.discount_price
77+
# end
78+
79+
# def retail_price_sum
80+
#
81+
# end
82+
83+
def cancel!
84+
CartItemCancelledTag.create(cart_item: self, cancelled_at: Time.zone.now).persisted? unless cancelled
85+
true
4286
end
4387

44-
def similar_barcodes
45-
Barcode.options_with(product_options.ids)
88+
def cancelled
89+
cancelled_tag.present?
4690
end
4791

48-
def stat
49-
@stat = StatReportService.new(self)
92+
alias cancelled? cancelled
93+
94+
def cancelled_rollback
95+
cancelled_tag.destroy!
5096
end
5197

52-
def self.migrate_cart_items
53-
CartItem.where('created_at > ?', 4.months.ago).each do |cart_item|
54-
cart_item.product_option = cart_item.product_options.first
55-
cart_item.save!
98+
def should_expired?
99+
barcode_items = []
100+
product_item_barcodes.each { |barcode| barcode_items << barcode.product_item }
101+
bridge_items = product_option.bridges.map(&:items) * option_count
102+
return true if barcode_items.flatten.pluck(:id).sort != bridge_items.flatten.pluck(:id).sort
103+
return true unless product_option.is_active?
104+
return true if updated_at < 3.days.ago
105+
106+
false
107+
end
108+
109+
def expire!
110+
ActiveRecord::Base.transaction do
111+
product_item_barcodes.map(&:disexpire!)
112+
destroy
56113
end
57114
end
115+
#def similar_barcodes
116+
# Barcode.options_with(product_options.ids)
117+
#end
118+
119+
def item_count(product_item)
120+
product_option.items.count(product_item) * option_count
121+
end
122+
123+
def self.item_count(product_item)
124+
all.map { |cart_item| cart_item.item_count(product_item) }.sum
125+
end
58126

127+
# def _barcode_count
128+
# @_barcode_count ||= barcodes.length
129+
# end
130+
#
131+
# def unit_price
132+
# _barcode_count.zero? ? 0 : barcodes.first&.price.to_i
133+
# end
134+
#
135+
# def price_sum
136+
# _barcode_count * unit_price
137+
# end
138+
#
139+
# def self.migrate_cart_items
140+
# CartItem.where('created_at > ?', 4.months.ago).each do |cart_item|
141+
# cart_item.product_option = cart_item.product_options.first
142+
# cart_item.save!
143+
# end
144+
# end
59145
end
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
module Business
2+
class KpiReport
3+
def self.call(date = Date.today)
4+
date = date.in_time_zone
5+
data_format = lambda do |orders|
6+
{
7+
count: orders.count,
8+
price: orders.map { |order| order.cart.final_price }.sum
9+
}
10+
end
11+
12+
orders = OrderInfo.includes(:ship_info, cart: { items: [:product_option, :cancelled_tag] })
13+
users = User.where(is_admin: [false, nil], is_manager: [false, nil], is_seller: [false, nil])
14+
15+
16+
# 기간
17+
range = date.beginning_of_month..date.end_of_month
18+
19+
# 주문 완료
20+
complete_data = data_format.call(orders.where(ordered_at: range).sold)
21+
22+
# 주문 취소
23+
cancelled_data = data_format.call(orders.where(cart: Cart.where(items: CartItem.cancelled_at(range))))
24+
25+
{
26+
duration: {
27+
from: range.first.strftime('%F'),
28+
to: range.last.strftime('%F'),
29+
length: 1.month
30+
},
31+
orders: {
32+
complete: complete_data,
33+
cancelled: cancelled_data,
34+
GMV: complete_data[:price] - cancelled_data[:price],
35+
},
36+
users: {
37+
newbie_count: users.where(created_at: range).count,
38+
buyer_count: users.where(carts: Cart.where(order_info: OrderInfo.where(ordered_at: range))).count,
39+
newbie_buyer_count: users.where(created_at: range).where(carts: Cart.where(order_info: OrderInfo.where(ordered_at: range))).count
40+
}
41+
}
42+
end
43+
end
44+
end

0 commit comments

Comments
 (0)