@@ -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
59145end
0 commit comments