module Workarea module Storefront class OrderViewModel < ApplicationViewModel include OrderPricing class PendingItem < Struct.new(:product_attributes, :sku, :quantity); end class CancelledItem < Struct.new(:product_attributes, :sku, :quantity); end alias_method :order, :model delegate :tenders, :credit_card, :credit_card?, :store_credit?, :store_credit, to: :payment delegate :issuer, :display_number, :month, :year, :amount, to: :credit_card, prefix: true, allow_nil: true delegate :saved_card_id, to: :credit_card, allow_nil: true def render_signup_form? User.find_by_email(model.email).blank? end def user @user ||= User.find(model.user_id) if model.user_id.present? end def billing_address payment.address end def shipping_address shipping.try(:address) end def shipping_service shipping.try(:shipping_service).try(:name) end def full_name if billing_address.present? "#{billing_address.last_name}, #{billing_address.first_name}" elsif shipping_address.present? "#{shipping_address.last_name}, #{shipping_address.first_name}" end end def items @items ||= model.items.by_newest.map do |item| Storefront::OrderItemViewModel.new(item) end end def shippings @shippings ||= Storefront::ShippingViewModel.wrap( Shipping.by_order(model.id).to_a, options.merge(order: model) ) end def store_credit_amount if store_credit.present? store_credit.amount else 0.to_m end end def paid_amount total_price - store_credit_amount end def refunds @refunds ||= RefundViewModel.wrap(payment.refunds, options) end def status if fulfillment_status_slug.in?(%w(open not_available)) model.status.to_s.titleize else fulfillment_status end end def fulfillment_status return if fulfillment_status_slug == 'not_available' fulfillment_status_slug.titleize end def packages @packages ||= fulfillment.packages.map do |package| Storefront::PackageViewModel.wrap(package, order: self) end end def pending_items @pending_items ||= fulfillment.pending_items.map do |fulfillment_item| next unless order_item = items .detect { |i| i.id.to_s == fulfillment_item.order_item_id } FulfillmentItemViewModel.new(order_item, quantity: fulfillment_item.quantity_pending) end.compact end def canceled_items @canceled_items ||= fulfillment.canceled_items.map do |fulfillment_item| next unless order_item = items .detect { |i| i.id.to_s == fulfillment_item.order_item_id } FulfillmentItemViewModel.new(order_item, quantity: fulfillment_item.quantity_canceled) end.compact end # Returns recommendations for the order. The view model it returns behave # like {Enumerable}. # # @return [Workarea::Storefront::CartRecommendationsViewModel] # def recommendations @recommendations ||= CartRecommendationsViewModel.new(model) end private def payment @payment ||= Payment.find_or_initialize_by(id: model.id) end def shipping @shipping ||= Shipping.find_by_order(model.id) end def fulfillment @fulfillment ||= Fulfillment.find_or_initialize_by(id: model.id) end def fulfillment_status_slug @fulfillment_status ||= ( options[:fulfillment_status].presence || fulfillment.status ).to_s end end end end