diff --git a/README.md b/README.md index a5ddb884..98f10447 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,23 @@ bundle bundle exec rails g solidus_paypal_braintree:install ``` +Store Configuration +------------------- + +This gem adds a configuration model - `SolidusPaypalBraintree::Configuration` - +that belongs to `Spree::Store` as `braintree_configuration`. In multi-store +Solidus applications, this model allows admins to enable/disable payment types +on a per-store basis. + +The migrations for this gem will add a default configuration to all stores that +has each payment type disabled. It also adds a `before_create` callback to +`Spree::Store` that builds a default configuration. You can customize the +default configuration that gets created by overriding the private +`build_default_configuration` method on `Spree::Store`. + +A view override is provided that adds a `Braintree` tab to the admin settings +submenu. Admins can go here to edit the configuration for each store. + Testing ------- diff --git a/app/helpers/solidus_paypal_braintree/routes_helper.rb b/app/helpers/solidus_paypal_braintree/routes_helper.rb new file mode 100644 index 00000000..60dfcb10 --- /dev/null +++ b/app/helpers/solidus_paypal_braintree/routes_helper.rb @@ -0,0 +1,15 @@ +module SolidusPaypalBraintree + module RoutesHelper + def method_missing(method_sym, *arguments, &block) + if spree.respond_to?(method_sym) + spree.send(method_sym, arguments) + else + super + end + end + + def respond_to_missing?(method_sym, include_private = false) + spree.respond_to?(method_sym) || super + end + end +end diff --git a/app/models/solidus_paypal_braintree/configuration.rb b/app/models/solidus_paypal_braintree/configuration.rb new file mode 100644 index 00000000..bddbc798 --- /dev/null +++ b/app/models/solidus_paypal_braintree/configuration.rb @@ -0,0 +1,5 @@ +class SolidusPaypalBraintree::Configuration < ApplicationRecord + belongs_to :store, class_name: 'Spree::Store' + + validates :store, presence: true +end diff --git a/app/models/spree/store_decorator.rb b/app/models/spree/store_decorator.rb new file mode 100644 index 00000000..82349416 --- /dev/null +++ b/app/models/spree/store_decorator.rb @@ -0,0 +1,11 @@ +Spree::Store.class_eval do + has_one :braintree_configuration, class_name: "SolidusPaypalBraintree::Configuration" + + before_create :build_default_configuration + + private + + def build_default_configuration + build_braintree_configuration + end +end diff --git a/app/overrides/admin_navigation_menu.rb b/app/overrides/admin_navigation_menu.rb new file mode 100644 index 00000000..ca2fe726 --- /dev/null +++ b/app/overrides/admin_navigation_menu.rb @@ -0,0 +1,6 @@ +Deface::Override.new( + virtual_path: "spree/admin/shared/_settings_sub_menu", + name: "solidus_paypal_braintree_admin_navigation_configuration", + insert_bottom: "[data-hook='admin_settings_sub_tabs']", + partial: "solidus_paypal_braintree/configurations/admin_tab" +) diff --git a/config/locales/en.yml b/config/locales/en.yml index cdec84f8..4ea86026 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,7 +1,16 @@ en: + spree: + admin: + tab: + braintree: Braintree solidus_paypal_braintree: nonce: Nonce token: Token payment_type: apple_pay_card: Apple Pay pay_pal_account: PayPal + configurations: + title: Braintree Configurations + tab: Braintree + update_success: Successfully updated Braintree configurations. + update_error: An error occurred while updating Braintree configurations. diff --git a/config/routes.rb b/config/routes.rb index 8cd58dd6..89fb2aed 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,7 +1,12 @@ -Rails.application.routes.draw do - namespace :solidus_paypal_braintree do - resource :checkout, only: [:update, :edit] - resource :client_token, only: [:create], format: :json - resource :transactions, only: [:create] +SolidusPaypalBraintree::Engine.routes.draw do + resource :checkout, only: [:update, :edit] + resource :client_token, only: [:create], format: :json + resource :transactions, only: [:create] + + resources :configurations do + collection do + get :list + post :update + end end end diff --git a/db/migrate/20161114231422_create_solidus_paypal_braintree_configurations.rb b/db/migrate/20161114231422_create_solidus_paypal_braintree_configurations.rb new file mode 100644 index 00000000..bde4a1e5 --- /dev/null +++ b/db/migrate/20161114231422_create_solidus_paypal_braintree_configurations.rb @@ -0,0 +1,11 @@ +class CreateSolidusPaypalBraintreeConfigurations < ActiveRecord::Migration + def change + create_table :solidus_paypal_braintree_configurations do |t| + t.boolean :paypal, null: false, default: false + t.boolean :apple_pay, null: false, default: false + t.integer :store_id, null: false, index: true, foreign_key: { references: :spree_stores } + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20161125172005_add_braintree_configuration_to_stores.rb b/db/migrate/20161125172005_add_braintree_configuration_to_stores.rb new file mode 100644 index 00000000..cd61993f --- /dev/null +++ b/db/migrate/20161125172005_add_braintree_configuration_to_stores.rb @@ -0,0 +1,9 @@ +class AddBraintreeConfigurationToStores < ActiveRecord::Migration + def up + Spree::Store.all.each(&:create_braintree_configuration) + end + + def down + SolidusPaypalBraintree::Configuration.joins(:store).destroy_all + end +end diff --git a/lib/controllers/backend/solidus_paypal_braintree/configurations_controller.rb b/lib/controllers/backend/solidus_paypal_braintree/configurations_controller.rb new file mode 100644 index 00000000..410f0908 --- /dev/null +++ b/lib/controllers/backend/solidus_paypal_braintree/configurations_controller.rb @@ -0,0 +1,30 @@ +module SolidusPaypalBraintree + class ConfigurationsController < Spree::Admin::BaseController + helper RoutesHelper + + def list + authorize! :list, SolidusPaypalBraintree::Configuration + + @configurations = Spree::Store.all.map(&:braintree_configuration) + end + + def update + authorize! :update, SolidusPaypalBraintree::Configuration + + params = configurations_params[:configuration_fields] + if SolidusPaypalBraintree::Configuration.update(params.keys, params.values) + flash[:success] = t('update_success', scope: 'solidus_paypal_braintree.configurations') + else + flash[:error] = t('update_error', scope: 'solidus_paypal_braintree.configurations') + end + redirect_to action: :list + end + + private + + def configurations_params + params.require(:configurations). + permit(configuration_fields: [:paypal, :apple_pay]) + end + end +end diff --git a/lib/generators/solidus_paypal_braintree/install/install_generator.rb b/lib/generators/solidus_paypal_braintree/install/install_generator.rb index 85597ac0..4990ef4a 100644 --- a/lib/generators/solidus_paypal_braintree/install/install_generator.rb +++ b/lib/generators/solidus_paypal_braintree/install/install_generator.rb @@ -18,6 +18,12 @@ def add_migrations run 'bundle exec rake railties:install:migrations FROM=solidus_paypal_braintree' end + def mount_engine + insert_into_file File.join('config', 'routes.rb'), after: "Rails.application.routes.draw do\n" do + "mount SolidusPaypalBraintree::Engine, at: '/solidus_paypal_braintree'" + end + end + def run_migrations run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]')) if run_migrations diff --git a/lib/solidus_paypal_braintree/engine.rb b/lib/solidus_paypal_braintree/engine.rb index bcd356ee..5a2c9b2e 100644 --- a/lib/solidus_paypal_braintree/engine.rb +++ b/lib/solidus_paypal_braintree/engine.rb @@ -1,7 +1,6 @@ module SolidusPaypalBraintree class Engine < Rails::Engine - require 'spree/core' - isolate_namespace Spree + isolate_namespace SolidusPaypalBraintree engine_name 'solidus_paypal_braintree' # use rspec for tests @@ -25,6 +24,10 @@ def self.frontend_available? defined?(Spree::Frontend::Engine) == "constant" end + def self.backend_available? + defined?(Spree::Backend::Engine) == "constant" + end + if frontend_available? config.assets.precompile += [ 'spree/frontend/solidus_paypal_braintree', @@ -33,5 +36,10 @@ def self.frontend_available? paths["app/controllers"] << "lib/controllers/frontend" paths["app/views"] << "lib/views/frontend" end + + if backend_available? + paths["app/controllers"] << "lib/controllers/backend" + paths["app/views"] << "lib/views/backend" + end end end diff --git a/lib/views/backend/solidus_paypal_braintree/configurations/_admin_tab.html.erb b/lib/views/backend/solidus_paypal_braintree/configurations/_admin_tab.html.erb new file mode 100644 index 00000000..1145efc2 --- /dev/null +++ b/lib/views/backend/solidus_paypal_braintree/configurations/_admin_tab.html.erb @@ -0,0 +1,3 @@ +<%= tab :braintree, match_path: /braintree\/configurations/, + url: solidus_paypal_braintree.list_configurations_path +%> diff --git a/lib/views/backend/solidus_paypal_braintree/configurations/list.html.erb b/lib/views/backend/solidus_paypal_braintree/configurations/list.html.erb new file mode 100644 index 00000000..12128af2 --- /dev/null +++ b/lib/views/backend/solidus_paypal_braintree/configurations/list.html.erb @@ -0,0 +1,26 @@ +<% content_for :page_title do %> + <%= t(:title, scope: 'solidus_paypal_braintree.configurations') %> +<% end %> + +<%= form_for :configurations, url: solidus_paypal_braintree.configurations_path do |f| %> + <% @configurations.each do |config| %> +