solidus_marketplace 0.1.0

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 (116) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +8 -0
  6. data/LICENSE +26 -0
  7. data/README.md +123 -0
  8. data/Rakefile +15 -0
  9. data/Versionfile +6 -0
  10. data/app/assets/javascripts/spree/backend/solidus_marketplace.js +5 -0
  11. data/app/assets/javascripts/spree/backend/solidus_marketplace_routes.js +1 -0
  12. data/app/assets/javascripts/spree/backend/suppliers_autocomplete.js +55 -0
  13. data/app/assets/javascripts/spree/frontend/solidus_marketplace.js +1 -0
  14. data/app/assets/stylesheets/spree/backend/solidus_marketplace.scss +22 -0
  15. data/app/assets/stylesheets/spree/frontend/solidus_marketplace.css +3 -0
  16. data/app/controllers/ckeditor/attachment_files_controller_decorator.rb +20 -0
  17. data/app/controllers/ckeditor/pictures_controller_decorator.rb +17 -0
  18. data/app/controllers/spree/admin/marketplace_settings_controller.rb +19 -0
  19. data/app/controllers/spree/admin/products_controller_decorator.rb +79 -0
  20. data/app/controllers/spree/admin/reports_controller_decorator.rb +68 -0
  21. data/app/controllers/spree/admin/shipments_controller.rb +47 -0
  22. data/app/controllers/spree/admin/stock_items_controller_decorator.rb +10 -0
  23. data/app/controllers/spree/admin/stock_locations_controller_decorator.rb +23 -0
  24. data/app/controllers/spree/admin/suppliers_controller.rb +54 -0
  25. data/app/controllers/spree/admin/users_controller_decorator.rb +34 -0
  26. data/app/controllers/spree/api/suppliers_controller.rb +16 -0
  27. data/app/controllers/spree/api/v1/stock_locations_controller_decorator.rb +18 -0
  28. data/app/controllers/spree/base_controller_decorator.rb +13 -0
  29. data/app/helpers/spree/api/api_helpers_decorator.rb +22 -0
  30. data/app/mailers/spree/marketplace_order_mailer.rb +13 -0
  31. data/app/mailers/spree/supplier_mailer.rb +12 -0
  32. data/app/models/ckeditor/asset_decorator.rb +5 -0
  33. data/app/models/spree.rb +5 -0
  34. data/app/models/spree/marketplace_configuration.rb +14 -0
  35. data/app/models/spree/order_decorator.rb +44 -0
  36. data/app/models/spree/payment_decorator.rb +7 -0
  37. data/app/models/spree/product_decorator.rb +52 -0
  38. data/app/models/spree/shipment_decorator.rb +40 -0
  39. data/app/models/spree/stock/splitter/marketplace.rb +47 -0
  40. data/app/models/spree/stock_location_decorator.rb +23 -0
  41. data/app/models/spree/supplier.rb +120 -0
  42. data/app/models/spree/supplier_ability.rb +35 -0
  43. data/app/models/spree/supplier_variant.rb +6 -0
  44. data/app/models/spree/user_decorator.rb +23 -0
  45. data/app/models/spree/variant_decorator.rb +24 -0
  46. data/app/overrides/spree/admin/menus.rb +15 -0
  47. data/app/overrides/spree/admin/products/_form/converted_admin_product_form_right.html.erb.deface +5 -0
  48. data/app/overrides/spree/admin/products/edit/override_rows.html.erb.deface +22 -0
  49. data/app/overrides/spree/admin/stock_locations/_form/add_supplier.html.erb.deface +12 -0
  50. data/app/views/spree/admin/marketplace_settings/edit.html.erb +21 -0
  51. data/app/views/spree/admin/orders/index.html.erb +187 -0
  52. data/app/views/spree/admin/products/_form.html.erb +198 -0
  53. data/app/views/spree/admin/reports/earnings.html.erb +34 -0
  54. data/app/views/spree/admin/shared/_marketplace_settings.html.erb +1 -0
  55. data/app/views/spree/admin/shared/_marketplace_tabs.html.erb +4 -0
  56. data/app/views/spree/admin/shipments/edit.html.erb +24 -0
  57. data/app/views/spree/admin/shipments/index.html.erb +93 -0
  58. data/app/views/spree/admin/suppliers/_form.html.erb +75 -0
  59. data/app/views/spree/admin/suppliers/edit.html.erb +22 -0
  60. data/app/views/spree/admin/suppliers/index.html.erb +68 -0
  61. data/app/views/spree/admin/suppliers/new.html.erb +17 -0
  62. data/app/views/spree/api/shared/_pagination.json.jbuilder +5 -0
  63. data/app/views/spree/api/suppliers/_supplier.json.jbuilder +1 -0
  64. data/app/views/spree/api/suppliers/index.json.jbuilder +4 -0
  65. data/app/views/spree/marketplace_order_mailer/supplier_order.html.erb +119 -0
  66. data/app/views/spree/shared/unauthorized.erb +1 -0
  67. data/app/views/spree/supplier_mailer/welcome.html.erb +53 -0
  68. data/config/locales/en.yml +107 -0
  69. data/config/locales/es.yml +133 -0
  70. data/config/routes.rb +24 -0
  71. data/db/default/spree/marketplace_roles.rb +14 -0
  72. data/db/migrate/20121006073854_create_suppliers.rb +20 -0
  73. data/db/migrate/20130216070944_product_belongs_to_supplier.rb +6 -0
  74. data/db/migrate/20130405005502_stock_locations_belongs_to_supplier.rb +6 -0
  75. data/db/migrate/20130405011127_user_belongs_to_supplier.rb +6 -0
  76. data/db/migrate/20130428063053_add_balanced_token_to_suppliers.rb +7 -0
  77. data/db/migrate/20130510181443_add_supplier_id_to_ckeditor_assets.rb +8 -0
  78. data/db/migrate/20130606220913_add_permalink_to_suppliers.rb +6 -0
  79. data/db/migrate/20140323170638_add_supplier_commission_to_shipments.rb +5 -0
  80. data/db/migrate/20140416184616_migrate_payment_and_commission.rb +7 -0
  81. data/db/migrate/20140529041325_create_spree_supplier_variants.rb +15 -0
  82. data/db/migrate/20171027180043_add_paypal_email_to_suppliers.rb +5 -0
  83. data/db/seeds.rb +8 -0
  84. data/lib/generators/solidus_marketplace/install/install_generator.rb +36 -0
  85. data/lib/solidus_marketplace.rb +6 -0
  86. data/lib/solidus_marketplace/engine.rb +53 -0
  87. data/lib/solidus_marketplace/factories.rb +107 -0
  88. data/lib/solidus_marketplace/version.rb +3 -0
  89. data/lib/spree/permitted_attributes_decorator.rb +18 -0
  90. data/lib/tasks/spree_sample.rake +72 -0
  91. data/log/awesome.log +1 -0
  92. data/script/rails +7 -0
  93. data/solidus_marketplace.gemspec +46 -0
  94. data/spec/features/admin/orders_spec.rb +11 -0
  95. data/spec/features/admin/products_spec.rb +25 -0
  96. data/spec/features/admin/return_authorizations_spec.rb +7 -0
  97. data/spec/features/admin/settings_spec.rb +33 -0
  98. data/spec/features/admin/shipments_spec.rb +80 -0
  99. data/spec/features/admin/stock_management_spec.rb +156 -0
  100. data/spec/features/admin/stock_spec.rb +98 -0
  101. data/spec/features/admin/suppliers_spec.rb +130 -0
  102. data/spec/models/spree/order_decorator_spec.rb +80 -0
  103. data/spec/models/spree/payment_decorator_spec.rb +7 -0
  104. data/spec/models/spree/product_decorator_spec.rb +56 -0
  105. data/spec/models/spree/shipment_decorator_spec.rb +48 -0
  106. data/spec/models/spree/stock/splitter/marketplace_spec.rb +62 -0
  107. data/spec/models/spree/stock_location_decorator_spec.rb +33 -0
  108. data/spec/models/spree/supplier_ability_spec.rb +182 -0
  109. data/spec/models/spree/supplier_spec.rb +123 -0
  110. data/spec/models/spree/supplier_variant_spec.rb +5 -0
  111. data/spec/models/spree/user_decorator_spec.rb +57 -0
  112. data/spec/models/spree/variant_decorator_spec.rb +7 -0
  113. data/spec/spec_helper.rb +91 -0
  114. data/spec/support/ability_helpers.rb +11 -0
  115. data/spec/support/integration_helpers.rb +15 -0
  116. metadata +473 -0
