spree_winkelstraat 3.1.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +7 -0
  5. data/LICENSE +26 -0
  6. data/README.md +53 -0
  7. data/Rakefile +21 -0
  8. data/app/assets/javascripts/spree/backend/spree_winkelstraat.js +2 -0
  9. data/app/assets/javascripts/spree/frontend/spree_winkelstraat.js +2 -0
  10. data/app/assets/stylesheets/spree/backend/spree_winkelstraat.css +4 -0
  11. data/app/assets/stylesheets/spree/frontend/spree_winkelstraat.css +4 -0
  12. data/app/controllers/api/v1/orders_controller_decorator.rb +15 -0
  13. data/app/controllers/api/v1/products_controller_decorator.rb +13 -0
  14. data/app/models/spree/order/mail_defuser.rb +15 -0
  15. data/app/models/spree/order_decorator.rb +180 -0
  16. data/app/models/spree/product_decorator.rb +110 -0
  17. data/app/models/spree/promotion/rules/not_winkelstraat_order.rb +18 -0
  18. data/app/models/spree/reimbursement/mail_defuser.rb +9 -0
  19. data/app/models/spree/reimbursement_decorator.rb +5 -0
  20. data/app/models/spree/shipment_handler/mail_defuser.rb +7 -0
  21. data/app/models/spree/shipment_handler_decorator.rb +5 -0
  22. data/app/models/spree/variant_decorator.rb +51 -0
  23. data/app/overrides/option_value_fields.rb +13 -0
  24. data/app/overrides/order_index.rb +13 -0
  25. data/app/overrides/product_form.rb +6 -0
  26. data/app/views/spree/admin/option_types/_extra_option_value_fields.html.erb +1 -0
  27. data/app/views/spree/admin/option_types/_extra_option_value_headers.html.erb +1 -0
  28. data/app/views/spree/admin/orders/_index_tradebyte_state_override.html.erb +7 -0
  29. data/app/views/spree/admin/orders/_index_tradebyte_state_override_head.html.erb +1 -0
  30. data/app/views/spree/admin/products/_sell_on_winkelstraat.html.erb +7 -0
  31. data/app/views/spree/admin/promotions/rules/_not_winkelstraat_order.html.erb +0 -0
  32. data/bin/rails +7 -0
  33. data/config/locales/en.yml +9 -0
  34. data/config/routes.rb +18 -0
  35. data/db/migrate/20190424140108_add_winkelstraat_data.rb +5 -0
  36. data/db/migrate/20190429134248_add_ws_code_to_option_values.rb +5 -0
  37. data/db/migrate/20190501101657_add_winkelstraat_taxons.rb +24 -0
  38. data/db/migrate/20190501122837_add_winkelstraat_payment_method_and_shipping_method.rb +11 -0
  39. data/db/migrate/20190507114902_add_active_on_winkelstraat_to_spree_products.rb +5 -0
  40. data/lib/generators/spree_winkelstraat/install/install_generator.rb +31 -0
  41. data/lib/spree_winkelstraat/engine.rb +26 -0
  42. data/lib/spree_winkelstraat/factories.rb +6 -0
  43. data/lib/spree_winkelstraat/order_importer.rb +65 -0
  44. data/lib/spree_winkelstraat.rb +3 -0
  45. data/spec/spec_helper.rb +93 -0
  46. data/spree_winkelstraat.gemspec +33 -0
  47. metadata +257 -0
