# frozen_string_literal: true require 'open_food_network/address_finder' # rubocop:disable Metrics/ClassLength module Admin class CustomersController < Admin::ResourceController before_action :load_managed_shops, only: :index, if: :html_request? respond_to :json respond_override update: { json: { success: lambda { tag_rule_mapping = TagRule.mapping_for(Enterprise.where(id: @customer.enterprise)) render_as_json @customer, tag_rule_mapping: }, failure: lambda { render json: { errors: @customer.errors.full_messages }, status: :unprocessable_entity } } } def index respond_to do |format| format.html format.json do render json: @collection, each_serializer: ::Api::Admin::CustomerWithBalanceSerializer, tag_rule_mapping:, customer_tags: customer_tags_by_id end end end def show render_as_json @customer, ams_prefix: params[:ams_prefix] end def create @customer = Customer.find_or_initialize_by(customer_params.slice(:email, :enterprise_id)) if user_can_create_customer? @customer.created_manually = true if @customer.save tag_rule_mapping = TagRule.mapping_for(Enterprise.where(id: @customer.enterprise)) render_as_json @customer, tag_rule_mapping: else render json: { errors: @customer.errors.full_messages }, status: :bad_request end else redirect_to '/unauthorized' end end # copy of Admin::ResourceController without flash notice def update if @object.update(permitted_resource_params) respond_with(@object) do |format| format.html { redirect_to location_after_save } format.js { render layout: false } end else respond_with(@object) end end # copy of Admin::ResourceController without flash notice def destroy if @object.destroy respond_with(@object) do |format| format.html { redirect_to location_after_destroy } format.js { render partial: "spree/admin/shared/destroy" } end else respond_with(@object) do |format| format.html { redirect_to location_after_destroy } format.json { render json: { errors: @object.errors.full_messages }, status: :conflict } end end end private def collection if json_request? && params[:enterprise_id].present? CustomersWithBalanceQuery.new(customers).call. includes( :enterprise, { bill_address: [:state, :country] }, { ship_address: [:state, :country] }, user: :credit_cards ) else Customer.where('1=0') end end def customers return @customers if @customers.present? @customers = Customer.visible.managed_by(spree_current_user) return @customers if params[:enterprise_id].blank? @customers = @customers.where(enterprise_id: params[:enterprise_id]) end def managed_enterprise_id @managed_enterprise_id ||= Enterprise.managed_by(spree_current_user). select('enterprises.id').find_by(id: params[:enterprise_id]) end def load_managed_shops @shops = Enterprise.managed_by(spree_current_user).is_distributor end def user_can_create_customer? spree_current_user.admin? || spree_current_user.enterprises.include?(@customer.enterprise) end def ams_prefix_whitelist [:subscription] end def customer_params params.require(:customer).permit( :enterprise_id, :first_name, :last_name, :email, :code, :tag_list, ship_address_attributes: PermittedAttributes::Address.attributes, bill_address_attributes: PermittedAttributes::Address.attributes, ) end # Used in Admin::ResourceController#update def permitted_resource_params customer_params end def tag_rule_mapping TagRule.mapping_for(Enterprise.where(id: managed_enterprise_id)) end # Fetches tags for all customers of the enterprise and returns a hash indexed by customer_id def customer_tags_by_id BatchTaggableTagsQuery.call(Customer.of(managed_enterprise_id)) end end end # rubocop:enable Metrics/ClassLength