# frozen_string_literal: true module Spree module UserMethods extend ActiveSupport::Concern include Spree::UserApiAuthentication include Spree::UserReporting include Spree::UserAddressBook included do extend Spree::DisplayMoney has_many :role_users, foreign_key: "user_id", class_name: "Spree::RoleUser", dependent: :destroy has_many :spree_roles, through: :role_users, source: :role, class_name: "Spree::Role" has_many :user_stock_locations, foreign_key: "user_id", class_name: "Spree::UserStockLocation" has_many :stock_locations, through: :user_stock_locations has_many :spree_orders, foreign_key: "user_id", class_name: "Spree::Order" has_many :orders, foreign_key: "user_id", class_name: "Spree::Order" has_many :store_credits, -> { includes(:credit_type) }, foreign_key: "user_id", class_name: "Spree::StoreCredit" has_many :store_credit_events, through: :store_credits has_many :credit_cards, class_name: "Spree::CreditCard", foreign_key: :user_id has_many :wallet_payment_sources, foreign_key: 'user_id', class_name: 'Spree::WalletPaymentSource', inverse_of: :user after_create :auto_generate_spree_api_key before_destroy :check_for_deletion include Spree::RansackableAttributes unless included_modules.include?(Spree::RansackableAttributes) ransack_alias :name, :addresses_name self.allowed_ransackable_associations = %w[addresses spree_roles] self.allowed_ransackable_attributes = %w[name id email created_at] end def wallet @wallet ||= Spree::Wallet.new(self) end # has_spree_role? simply needs to return true or false whether a user has a role or not. def has_spree_role?(role_in_question) spree_roles.any? { |role| role.name == role_in_question.to_s } end def auto_generate_spree_api_key return if !respond_to?(:spree_api_key) || spree_api_key.present? if Spree::Config.generate_api_key_for_all_roles || (spree_roles.map(&:name) & Spree::Config.roles_for_auto_api_key).any? generate_spree_api_key! end end # @return [Spree::Order] the most-recently-created incomplete order # since the customer's last complete order. def last_incomplete_spree_order(store: nil, only_frontend_viewable: true) self_orders = orders self_orders = self_orders.where(frontend_viewable: true) if only_frontend_viewable self_orders = self_orders.where(store: store) if store self_orders = self_orders.where('updated_at > ?', Spree::Config.completable_order_updated_cutoff_days.days.ago) if Spree::Config.completable_order_updated_cutoff_days self_orders = self_orders.where('created_at > ?', Spree::Config.completable_order_created_cutoff_days.days.ago) if Spree::Config.completable_order_created_cutoff_days last_order = self_orders.order(:created_at).last last_order unless last_order.try!(:completed?) end def available_store_credit_total(currency:) store_credits.to_a. select { |credit| credit.currency == currency }. sum(&:amount_remaining) end def display_available_store_credit_total(currency:) Spree::Money.new( available_store_credit_total(currency: currency), currency: currency, ) end # Restrict to delete users with existing orders # # Override this in your user model class to add another logic. # # Ie. to allow to delete users with incomplete orders add: # # orders.complete.none? # def can_be_deleted? orders.none? end # Updates the roles in keeping with the given ability's permissions # # Roles that are not accessible to the given ability will be ignored. It # also ensure not to remove non accessible roles when assigning new # accessible ones. # # @param given_roles [Spree::Role] # @param ability [Spree::Ability] def update_spree_roles(given_roles, ability:) accessible_roles = Spree::Role.accessible_by(ability) non_accessible_roles = Spree::Role.all - accessible_roles new_accessible_roles = given_roles - non_accessible_roles self.spree_roles = spree_roles - accessible_roles + new_accessible_roles end private def check_for_deletion raise ActiveRecord::DeleteRestrictionError unless can_be_deleted? end end end