@@ -0,0 +1,18 @@
1
+ class Spree::Promotion::Rules::NotWinkelstraatOrder < Spree::PromotionRule
2
+
3
+ def description
4
+ 'Order is not a winkelstraat order'
5
+ end
6
+
7
+ def applicable?(promotable)
8
+ promotable.is_a?(Spree::Order)
9
+ end
10
+
11
+ def eligible?(order, options = {})
12
+ !order.is_winkelstraat_order?
13
+ end
14
+
15
+ def actionable?(line_item)
16
+ !line_item.order.is_winkelstraat_order?
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ module Spree
2
+ module Reimbursement::MailDefuser
3
+
4
+ def send_reimbursement_email
5
+ super unless order.is_winkelstraat_order?
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ Spree::Reimbursement.class_eval do
2
+
3
+ self.prepend(Spree::Reimbursement::MailDefuser)
4
+
5
+ end
@@ -0,0 +1,7 @@
1
+ module Spree
2
+ module ShipmentHandler::MailDefuser
3
+ def send_shipped_email
4
+ super unless @shipment.order.is_winkelstraat_order?
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ Spree::ShipmentHandler.class_eval do
2
+
3
+ self.prepend(Spree::ShipmentHandler::MailDefuser)
4
+
5
+ end
@@ -0,0 +1,51 @@
1
+ Spree::Variant.class_eval do
2
+
3
+ scope :active_on_winkelstraat, -> {joins(:product).where(spree_products: {sell_on_winkelstraat: true})}
4
+
5
+ delegate :sell_on_winkelstraat, to: :product
6
+
7
+ def self.winkelstraat_stock_csv(stock_location_name = :all)
8
+ stock_location = Spree::StockLocation.find_by_admin_name(stock_location_name) || Spree::StockLocation.find_by_name!(stock_location_name) if stock_location_name != :all
9
+ CSV.generate(headers: false) do |csv|
10
+ size_option_type = Spree::OptionType.includes(:translations).where(spree_option_type_translations: {name: 'size'}).first
11
+ size_option_values = size_option_type.option_values.map do |ov|
12
+ {
13
+ option_value_id: ov.id,
14
+ presentation: ov.presentation
15
+ }
16
+ end
17
+ Spree::Variant.active_on_winkelstraat.active.each do |variant|
18
+ next unless variant.product.available?
19
+ size = size_option_values.detect {|ov| variant.option_values.ids.include?(ov[:option_value_id])}
20
+ csv << [
21
+ variant.sku, #sku
22
+ size.present? ? size.fetch(:presentation) : nil, #maat
23
+ variant.stock_for_stock_location(stock_location) #stock
24
+ ]
25
+ end
26
+ end
27
+ end
28
+
29
+ def in_taxon?(taxon)
30
+ return false if taxon.blank?
31
+ product.taxon_ids.include?(taxon.id)
32
+ end
33
+
34
+ # pass :all for all stock locations
35
+ def stock_for_stock_location(stock_location)
36
+ begin
37
+ if stock_location == :all
38
+ total_on_hand
39
+ else
40
+ stock_items.where(stock_location: stock_location).first.try(:count_on_hand) || 0
41
+ end
42
+ rescue
43
+ 0
44
+ end
45
+ end
46
+
47
+ def kassa_reference
48
+ nil
49
+ end
50
+
51
+ end
@@ -0,0 +1,13 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/option_types/_option_value_fields',
3
+ name: 'add_ws_code_to_option_values',
4
+ insert_before: '[data-hook="option_value"] .actions',
5
+ partial: 'spree/admin/option_types/extra_option_value_fields'
6
+ )
7
+
8
+ Deface::Override.new(
9
+ virtual_path: 'spree/admin/option_types/edit',
10
+ name: 'add_ws_code_to_option_values_headers',
11
+ insert_before: '[data-hook="option_header"] th.actions',
12
+ partial: 'spree/admin/option_types/extra_option_value_headers'
13
+ )
@@ -0,0 +1,13 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/orders/index',
3
+ name: 'add tradebyte order info header',
4
+ insert_after: '#listing_orders thead th:nth-last-child(3)',
5
+ partial: 'spree/admin/orders/index_tradebyte_state_override_head'
6
+ )
7
+
8
+ Deface::Override.new(
9
+ virtual_path: 'spree/admin/orders/index',
10
+ name: 'add tradebyte order info',
11
+ insert_after: '#listing_orders tbody td:nth-last-child(3)',
12
+ partial: 'spree/admin/orders/index_tradebyte_state_override'
13
+ )
@@ -0,0 +1,6 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/products/_form',
3
+ name: 'sell on winkelstraat checkbox',
4
+ insert_after: '[data-hook="admin_product_form_promotionable"]',
5
+ partial: 'spree/admin/products/sell_on_winkelstraat'
6
+ )
@@ -0,0 +1 @@
1
+ <td class="ws_code"><%= f.text_field :ws_code, class: "form-control" %></td>
@@ -0,0 +1 @@
1
+ <th>Winkelstraat code</th>
@@ -0,0 +1,7 @@
1
+ <td>
2
+ <% if order.is_winkelstraat_order? %>
3
+ <span class="label label-success">Winkelstraat order (<%= order.winkelstraat_order_id %>)</span>
4
+ <% else %>
5
+ <span class="label label-success">Regular order</span>
6
+ <% end %>
7
+ </td>
@@ -0,0 +1 @@
1
+ <th><%= sort_link @search, :is_winkelstraat_order?, 'Type' %></th>
@@ -0,0 +1,7 @@
1
+ <div data-hook="admin_product_form_sell_on_winkelstraat">
2
+ <%= f.field_container :sell_on_winkelstraat, class: ['form-group'] do %>
3
+ <%= f.label :sell_on_winkelstraat, 'Sell on winkelstraat' %>
4
+ <%= f.error_message_on :sell_on_winkelstraat %>
5
+ <%= f.check_box :sell_on_winkelstraat, class: 'form-control' %>
6
+ <% end %>
7
+ </div>
data/bin/rails ADDED
@@ -0,0 +1,7 @@
1
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
2
+
3
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
4
+ ENGINE_PATH = File.expand_path('../../lib/spree_winkelstraat/engine', __FILE__)
5
+
6
+ require 'rails/all'
7
+ require 'rails/engine/commands'
@@ -0,0 +1,9 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ spree:
6
+ promotion_rule_types:
7
+ not_winkelstraat_order:
8
+ name: "Order is not from winkelstraat"
9
+ description: "The order does not originate from winkelstraat"
data/config/routes.rb ADDED
@@ -0,0 +1,18 @@
1
+ Spree::Core::Engine.routes.draw do
2
+ # Add your extension routes here
3
+
4
+ namespace :api do
5
+ namespace :v1 do
6
+
7
+ resources :products, path: '/ws_product', only: [] do
8
+ get :winkelstraat_stock, on: :collection
9
+ get :winkelstraat_article, on: :collection
10
+ end
11
+
12
+ resources :orders, path: '/ws_order',only: [] do
13
+ post :import, on: :collection
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ class AddWinkelstraatData < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_orders, :winkelstraat_order_id, :string
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddWsCodeToOptionValues < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_option_values, :ws_code, :string
4
+ end
5
+ end
@@ -0,0 +1,24 @@
1
+ class AddWinkelstraatTaxons < ActiveRecord::Migration
2
+
3
+ WOMEN_CATEGORIES = ["Accessoires", "Badmode", "Blazers & Gilets", "Blouses", "Broeken", "Jassen", "Jeans",
4
+ "Jumpsuits", "Jurken", "Lingerie", "Nachtmode", "Rokken", "Schoenen", "Sport", "Tassen", "Tops", "Truien & Vesten"]
5
+ MEN_CATEGORIES = ["Accessoires", "Badmode", "Broeken", "Colberts & Gilets", "Jassen", "Jeans", "Ondergoed",
6
+ "Overhemden", "Schoenen", "Shirts", "Sport", "Truien", "Vesten"]
7
+ KIDS_CATEGORIES = ["Jongens", "Meisjes"]
8
+
9
+ def change
10
+ taxonomy = Spree::Taxonomy.find_or_create_by(name: 'Winkelstraat Category')
11
+
12
+ WOMEN_CATEGORIES.each do |taxon|
13
+ Spree::Taxon.find_or_create_by(name: taxon, taxonomy: taxonomy)
14
+ end
15
+
16
+ MEN_CATEGORIES.each do |taxon|
17
+ Spree::Taxon.find_or_create_by(name: taxon, taxonomy: taxonomy)
18
+ end
19
+
20
+ KIDS_CATEGORIES.each do |taxon|
21
+ Spree::Taxon.find_or_create_by(name: taxon, taxonomy: taxonomy)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ class AddWinkelstraatPaymentMethodAndShippingMethod < ActiveRecord::Migration
2
+ def change
3
+ Spree::PaymentMethod.find_or_create_by(name: 'Paid at winkelstraat', display_on: :back_end, type: 'Spree::PaymentMethod::Check', active: true)
4
+
5
+ sm = Spree::ShippingMethod.find_or_create_by(name: 'Shipped by winkelstraat', display_on: :back_end, admin_name: 'Winkelstraat shipping')
6
+ sm.zones = Spree::Zone.all
7
+ sm.shipping_categories = [Spree::ShippingCategory.first]
8
+ sm.calculator = Spree::Calculator::Shipping::FlatRate.create(calculable: sm) unless sm.calculator.present?
9
+ sm.save!
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class AddActiveOnWinkelstraatToSpreeProducts < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_products, :sell_on_winkelstraat, :boolean, default: false
4
+ end
5
+ end
@@ -0,0 +1,31 @@
1
+ module SpreeWinkelstraat
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+
5
+ class_option :auto_run_migrations, :type => :boolean, :default => false
6
+
7
+ def add_javascripts
8
+ append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/spree_winkelstraat\n"
9
+ append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/spree_winkelstraat\n"
10
+ end
11
+
12
+ def add_stylesheets
13
+ inject_into_file 'vendor/assets/stylesheets/spree/frontend/all.css', " *= require spree/frontend/spree_winkelstraat\n", :before => /\*\//, :verbose => true
14
+ inject_into_file 'vendor/assets/stylesheets/spree/backend/all.css', " *= require spree/backend/spree_winkelstraat\n", :before => /\*\//, :verbose => true
15
+ end
16
+
17
+ def add_migrations
18
+ run 'bundle exec rake railties:install:migrations FROM=spree_winkelstraat'
19
+ end
20
+
21
+ def run_migrations
22
+ run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask 'Would you like to run the migrations now? [Y/n]')
23
+ if run_migrations
24
+ run 'bundle exec rake db:migrate'
25
+ else
26
+ puts 'Skipping rake db:migrate, don\'t forget to run it!'
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ module SpreeWinkelstraat
2
+ class Engine < Rails::Engine
3
+ require 'spree/core'
4
+ isolate_namespace Spree
5
+ engine_name 'spree_winkelstraat'
6
+
7
+ # use rspec for tests
8
+ config.generators do |g|
9
+ g.test_framework :rspec
10
+ end
11
+
12
+ def self.activate
13
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
14
+ Rails.configuration.cache_classes ? require(c) : load(c)
15
+ end
16
+
17
+ Rails.application.config.spree.promotions.rules << Spree::Promotion::Rules::NotWinkelstraatOrder
18
+ end
19
+
20
+ Spree::PermittedAttributes.option_value_attributes << :ws_code
21
+ Spree::PermittedAttributes.product_attributes << :sell_on_winkelstraat
22
+
23
+
24
+ config.to_prepare &method(:activate).to_proc
25
+ end
26
+ end
@@ -0,0 +1,6 @@
1
+ FactoryGirl.define do
2
+ # Define your Spree extensions Factories within this file to enable applications, and other extensions to use and override them.
3
+ #
4
+ # Example adding this to your spec_helper will load these Factories for use:
5
+ # require 'spree_winkelstraat/factories'
6
+ end
@@ -0,0 +1,65 @@
1
+ class SpreeWinkelstraat::OrderImporter < Spree::Core::Importer::Order
2
+
3
+ def self.import(user, params)
4
+ begin
5
+ ensure_country_id_from_params params[:ship_address_attributes]
6
+ ensure_state_id_from_params params[:ship_address_attributes]
7
+ ensure_country_id_from_params params[:bill_address_attributes]
8
+ ensure_state_id_from_params params[:bill_address_attributes]
9
+
10
+ create_params = params.slice :currency
11
+ order = Spree::Order.create! create_params
12
+ order.associate_user!(user) if user.present?
13
+
14
+ shipments_attrs = params.delete(:shipments_attributes)
15
+
16
+ create_line_items_from_params(params.delete(:line_items_attributes),order)
17
+ create_shipments_from_params(shipments_attrs, order)
18
+ create_adjustments_from_params(params.delete(:adjustments_attributes), order)
19
+ create_payments_from_params(params.delete(:payments_attributes), order)
20
+
21
+ if completed_at = params.delete(:completed_at)
22
+ order.completed_at = completed_at
23
+ order.state = 'complete'
24
+ end
25
+
26
+ params.delete(:user_id) unless user.present? && user.try(:has_spree_role?, "admin") && params.key?(:user_id)
27
+
28
+ order.update_attributes!(params)
29
+
30
+ order.create_proposed_shipments unless shipments_attrs.present?
31
+
32
+ # Really ensure that the order totals & states are correct
33
+ order.updater.update
34
+ if shipments_attrs.present?
35
+ order.shipments.each_with_index do |shipment, index|
36
+ shipment.update_columns(cost: shipments_attrs[index][:cost].to_f) if shipments_attrs[index][:cost].present?
37
+ end
38
+ end
39
+ order.reload
40
+ rescue Exception => e
41
+ order.destroy if order && order.persisted?
42
+ raise e.message
43
+ end
44
+ end
45
+
46
+ def self.create_payments_from_params(payments_hash, order)
47
+ return [] unless payments_hash
48
+ payments_hash.each do |p|
49
+ begin
50
+ payment = order.payments.build order: order
51
+ payment.amount = p.fetch(:amount, order.total)
52
+ # Order API should be using state as that's the normal payment field.
53
+ # spree_wombat serializes payment state as status so imported orders should fall back to status field.
54
+ payment.state = p[:state] || p[:status] || 'completed'
55
+ payment.created_at = p[:created_at] if p[:created_at]
56
+ payment.payment_method = Spree::PaymentMethod.find_by_name!(p[:payment_method])
57
+ payment.source = create_source_payment_from_params(p[:source], payment) if p[:source]
58
+ payment.save!
59
+ rescue Exception => e
60
+ raise "Order import payments: #{e.message} #{p}"
61
+ end
62
+ end
63
+ end
64
+
65
+ end
@@ -0,0 +1,3 @@
1
+ require 'spree_core'
2
+ require 'spree_winkelstraat/engine'
3
+ require 'spree_winkelstraat/order_importer'
@@ -0,0 +1,93 @@
1
+ # Run Coverage report
2
+ require 'simplecov'
3
+ SimpleCov.start do
4
+ add_filter 'spec/dummy'
5
+ add_group 'Controllers', 'app/controllers'
6
+ add_group 'Helpers', 'app/helpers'
7
+ add_group 'Mailers', 'app/mailers'
8
+ add_group 'Models', 'app/models'
9
+ add_group 'Views', 'app/views'
10
+ add_group 'Libraries', 'lib'
11
+ end
12
+
13
+ # Configure Rails Environment
14
+ ENV['RAILS_ENV'] = 'test'
15
+
16
+ require File.expand_path('../dummy/config/environment.rb', __FILE__)
17
+
18
+ require 'rspec/rails'
19
+ require 'database_cleaner'
20
+ require 'ffaker'
21
+
22
+ # Requires supporting ruby files with custom matchers and macros, etc,
23
+ # in spec/support/ and its subdirectories.
24
+ Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require f }
25
+
26
+ # Requires factories and other useful helpers defined in spree_core.
27
+ require 'spree/testing_support/authorization_helpers'
28
+ require 'spree/testing_support/capybara_ext'
29
+ require 'spree/testing_support/controller_requests'
30
+ require 'spree/testing_support/factories'
31
+ require 'spree/testing_support/url_helpers'
32
+
33
+ # Requires factories defined in lib/spree_winkelstraat/factories.rb
34
+ require 'spree_winkelstraat/factories'
35
+
36
+ RSpec.configure do |config|
37
+ config.include FactoryGirl::Syntax::Methods
38
+
39
+ # Infer an example group's spec type from the file location.
40
+ config.infer_spec_type_from_file_location!
41
+
42
+ # == URL Helpers
43
+ #
44
+ # Allows access to Spree's routes in specs:
45
+ #
46
+ # visit spree.admin_path
47
+ # current_path.should eql(spree.products_path)
48
+ config.include Spree::TestingSupport::UrlHelpers
49
+
50
+ # == Requests support
51
+ #
52
+ # Adds convenient methods to request Spree's controllers
53
+ # spree_get :index
54
+ config.include Spree::TestingSupport::ControllerRequests, type: :controller
55
+
56
+ # == Mock Framework
57
+ #
58
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
59
+ #
60
+ # config.mock_with :mocha
61
+ # config.mock_with :flexmock
62
+ # config.mock_with :rr
63
+ config.mock_with :rspec
64
+ config.color = true
65
+
66
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
67
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
68
+
69
+ # Capybara javascript drivers require transactional fixtures set to false, and we use DatabaseCleaner
70
+ # to cleanup after each test instead. Without transactional fixtures set to false the records created
71
+ # to setup a test will be unavailable to the browser, which runs under a separate server instance.
72
+ config.use_transactional_fixtures = false
73
+
74
+ # Ensure Suite is set to use transactions for speed.
75
+ config.before :suite do
76
+ DatabaseCleaner.strategy = :transaction
77
+ DatabaseCleaner.clean_with :truncation
78
+ end
79
+
80
+ # Before each spec check if it is a Javascript test and switch between using database transactions or not where necessary.
81
+ config.before :each do
82
+ DatabaseCleaner.strategy = RSpec.current_example.metadata[:js] ? :truncation : :transaction
83
+ DatabaseCleaner.start
84
+ end
85
+
86
+ # After each spec clean the database.
87
+ config.after :each do
88
+ DatabaseCleaner.clean
89
+ end
90
+
91
+ config.fail_fast = ENV['FAIL_FAST'] || false
92
+ config.order = "random"
93
+ end