@@ -0,0 +1,40 @@
1
+ Spree::Shipment.class_eval do
2
+ # TODO here to fix cancan issue thinking its just Order
3
+ belongs_to :order, class_name: 'Spree::Order', touch: true, inverse_of: :shipments
4
+
5
+ has_many :payments, as: :payable
6
+
7
+ scope :by_supplier, -> (supplier_id) { joins(:stock_location).where(spree_stock_locations: { supplier_id: supplier_id }) }
8
+
9
+ delegate :supplier, to: :stock_location
10
+
11
+ self.whitelisted_ransackable_attributes = ["number", "state"]
12
+
13
+ def display_final_price_with_items
14
+ Spree::Money.new final_price_with_items
15
+ end
16
+
17
+ def final_price_with_items
18
+ self.item_cost + self.final_price
19
+ end
20
+
21
+ # TODO move commission to spree_marketplace?
22
+ def supplier_commission_total
23
+ ((self.final_price_with_items * self.supplier.commission_percentage / 100) + self.supplier.commission_flat_rate)
24
+ end
25
+
26
+ private
27
+
28
+ durably_decorate :after_ship, mode: 'soft', sha: '5401c76850108aba74c87a87ff634379bdc844ce' do
29
+ original_after_ship
30
+
31
+ if supplier.present?
32
+ update_commission
33
+ end
34
+ end
35
+
36
+ def update_commission
37
+ update_column :supplier_commission, self.supplier_commission_total
38
+ end
39
+
40
+ end
@@ -0,0 +1,47 @@
1
+ module Spree
2
+ module Stock
3
+ module Splitter
4
+ class Marketplace < Spree::Stock::Splitter::Base
5
+
6
+ def split(packages)
7
+ begin
8
+ split_packages = []
9
+ packages.each do |package|
10
+ # Package fulfilled items together.
11
+ fulfilled = package.contents.select { |content|
12
+ begin
13
+ content.variant.suppliers.count == 0
14
+ rescue => e
15
+ end
16
+ }
17
+ split_packages << build_package(fulfilled)
18
+ # Determine which supplier to package shipped items.
19
+ supplier_contents = package.contents.select { |content| content.variant.suppliers.count > 0 }
20
+ supplier_contents.each do |content|
21
+ # Select the related variant
22
+ variant = content.variant
23
+ # Select suppliers ordering ascending according to cost.
24
+ suppliers = variant.supplier_variants.order("spree_supplier_variants.cost ASC").map(&:supplier)
25
+ # Select first supplier that has stock location with avialable stock item.
26
+ available_supplier = suppliers.detect do |supplier|
27
+ supplier.stock_locations_with_available_stock_items(variant).any?
28
+ end
29
+ # Select the first available stock location with in the available_supplier stock locations.
30
+ stock_location = available_supplier.stock_locations_with_available_stock_items(variant).first
31
+ # Add to any existing packages or create a new one.
32
+ if existing_package = split_packages.detect { |p| p.stock_location == stock_location }
33
+ existing_package.contents << content
34
+ else
35
+ split_packages << Spree::Stock::Package.new(stock_location, [content])
36
+ end
37
+ end
38
+ end
39
+ rescue => e
40
+ end
41
+ return_next split_packages
42
+ end
43
+
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,23 @@
1
+ Spree::StockLocation.class_eval do
2
+
3
+ belongs_to :supplier, class_name: 'Spree::Supplier'
4
+
5
+ scope :by_supplier, -> (supplier_id) { where(supplier_id: supplier_id) }
6
+
7
+ # Wrapper for creating a new stock item respecting the backorderable config and supplier
8
+ durably_decorate :propagate_variant, mode: 'soft', sha: '68fd322da48facbdbf567a2391c2495d04c3c8bc' do |variant|
9
+ if self.supplier_id.blank? || variant.suppliers.pluck(:id).include?(self.supplier_id)
10
+ self.stock_items.create!(variant: variant, backorderable: self.backorderable_default)
11
+ end
12
+ end
13
+
14
+ def unpropagate_variant(variant)
15
+ stock_items = self.stock_items.where(variant: variant)
16
+ stock_items.map(&:destroy)
17
+ end
18
+
19
+ def available?(variant)
20
+ stock_item(variant).try(:available?)
21
+ end
22
+
23
+ end
@@ -0,0 +1,120 @@
1
+ class Spree::Supplier < Spree::Base
2
+ extend FriendlyId
3
+ # include ActiveModel::ForbiddenAttributesProtection
4
+ friendly_id :name, use: :slugged
5
+
6
+ attr_accessor :password, :password_confirmation
7
+
8
+ #==========================================
9
+ # Associations
10
+
11
+ belongs_to :address, class_name: 'Spree::Address'
12
+ accepts_nested_attributes_for :address
13
+
14
+ if defined?(Ckeditor::Asset)
15
+ has_many :ckeditor_pictures
16
+ has_many :ckeditor_attachment_files
17
+ end
18
+ has_many :supplier_variants
19
+ has_many :variants, through: :supplier_variants
20
+ has_many :products, through: :variants
21
+
22
+ has_many :stock_locations
23
+ has_many :shipments, through: :stock_locations
24
+
25
+ has_many :users, class_name: Spree.user_class.to_s
26
+
27
+ #==========================================
28
+ # Validations
29
+
30
+ validates :commission_flat_rate, presence: true
31
+ validates :commission_percentage, presence: true
32
+ validates :email, presence: true, email: true, uniqueness: true
33
+ validates :name, presence: true, uniqueness: true
34
+ validates :url, format: { with: URI::regexp(%w(http https)), allow_blank: true }
35
+
36
+ #==========================================
37
+ # Callbacks
38
+
39
+ after_create :assign_user
40
+ after_create :create_stock_location
41
+ after_create :send_welcome, if: -> { SolidusMarketplace::Config[:send_supplier_email] }
42
+ before_create :set_commission
43
+ before_validation :check_url
44
+
45
+ #==========================================
46
+ # Instance Methods
47
+ scope :active, -> { where(active: true) }
48
+
49
+ def deleted?
50
+ deleted_at.present?
51
+ end
52
+
53
+ def user_ids_string
54
+ user_ids.join(',')
55
+ end
56
+
57
+ def user_ids_string=(s)
58
+ self.user_ids = s.to_s.split(',').map(&:strip)
59
+ end
60
+
61
+ # Retreive the stock locations that has available
62
+ # stock items of the given variant
63
+ def stock_locations_with_available_stock_items(variant)
64
+ stock_locations.select { |sl| sl.available?(variant) }
65
+ end
66
+
67
+ #==========================================
68
+ # Protected Methods
69
+
70
+ protected
71
+
72
+ def assign_user
73
+ if self.users.empty?
74
+ if user = Spree.user_class.find_by_email(self.email)
75
+ self.users << user
76
+ self.save
77
+ end
78
+ end
79
+ end
80
+
81
+ def check_url
82
+ unless self.url.blank? or self.url =~ URI::regexp(%w(http https))
83
+ self.url = "http://#{self.url}"
84
+ end
85
+ end
86
+
87
+ def create_stock_location
88
+ if self.stock_locations.empty?
89
+ location = self.stock_locations.build(
90
+ active: true,
91
+ country_id: self.address.try(:country_id),
92
+ name: self.name,
93
+ state_id: self.address.try(:state_id)
94
+ )
95
+ # It's important location is always created. Some apps add validations that shouldn't break this.
96
+ location.save validate: false
97
+ end
98
+ end
99
+
100
+ def send_welcome
101
+ begin
102
+ Spree::SupplierMailer.welcome(self.id).deliver_later!
103
+ # Specs raise error for not being able to set default_url_options[:host]
104
+ rescue => ex #Errno::ECONNREFUSED => ex
105
+ Rails.logger.error ex.message
106
+ Rails.logger.error ex.backtrace.join("\n")
107
+ return true # always return true so that failed email doesn't crash app.
108
+ end
109
+ end
110
+
111
+ def set_commission
112
+ unless changes.has_key?(:commission_flat_rate)
113
+ self.commission_flat_rate = SolidusMarketplace::Config[:default_commission_flat_rate]
114
+ end
115
+ unless changes.has_key?(:commission_percentage)
116
+ self.commission_percentage = SolidusMarketplace::Config[:default_commission_percentage]
117
+ end
118
+ end
119
+
120
+ end
@@ -0,0 +1,35 @@
1
+ module Spree
2
+ class SupplierAbility
3
+ include CanCan::Ability
4
+
5
+ def initialize(user)
6
+ user ||= Spree.user_class.new
7
+
8
+ if user.supplier_admin?
9
+ can [:admin, :update, :read, :display, :stock], Spree::Product, suppliers: { id: user.supplier_id }
10
+ can [:admin, :create], Spree::Product
11
+ can [:admin, :create, :update, :destroy, :display], Spree::Variant, suppliers: { id: user.supplier_id }
12
+
13
+ can [:admin, :display, :index], Spree::Shipment, order: { state: 'complete' },
14
+ stock_location: { supplier_id: user.supplier_id }
15
+
16
+ can [:admin, :display], Spree::ReturnAuthorization, stock_location: { supplier_id: user.supplier_id }
17
+ can [:admin, :display], Spree::CustomerReturn, stock_location: { supplier_id: user.supplier_id }
18
+
19
+ #FIXME: come back to these when we work on shipping-related issues
20
+ # can [:admin, :manage, :read, :ready, :ship], Spree::Shipment, order: { state: 'complete' }, stock_location: { supplier_id: user.supplier_id }
21
+ # can [:admin, :create, :update], :stock_items
22
+ can [:admin, :index, :create, :edit, :read, :update], Spree::StockItem, stock_location: { supplier_id: user.supplier_id }
23
+ can [:admin, :manage, :create], Spree::StockLocation, supplier_id: user.supplier_id
24
+ can [:admin, :manage, :create], Spree::StockMovement, stock_item: { stock_location: { supplier_id: user.supplier_id } }
25
+
26
+ can [:admin, :create, :read, :update, :display], Spree::Supplier, id: user.supplier_id
27
+ cannot [:create], Spree::Supplier
28
+
29
+ can [:admin, :manage], Spree::User, supplier_id: user.supplier_id
30
+ can [:admin, :index, :edit], Spree::Order, stock_locations: { supplier_id: user.supplier_id }
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,6 @@
1
+ module Spree
2
+ class SupplierVariant < Spree::Base
3
+ belongs_to :supplier
4
+ belongs_to :variant
5
+ end
6
+ end
@@ -0,0 +1,23 @@
1
+ Spree.user_class.class_eval do
2
+
3
+ belongs_to :supplier, class_name: 'Spree::Supplier'
4
+
5
+ has_many :variants, through: :supplier
6
+
7
+ def supplier?
8
+ supplier.present?
9
+ end
10
+
11
+ def supplier_admin?
12
+ spree_roles.map(&:name).include?("supplier_admin")
13
+ end
14
+
15
+ def market_maker?
16
+ has_admin_role?
17
+ end
18
+
19
+ def has_admin_role?
20
+ spree_roles.map(&:name).include?("admin")
21
+ end
22
+
23
+ end
@@ -0,0 +1,24 @@
1
+ module Spree
2
+ Variant.class_eval do
3
+
4
+ has_many :supplier_variants
5
+ has_many :suppliers, through: :supplier_variants
6
+
7
+ before_create :populate_for_suppliers
8
+
9
+ private
10
+
11
+ durably_decorate :create_stock_items, mode: 'soft', sha: '98704433ac5c66ba46e02699f3cf03d13d4f1281' do
12
+ StockLocation.all.each do |stock_location|
13
+ if stock_location.supplier_id.blank? || self.suppliers.pluck(:id).include?(stock_location.supplier_id)
14
+ stock_location.propagate_variant(self) if stock_location.propagate_all_variants?
15
+ end
16
+ end
17
+ end
18
+
19
+ def populate_for_suppliers
20
+ self.suppliers = self.product.suppliers
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,15 @@
1
+ Deface::Override.new(
2
+ virtual_path: "spree/admin/shared/_menu",
3
+ name: "marketplace_menus",
4
+ insert_bottom: '[data-hook="admin_tabs"]',
5
+ partial: "spree/admin/shared/marketplace_tabs"
6
+ )
7
+
8
+
9
+ Deface::Override.new(
10
+ virtual_path: "spree/admin/shared/_configuration_menu",
11
+ name: "marketplace_admin_configurations_menu",
12
+ insert_bottom: "[data-hook='admin_configurations_sidebar_menu']",
13
+ disabled: false,
14
+ partial: "spree/admin/shared/marketplace_settings"
15
+ )
@@ -0,0 +1,5 @@
1
+ <!-- insert_bottom "[data-hook='admin_product_form_right'], #admin_product_form_right[data-hook]" -->
2
+
3
+ <% if can? :manage, Spree::Supplier %>
4
+ <!-- TODO allow assignment to variants -->
5
+ <% end %>
@@ -0,0 +1,22 @@
1
+ <!-- replace_contents '[data-hook="admin_products_index_rows"]' -->
2
+
3
+ <%# Changed classes to new like https://github.com/spree/spree/blob/master/backend/app/views/spree/admin/stock_locations/_form.html.erb %>
4
+ <td class="sku"><%= product.sku rescue '' %></td>
5
+ <td class="image"><%= mini_image product, class: "thumbnail" %></td>
6
+ <td>
7
+ <% if try_spree_current_user && try_spree_current_user.supplier? %>
8
+ <%= link_to product.try(:name), spree.admin_product_stock_path(product)%>
9
+ <% else %>
10
+ <%= link_to product.try(:name), edit_admin_product_path(product) %>
11
+ <% end %>
12
+ </td>
13
+ <td><%= product.display_price.to_html rescue '' %></td>
14
+ <td class="actions" data-hook="admin_products_index_row_actions">
15
+ <% if try_spree_current_user && try_spree_current_user.supplier? %>
16
+ <%= link_to 'Stock Management', spree.admin_product_stock_path(product), title:'Stock Management', class: 'btn btn-default btn-sm with-tip without-textdecor' if can?(:stock, product) && !product.deleted? %>
17
+ <% else %>
18
+ <%= link_to_edit product, :no_text => true, :class => 'edit' if can?(:edit, product) && !product.deleted? %>
19
+ <% end %>
20
+ <%= link_to_clone product, :no_text => true, :class => 'clone' if can?(:clone, product) %>
21
+ <%= link_to_delete product, :no_text => true if can?(:delete, product) && !product.deleted? %>
22
+ </td>
@@ -0,0 +1,12 @@
1
+ <!-- insert_after "[data-hook=admin_stock_locations_form_fields]" -->
2
+
3
+ <%# Remove extra div and change classes %>
4
+ <% if spree_current_user.admin? %>
5
+ <div class='form-group'>
6
+ <%= f.field_container :supplier do %>
7
+ <%= f.label :supplier_id, Spree.t(:supplier) %>
8
+ <%= f.collection_select(:supplier_id, Spree::Supplier.all, :id, :name, { :include_blank => 'None' }, { :class => 'select2' }) %>
9
+ <%= f.error_message_on :supplier %>
10
+ <% end %>
11
+ </div>
12
+ <% end %>
@@ -0,0 +1,21 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t("marketplace_settings") %>
3
+ <% end %>
4
+
5
+ <%= form_tag(spree.admin_marketplace_settings_path, :method => :put) do %>
6
+ <fieldset class="general no-border-top">
7
+ <% %w( default_commission_flat_rate default_commission_percentage automatically_deliver_orders_to_supplier send_supplier_email).each do |key|
8
+ type = SolidusMarketplace::Config.preference_type(key) %>
9
+ <div class="field col-md-6">
10
+ <%= label_tag(key, Spree.t(key) + ': ') + tag(:br) if type != :boolean %>
11
+ <%= preference_field_tag(key, SolidusMarketplace::Config[key], :type => type ,:class => 'form-control')%>
12
+ <%= label_tag(key, Spree.t(key)) + tag(:br) if type == :boolean %>
13
+ </div>
14
+ <% end %>
15
+ <div class="form-buttons" data-hook="buttons">
16
+ <%= button Spree.t(:update), 'update' %>
17
+ <span class="or"><%= Spree.t(:or) %></span>
18
+ <%= button_link_to Spree.t(:cancel), spree.edit_admin_marketplace_settings_url, :icon => 'cancel' %>
19
+ </div>
20
+ </fieldset>
21
+ <% end %>
@@ -0,0 +1,187 @@
1
+ <% admin_layout "full-width" %>
2
+
3
+ <% admin_breadcrumb(plural_resource_name(Spree::Order)) %>
4
+
5
+
6
+ <% content_for :page_actions do %>
7
+ <li>
8
+ <%= button_link_to Spree.t(:new_order), new_admin_order_url, id: 'admin_new_order' %>
9
+ </li>
10
+ <% end if can? :create, Spree::Order %>
11
+
12
+ <% content_for :table_filter_title do %>
13
+ <%= Spree.t(:search) %>
14
+ <% end %>
15
+
16
+ <% content_for :table_filter do %>
17
+ <div data-hook="admin_orders_index_search">
18
+ <%= search_form_for [:admin, @search] do |f| %>
19
+ <div class="row">
20
+ <div class="field-block col-12 col-md-6 col-lg-4 col-xl-3">
21
+ <div class="date-range-filter field">
22
+ <%= label_tag :q_created_at_gt, Spree.t(:date_range) %>
23
+ <div class="date-range-fields input-group">
24
+ <%= f.text_field :created_at_gt, class: 'datepicker form-control datepicker-from', value: params[:q][:created_at_gt], placeholder: Spree.t(:start) %>
25
+
26
+ <span class="range-divider input-group-addon">
27
+ <i class="fa fa-arrow-right"></i>
28
+ </span>
29
+
30
+ <%= f.text_field :created_at_lt, class: 'datepicker form-control datepicker-to', value: params[:q][:created_at_lt], placeholder: Spree.t(:stop) %>
31
+ </div>
32
+ </div>
33
+
34
+ <div class="field">
35
+ <%= label_tag :q_state_eq, Spree.t(:status) %>
36
+ <%= f.select :state_eq, Spree::Order.state_machines[:state].states.collect {|s| [Spree.t("order_state.#{s.name}"), s.value]}, {include_blank: true}, class: 'custom-select fullwidth' %>
37
+ </div>
38
+
39
+ <div class="field">
40
+ <%= label_tag nil, Spree.t(:promotion) %>
41
+ <%= f.text_field :order_promotions_promotion_code_value_cont, size: 25 %>
42
+ </div>
43
+
44
+ <div class="field">
45
+ <%= label_tag nil, Spree.t(:shipment_number) %>
46
+ <%= f.text_field :shipments_number_cont %>
47
+ </div>
48
+
49
+ </div>
50
+
51
+ <div class="col-12 col-md-6 col-lg-4 col-xl-6">
52
+ <div class="row">
53
+ <div class="col-12 col-xl-6">
54
+ <div class="field">
55
+ <%= label_tag :q_number_cont, Spree.t(:order_number, number: '') %>
56
+ <%= f.text_field :number_cont %>
57
+ </div>
58
+
59
+ <div class="field">
60
+ <%= label_tag :q_email_cont, Spree.t(:email) %>
61
+ <%= f.text_field :email_cont %>
62
+ </div>
63
+ </div>
64
+
65
+ <div class="col-12 col-xl-6">
66
+ <div class="field">
67
+ <%= label_tag :q_bill_address_firstname_start, Spree.t(:first_name_begins_with) %>
68
+ <%= f.text_field :bill_address_firstname_start, size: 25 %>
69
+ </div>
70
+ <div class="field">
71
+ <%= label_tag :q_bill_address_lastname_start, Spree.t(:last_name_begins_with) %>
72
+ <%= f.text_field :bill_address_lastname_start, size: 25%>
73
+ </div>
74
+ </div>
75
+
76
+ <div class="col-12 col-xl-6">
77
+ <div class="field" data-hook="sku-select">
78
+ <%= label_tag :q_line_items_variant_id_in, Spree.t(:variant) %>
79
+ <%= f.text_field :line_items_variant_id_in, class: "variant_autocomplete fullwidth" %>
80
+ </div>
81
+ </div>
82
+ </div>
83
+ </div>
84
+
85
+ <div class="col-12 col-md-6 col-lg-4 col-xl-3">
86
+ <% if Spree::Store.count > 1 %>
87
+ <div class="field">
88
+ <%= label_tag :q_store_id_eq, Spree.t(:store) %>
89
+ <%= f.select :store_id_eq, Spree::Store.all.map { |s| [s.name, s.id] }, { include_blank: true }, { class: "custom-select fullwidth" } %>
90
+ </div>
91
+ <% end %>
92
+
93
+ <div class="field checkbox">
94
+ <label>
95
+ <%= f.check_box :completed_at_not_null, {checked: @show_only_completed}, '1', '0' %>
96
+ <%= Spree.t(:show_only_complete_orders) %>
97
+ </label>
98
+ </div>
99
+ </div>
100
+
101
+ </div>
102
+
103
+ <div class="clearfix"></div>
104
+
105
+ <div class="actions filter-actions">
106
+ <div data-hook="admin_orders_index_search_buttons">
107
+ <%= button Spree.t(:filter_results) %>
108
+ </div>
109
+ </div>
110
+ <% end %>
111
+ </div>
112
+ <% end %>
113
+
114
+ <%= paginate @orders, theme: "solidus_admin" %>
115
+
116
+ <% if @orders.any? %>
117
+ <table class="index" id="listing_orders" data-hook>
118
+ <colgroup>
119
+ <col style="width: 13%;">
120
+ <col style="width: 10%;">
121
+ <col style="width: 10%;">
122
+ <col style="width: 12%;">
123
+ <% if Spree::Order.checkout_step_names.include?(:delivery) %>
124
+ <col style="width: 12%;">
125
+ <% end %>
126
+ <col style="width: 25%;">
127
+ <col style="width: 10%;">
128
+ <col style="width: 8%;">
129
+ </colgroup>
130
+ <thead>
131
+ <tr data-hook="admin_orders_index_headers">
132
+ <% if @show_only_completed %>
133
+ <th><%= sort_link @search, :completed_at %></th>
134
+ <% else %>
135
+ <th><%= sort_link @search, :created_at %></th>
136
+ <% end %>
137
+ <th><%= sort_link @search, :number %></th>
138
+ <th><%= sort_link @search, :state %></th>
139
+ <th><%= sort_link @search, :payment_state %></th>
140
+ <% if Spree::Order.checkout_step_names.include?(:delivery) %>
141
+ <th><%= sort_link @search, :shipment_state %></th>
142
+ <% end %>
143
+ <th><%= sort_link @search, :email %></th>
144
+ <th><%= sort_link @search, :total %></th>
145
+ <th data-hook="admin_orders_index_header_actions" class="actions"></th>
146
+ </tr>
147
+ </thead>
148
+ <tbody>
149
+ <% @orders.each do |order| %>
150
+ <tr data-hook="admin_orders_index_rows" class="state-<%= order.state.downcase %> <%= cycle('odd', 'even') %>">
151
+ <td class="align-center"><%= l (@show_only_completed ? order.completed_at : order.created_at).to_date %></td>
152
+ <td class="align-center"><%= link_to order.number, edit_admin_order_path(order) %></td>
153
+ <td class="align-center"><span class="state <%= order.state.downcase %>"><%= Spree.t("order_state.#{order.state.downcase}") %></span></td>
154
+ <td class="align-center"><span class="state <%= order.payment_state %>"><%= link_to Spree.t("payment_states.#{order.payment_state}"), admin_order_payments_path(order) if order.payment_state %></span></td>
155
+ <% if Spree::Order.checkout_step_names.include?(:delivery) %>
156
+ <td class="align-center"><span class="state <%= order.shipment_state %>"><%= Spree.t("shipment_states.#{order.shipment_state}") if order.shipment_state %></span></td>
157
+ <% end %>
158
+ <td>
159
+ <% if order.user %>
160
+ <%= link_to order.email, edit_admin_user_path(order.user) %>
161
+ <% else %>
162
+ <%= mail_to order.email %>
163
+ <% end %>
164
+ </td>
165
+ <td class="align-center">
166
+ <% if try_spree_current_user.supplier? %>
167
+ <%= order.supplier_total(try_spree_current_user).to_html %>
168
+ <% else %>
169
+ <%= order.display_total.to_html %>
170
+ <% end %>
171
+ </td>
172
+ <td class='actions align-center' data-hook="admin_orders_index_row_actions">
173
+ <%= link_to_edit_url edit_admin_order_path(order), title: "admin_edit_#{dom_id(order)}", no_text: true %>
174
+ </td>
175
+ </tr>
176
+ <% end %>
177
+ </tbody>
178
+ </table>
179
+ <% else %>
180
+ <div class="col-9 no-objects-found">
181
+ <%= render 'spree/admin/shared/no_objects_found',
182
+ resource: Spree::Order,
183
+ new_resource_url: spree.new_admin_order_path %>
184
+ </div>
185
+ <% end %>
186
+
187
+ <%= paginate @orders, theme: "solidus_admin" %>