spree_drop_ship 3.1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +9 -0
- data/LICENSE +21 -0
- data/README.md +116 -0
- data/Rakefile +15 -0
- data/Versionfile +6 -0
- data/app/assets/javascripts/spree/backend/spree_drop_ship.js +2 -0
- data/app/assets/javascripts/spree/frontend/spree_drop_ship.js +1 -0
- data/app/assets/stylesheets/spree/backend/spree_drop_ship.scss +22 -0
- data/app/assets/stylesheets/spree/frontend/spree_drop_ship.css +3 -0
- data/app/controllers/ckeditor/attachment_files_controller_decorator.rb +20 -0
- data/app/controllers/ckeditor/pictures_controller_decorator.rb +17 -0
- data/app/controllers/spree/admin/drop_ship_settings_controller.rb +19 -0
- data/app/controllers/spree/admin/products_controller_decorator.rb +19 -0
- data/app/controllers/spree/admin/shipments_controller.rb +47 -0
- data/app/controllers/spree/admin/stock_locations_controller_decorator.rb +14 -0
- data/app/controllers/spree/admin/suppliers_controller.rb +32 -0
- data/app/controllers/spree/api/v1/stock_locations_controller_decorator.rb +18 -0
- data/app/controllers/spree/base_controller_decorator.rb +23 -0
- data/app/mailers/spree/drop_ship_order_mailer.rb +13 -0
- data/app/mailers/spree/supplier_mailer.rb +12 -0
- data/app/models/ckeditor/asset_decorator.rb +5 -0
- data/app/models/spree/drop_ship_configuration.rb +17 -0
- data/app/models/spree/order_decorator.rb +27 -0
- data/app/models/spree/payment_decorator.rb +7 -0
- data/app/models/spree/product_decorator.rb +32 -0
- data/app/models/spree/shipment_decorator.rb +39 -0
- data/app/models/spree/stock/splitter/drop_ship.rb +42 -0
- data/app/models/spree/stock_location_decorator.rb +18 -0
- data/app/models/spree/supplier.rb +117 -0
- data/app/models/spree/supplier_ability.rb +28 -0
- data/app/models/spree/supplier_variant.rb +6 -0
- data/app/models/spree/user_decorator.rb +11 -0
- data/app/models/spree/variant_decorator.rb +24 -0
- data/app/models/spree.rb +5 -0
- data/app/overrides/spree/admin/products/_form/converted_admin_product_form_right.html.erb.deface +5 -0
- data/app/overrides/spree/admin/products/index/override_rows.html.erb.deface +22 -0
- data/app/overrides/spree/admin/shared/sub_menu/_configuration/add_drop_ship_settings.html.erb.deface +3 -0
- data/app/overrides/spree/admin/stock_locations/_form/add_supplier.html.erb.deface +12 -0
- data/app/overrides/spree/admin/stock_movements/_form/fix_bootstrap_form.html.erb.deface +11 -0
- data/app/overrides/spree/layouts/admin/add_profile_admin_tabs.html.erb.deface +8 -0
- data/app/overrides/spree/layouts/admin/converted_admin_tabs.html.erb.deface +18 -0
- data/app/views/spree/admin/drop_ship_settings/edit.html.erb +21 -0
- data/app/views/spree/admin/shared/_header.html.erb +24 -0
- data/app/views/spree/admin/shipments/edit.html.erb +24 -0
- data/app/views/spree/admin/shipments/index.html.erb +95 -0
- data/app/views/spree/admin/suppliers/_form.html.erb +69 -0
- data/app/views/spree/admin/suppliers/edit.html.erb +22 -0
- data/app/views/spree/admin/suppliers/index.html.erb +71 -0
- data/app/views/spree/admin/suppliers/new.html.erb +17 -0
- data/app/views/spree/drop_ship_order_mailer/supplier_order.html.erb +119 -0
- data/app/views/spree/shared/unauthorized.erb +1 -0
- data/app/views/spree/supplier_mailer/welcome.html.erb +53 -0
- data/config/locales/en.yml +89 -0
- data/config/locales/es.yml +133 -0
- data/config/routes.rb +9 -0
- data/db/migrate/20121006073854_create_suppliers.rb +20 -0
- data/db/migrate/20130216070944_product_belongs_to_supplier.rb +6 -0
- data/db/migrate/20130405005502_stock_locations_belongs_to_supplier.rb +6 -0
- data/db/migrate/20130405011127_user_belongs_to_supplier.rb +6 -0
- data/db/migrate/20130428063053_add_balanced_token_to_suppliers.rb +7 -0
- data/db/migrate/20130510181443_add_supplier_id_to_ckeditor_assets.rb +8 -0
- data/db/migrate/20130606220913_add_permalink_to_suppliers.rb +6 -0
- data/db/migrate/20140323170638_add_supplier_commission_to_shipments.rb +5 -0
- data/db/migrate/20140416184616_migrate_payment_and_commission.rb +7 -0
- data/db/migrate/20140529041325_create_spree_supplier_variants.rb +15 -0
- data/lib/generators/spree_drop_ship/install/install_generator.rb +30 -0
- data/lib/spree_drop_ship/engine.rb +31 -0
- data/lib/spree_drop_ship/factories.rb +93 -0
- data/lib/spree_drop_ship.rb +6 -0
- data/lib/tasks/spree_sample.rake +72 -0
- data/script/rails +7 -0
- data/spec/features/admin/orders_spec.rb +12 -0
- data/spec/features/admin/products_spec.rb +25 -0
- data/spec/features/admin/return_authorizations_spec.rb +7 -0
- data/spec/features/admin/settings_spec.rb +33 -0
- data/spec/features/admin/shipments_spec.rb +80 -0
- data/spec/features/admin/stock_management_spec.rb +153 -0
- data/spec/features/admin/stock_spec.rb +98 -0
- data/spec/features/admin/suppliers_spec.rb +126 -0
- data/spec/models/spree/order_decorator_spec.rb +54 -0
- data/spec/models/spree/payment_decorator_spec.rb +7 -0
- data/spec/models/spree/product_decorator_spec.rb +13 -0
- data/spec/models/spree/shipment_decorator_spec.rb +47 -0
- data/spec/models/spree/stock/splitter/drop_ship_spec.rb +62 -0
- data/spec/models/spree/stock_location_decorator_spec.rb +33 -0
- data/spec/models/spree/supplier_ability_spec.rb +172 -0
- data/spec/models/spree/supplier_spec.rb +123 -0
- data/spec/models/spree/supplier_variant_spec.rb +5 -0
- data/spec/models/spree/user_decorator_spec.rb +17 -0
- data/spec/models/spree/variant_decorator_spec.rb +7 -0
- data/spec/spec_helper.rb +79 -0
- data/spec/support/integration_helpers.rb +15 -0
- data/spree_drop_ship.gemspec +42 -0
- metadata +411 -0
@@ -0,0 +1,18 @@
|
|
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: 'f35b0d8a811311d4886d53024a9aa34e3aa5f8cb' 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 available?(variant)
|
15
|
+
stock_item(variant).try(:available?)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
class Spree::Supplier < Spree::Base
|
2
|
+
extend FriendlyId
|
3
|
+
friendly_id :name, use: :slugged
|
4
|
+
|
5
|
+
attr_accessor :password, :password_confirmation
|
6
|
+
|
7
|
+
#==========================================
|
8
|
+
# Associations
|
9
|
+
|
10
|
+
belongs_to :address, class_name: 'Spree::Address'
|
11
|
+
accepts_nested_attributes_for :address
|
12
|
+
|
13
|
+
if defined?(Ckeditor::Asset)
|
14
|
+
has_many :ckeditor_pictures
|
15
|
+
has_many :ckeditor_attachment_files
|
16
|
+
end
|
17
|
+
has_many :products, through: :variants
|
18
|
+
has_many :shipments, through: :stock_locations
|
19
|
+
has_many :stock_locations
|
20
|
+
has_many :supplier_variants
|
21
|
+
has_many :users, class_name: Spree.user_class.to_s
|
22
|
+
has_many :variants, through: :supplier_variants
|
23
|
+
|
24
|
+
#==========================================
|
25
|
+
# Validations
|
26
|
+
|
27
|
+
validates :commission_flat_rate, presence: true
|
28
|
+
validates :commission_percentage, presence: true
|
29
|
+
validates :email, presence: true, email: true, uniqueness: true
|
30
|
+
validates :name, presence: true, uniqueness: true
|
31
|
+
validates :url, format: { with: URI::regexp(%w(http https)), allow_blank: true }
|
32
|
+
|
33
|
+
#==========================================
|
34
|
+
# Callbacks
|
35
|
+
|
36
|
+
after_create :assign_user
|
37
|
+
after_create :create_stock_location
|
38
|
+
after_create :send_welcome, if: -> { SpreeDropShip::Config[:send_supplier_email] }
|
39
|
+
before_create :set_commission
|
40
|
+
before_validation :check_url
|
41
|
+
|
42
|
+
#==========================================
|
43
|
+
# Instance Methods
|
44
|
+
scope :active, -> { where(active: true) }
|
45
|
+
|
46
|
+
def deleted?
|
47
|
+
deleted_at.present?
|
48
|
+
end
|
49
|
+
|
50
|
+
def user_ids_string
|
51
|
+
user_ids.join(',')
|
52
|
+
end
|
53
|
+
|
54
|
+
def user_ids_string=(s)
|
55
|
+
self.user_ids = s.to_s.split(',').map(&:strip)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Retreive the stock locations that has available
|
59
|
+
# stock items of the given variant
|
60
|
+
def stock_locations_with_available_stock_items(variant)
|
61
|
+
stock_locations.select { |sl| sl.available?(variant) }
|
62
|
+
end
|
63
|
+
|
64
|
+
#==========================================
|
65
|
+
# Protected Methods
|
66
|
+
|
67
|
+
protected
|
68
|
+
|
69
|
+
def assign_user
|
70
|
+
if self.users.empty?
|
71
|
+
if user = Spree.user_class.find_by_email(self.email)
|
72
|
+
self.users << user
|
73
|
+
self.save
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def check_url
|
79
|
+
unless self.url.blank? or self.url =~ URI::regexp(%w(http https))
|
80
|
+
self.url = "http://#{self.url}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def create_stock_location
|
85
|
+
if self.stock_locations.empty?
|
86
|
+
location = self.stock_locations.build(
|
87
|
+
active: true,
|
88
|
+
country_id: self.address.try(:country_id),
|
89
|
+
name: self.name,
|
90
|
+
state_id: self.address.try(:state_id)
|
91
|
+
)
|
92
|
+
# It's important location is always created. Some apps add validations that shouldn't break this.
|
93
|
+
location.save validate: false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def send_welcome
|
98
|
+
begin
|
99
|
+
Spree::SupplierMailer.welcome(self.id).deliver_later!
|
100
|
+
# Specs raise error for not being able to set default_url_options[:host]
|
101
|
+
rescue => ex #Errno::ECONNREFUSED => ex
|
102
|
+
Rails.logger.error ex.message
|
103
|
+
Rails.logger.error ex.backtrace.join("\n")
|
104
|
+
return true # always return true so that failed email doesn't crash app.
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def set_commission
|
109
|
+
unless changes.has_key?(:commission_flat_rate)
|
110
|
+
self.commission_flat_rate = SpreeDropShip::Config[:default_commission_flat_rate]
|
111
|
+
end
|
112
|
+
unless changes.has_key?(:commission_percentage)
|
113
|
+
self.commission_percentage = SpreeDropShip::Config[:default_commission_percentage]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
@@ -0,0 +1,28 @@
|
|
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
|
9
|
+
# TODO: Want this to be inline like:
|
10
|
+
# can [:admin, :read, :stock], Spree::Product, suppliers: { id: user.supplier_id }
|
11
|
+
# can [:admin, :read, :stock], Spree::Product, supplier_ids: user.supplier_id
|
12
|
+
can [:admin, :read, :stock], Spree::Product do |product|
|
13
|
+
product.supplier_ids.include?(user.supplier_id)
|
14
|
+
end
|
15
|
+
can [:admin, :index, :manage, :create], Spree::Product
|
16
|
+
can [:admin, :manage, :read, :ready, :ship], Spree::Shipment, order: { state: 'complete' }, stock_location: { supplier_id: user.supplier_id }
|
17
|
+
can [:admin, :create, :update], :stock_items
|
18
|
+
can [:admin, :manage], Spree::StockItem, stock_location_id: user.supplier.stock_locations.pluck(:id)
|
19
|
+
can [:admin, :manage], Spree::StockLocation, supplier_id: user.supplier_id
|
20
|
+
can :create, Spree::StockLocation
|
21
|
+
can [:admin, :manage], Spree::StockMovement, stock_item: { stock_location_id: user.supplier.stock_locations.pluck(:id) }
|
22
|
+
can :create, Spree::StockMovement
|
23
|
+
can [:admin, :update], Spree::Supplier, id: user.supplier_id
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Spree
|
2
|
+
Variant.class_eval do
|
3
|
+
|
4
|
+
has_many :suppliers, through: :supplier_variants
|
5
|
+
has_many :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
|
data/app/models/spree.rb
ADDED
@@ -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), stock_admin_product_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 'SM', stock_admin_product_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_bottom "[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,11 @@
|
|
1
|
+
<!-- replace_contents '[data-hook="admin_stock_movements_form_fields"]' -->
|
2
|
+
|
3
|
+
<%# Fix markup form bug %>
|
4
|
+
<%= f.field_container :quantity, class: ['form-group'] do %>
|
5
|
+
<%= f.label :quantity, Spree.t(:quantity) %>
|
6
|
+
<%= f.text_field :quantity , class: 'form-control'%>
|
7
|
+
<% end %>
|
8
|
+
<%= f.field_container :stock_item_id, class: ['form-group'] do %>
|
9
|
+
<%= f.label :stock_item_id, Spree.t(:stock_item_id) %>
|
10
|
+
<%= f.text_field 'stock_item_id', :class => 'select2', :'data-stock-location-id' => params[:stock_location_id] %>
|
11
|
+
<% end %>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<!-- insert_top "div#main-sidebar" -->
|
2
|
+
|
3
|
+
<%# Add tab "profile to admin tabs" %>
|
4
|
+
<% if try_spree_current_user && try_spree_current_user.supplier? %>
|
5
|
+
<ul class="nav nav-sidebar">
|
6
|
+
<%= tab :profile, url: spree.edit_admin_supplier_url(spree_current_user.supplier_id), match_path: '/suppliers', icon: 'user' %>
|
7
|
+
</ul>
|
8
|
+
<% end %>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<!-- insert_bottom "div#main-sidebar" -->
|
2
|
+
|
3
|
+
<%# Add sidebar's items for supplier %>
|
4
|
+
<% if can? :index, Spree::Supplier %>
|
5
|
+
<ul class="nav nav-sidebar">
|
6
|
+
<%= tab :suppliers, label: Spree.t(:suppliers), match_path: '/suppliers', icon: 'home' %>
|
7
|
+
</ul>
|
8
|
+
<% end %>
|
9
|
+
<% if can? :index, Spree::Shipment %>
|
10
|
+
<ul class="nav nav-sidebar">
|
11
|
+
<%= tab :shipments, label: Spree.t(:shipments), match_path: '/shipments', icon: 'plane' %>
|
12
|
+
</ul>
|
13
|
+
<% end %>
|
14
|
+
<% if try_spree_current_user.try(:supplier?) and can? :index, Spree::StockLocation %>
|
15
|
+
<ul class="nav nav-sidebar">
|
16
|
+
<%= tab :stock_locations, label: Spree.t(:stock_locations), match_path: '/stock_locations', icon: 'globe' %>
|
17
|
+
</ul>
|
18
|
+
<% end %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<% content_for :page_title do %>
|
2
|
+
<%= Spree.t("drop_ship_settings") %>
|
3
|
+
<% end %>
|
4
|
+
|
5
|
+
<%= form_tag(spree.admin_drop_ship_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 = SpreeDropShip::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, SpreeDropShip::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_drop_ship_settings_url, :icon => 'cancel' %>
|
19
|
+
</div>
|
20
|
+
</fieldset>
|
21
|
+
<% end %>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<%# Override header for supplier %>
|
2
|
+
<% admin = try_spree_current_user.try(:supplier?) || try_spree_current_user.try(:has_spree_role?, "admin") %>
|
3
|
+
|
4
|
+
<header class="header <%= admin ? "logged-in" : "logged-out" %>">
|
5
|
+
|
6
|
+
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
7
|
+
<div class="container-fluid">
|
8
|
+
<div class="navbar-header">
|
9
|
+
<%= link_to image_tag(Spree::Config[:admin_interface_logo], id: 'logo', height: '100%'), spree.admin_path, class: "logo navbar-brand" %>
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<% if admin %>
|
13
|
+
<a href="#" class="navbar-btn sidebar-toggle" data-toggle="offcanvas" role="button">
|
14
|
+
<span class="sr-only">Toggle navigation</span>
|
15
|
+
<span class="icon-bar"></span>
|
16
|
+
<span class="icon-bar"></span>
|
17
|
+
<span class="icon-bar"></span>
|
18
|
+
</a>
|
19
|
+
<div class="navbar-right" data-hook="admin_login_navigation_bar"></div>
|
20
|
+
<% end %>
|
21
|
+
</div>
|
22
|
+
</nav>
|
23
|
+
|
24
|
+
</header>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<% content_for :page_actions do %>
|
2
|
+
<%= button_link_to Spree.t(:back_to_shipments_list), spree.admin_shipments_path, icon: 'arrow-left' %>
|
3
|
+
<% end %>
|
4
|
+
|
5
|
+
<% if spree_current_user.admin? && @shipment.supplier.present? %>
|
6
|
+
<div data-hook="admin_shipment_supplier" class="row">
|
7
|
+
<fieldset class="col-md-12 no-border-bottom">
|
8
|
+
<legend align="center"><%= Spree.t(:supplier_information) %></legend>
|
9
|
+
<div>
|
10
|
+
<b><%= Spree::Supplier.human_attribute_name(:name) %>:</b> <%= @shipment.supplier.name %><br/>
|
11
|
+
<b><%= Spree::Supplier.human_attribute_name(:email) %>:</b> <%= @shipment.supplier.email %><br/>
|
12
|
+
<b><%= Spree::Supplier.human_attribute_name(:url) %>:</b> <%= link_to @shipment.supplier.url, @shipment.supplier.url if @shipment.supplier.url.present? %><br/>
|
13
|
+
</div>
|
14
|
+
<div>
|
15
|
+
<b><%= Spree.t('contact_information') %>:</b>
|
16
|
+
</div>
|
17
|
+
<%= render partial: 'spree/shared/address', locals: { address: @shipment.supplier.address } %>
|
18
|
+
</fieldset>
|
19
|
+
</div>
|
20
|
+
<% end %>
|
21
|
+
|
22
|
+
<div data-hook="admin_shipment_form_fields">
|
23
|
+
<%= render partial: "spree/admin/orders/shipment", locals: { order: @shipment.order, shipment: @shipment } %>
|
24
|
+
</div>
|
@@ -0,0 +1,95 @@
|
|
1
|
+
<% content_for :page_title do %>
|
2
|
+
<%= Spree.t(:listing_shipments) %>
|
3
|
+
<% end %>
|
4
|
+
|
5
|
+
<% content_for :table_filter_title do %>
|
6
|
+
<%= Spree.t(:search) %>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<%# Update search form with new markup %>
|
10
|
+
<% content_for :table_filter do %>
|
11
|
+
<div data-hook="admin_shipments_index_search">
|
12
|
+
<%= search_form_for [:admin, @search] do |f| %>
|
13
|
+
<div class="row">
|
14
|
+
<div class="date-range-filter col-md-6">
|
15
|
+
<div class="form-group">
|
16
|
+
<%= label_tag :q_created_at_gt, Spree.t(:date_range) %>
|
17
|
+
<div class="row">
|
18
|
+
<div class="col-md-6">
|
19
|
+
<%= f.text_field :created_at_gt, :class => 'datepicker datepicker-from form-control', :value => params[:q][:created_at_gt], :placeholder => Spree.t(:start) %>
|
20
|
+
</div>
|
21
|
+
<div class="col-md-6">
|
22
|
+
<%= f.text_field :created_at_lt, :class => 'datepicker datepicker-to form-control', :value => params[:q][:created_at_lt], :placeholder => Spree.t(:stop) %>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
<div class="row">
|
29
|
+
<div class="col-md-4">
|
30
|
+
<div class="form-group">
|
31
|
+
<%= label_tag nil, Spree.t(:shipment_number) %>
|
32
|
+
<%= f.text_field :number_cont , class: 'form-control js-quick-search-target'%>
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
<div class="col-md-4">
|
37
|
+
<div class="form-group">
|
38
|
+
<%= label_tag nil, Spree.t(:status) %><br/>
|
39
|
+
<%= f.select :state_eq, Spree::Shipment.state_machines[:state].states.collect {|s| [Spree.t("shipment_state.#{s.name}"), s.value]}, {:include_blank => true}, :class => 'select2' %>
|
40
|
+
</div>
|
41
|
+
</div>
|
42
|
+
</div>
|
43
|
+
|
44
|
+
<div data-hook="admin_shipments_index_search_buttons" class="form-actions">
|
45
|
+
<%= button Spree.t(:filter_results), 'search' %>
|
46
|
+
</div>
|
47
|
+
<% end %>
|
48
|
+
</div>
|
49
|
+
<% end %>
|
50
|
+
|
51
|
+
<%# This is a new paginate! %>
|
52
|
+
<%= render :partial => 'spree/admin/shared/index_table_options', :locals => { :collection => @shipments } %>
|
53
|
+
|
54
|
+
<% unless @shipments.empty? %>
|
55
|
+
<table class="table" id="listing_shipments" data-hook>
|
56
|
+
<thead>
|
57
|
+
<tr data-hook="admin_orders_index_headers">
|
58
|
+
<th><%= sort_link @search, :created_at, Spree::Shipment.human_attribute_name(:created_at) %></th>
|
59
|
+
<th><%= sort_link @search, :number, Spree::Shipment.human_attribute_name(:number) %></th>
|
60
|
+
<th><%= sort_link @search, :state, Spree::Shipment.human_attribute_name(:state) %></th>
|
61
|
+
<th><%= sort_link @search, :item_cost, Spree::Shipment.human_attribute_name(:item_cost) %></th>
|
62
|
+
<th><%= sort_link @search, :shipping_total, Spree::Shipment.human_attribute_name(:cost) %></th>
|
63
|
+
<th><%= sort_link @search, :tax_total, Spree::Shipment.human_attribute_name(:tax_total) %></th>
|
64
|
+
<th><%= sort_link @search, :total, Spree::Shipment.human_attribute_name(:final_price) %></th>
|
65
|
+
<th><%= sort_link @search, :supplier_commission, Spree::Shipment.human_attribute_name(:supplier_commission) %></th>
|
66
|
+
<th data-hook="admin_shipments_index_header_actions" class="actions"></th>
|
67
|
+
</tr>
|
68
|
+
</thead>
|
69
|
+
<tbody>
|
70
|
+
<% @shipments.each do |shipment| %>
|
71
|
+
<tr data-hook="admin_shipments_index_rows" class="state-<%= shipment.state.downcase %> <%= cycle('odd', 'even') %>">
|
72
|
+
<td><%= l shipment.created_at.to_date %></td>
|
73
|
+
<td><%= link_to shipment.number, spree.edit_admin_shipment_path(shipment) %></td>
|
74
|
+
<td><span class="state <%= shipment.state.downcase %>"><%= Spree.t("shipment_state.#{shipment.state.downcase}") %></span></td>
|
75
|
+
<td> <%= shipment.display_item_cost.to_html %></td>
|
76
|
+
<td ><%= shipment.display_cost.to_html %></td>
|
77
|
+
<td><%= Spree::Money.new(shipment.tax_total, currency: shipment.currency).to_html %></td>
|
78
|
+
<td><%= Spree::Money.new(shipment.final_price_with_items, currency: shipment.currency).to_html %></td>
|
79
|
+
<td><%= Spree::Money.new(shipment.supplier_commission, currency: shipment.currency).to_html %></td>
|
80
|
+
<td data-hook="admin_shipments_index_row_actions">
|
81
|
+
<%= link_to_edit_url spree.edit_admin_shipment_path(shipment), :title => "admin_edit_#{dom_id(shipment)}", :no_text => true %>
|
82
|
+
</td>
|
83
|
+
</tr>
|
84
|
+
<% end %>
|
85
|
+
</tbody>
|
86
|
+
</table>
|
87
|
+
<% else %>
|
88
|
+
<%# New alert 'Not Found' with i18n %>
|
89
|
+
<div class="alert alert-info no-objects-found">
|
90
|
+
<%= Spree.t(:no_resource_found, resource: Spree::Shipment.model_name.human(count: :many)) %>,
|
91
|
+
</div>
|
92
|
+
<% end %>
|
93
|
+
|
94
|
+
<%# This is a new paginate! %>
|
95
|
+
<%= render :partial => 'spree/admin/shared/index_table_options', :locals => { :collection => @shipments } %>
|
@@ -0,0 +1,69 @@
|
|
1
|
+
<div data-hook="supplier_address_wrapper" class="col-md-6">
|
2
|
+
<fieldset class="no-border-bottom">
|
3
|
+
<legend align="center"><%= Spree.t('contact_address') %></legend>
|
4
|
+
<%= form.fields_for :address do |contact_form| %>
|
5
|
+
<%= render :partial => 'spree/admin/shared/address_form', :locals => { :f => contact_form, :name => Spree.t(:contact_address), :type => "shipping" } %>
|
6
|
+
<% end %>
|
7
|
+
</fieldset>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<%# added bootstrap classes for 'field_container' and '' %>
|
11
|
+
<div data-hook="supplier_details_wrapper" class="col-md-6">
|
12
|
+
<fieldset class="no-border-bottom">
|
13
|
+
<legend align="center" ><%= Spree.t('supplier_details') %></legend>
|
14
|
+
<%= form.field_container :name, class: ['form-group'] do %>
|
15
|
+
<%= form.label :name, Spree::Supplier.human_attribute_name(:name) %>:<br />
|
16
|
+
<%= form.text_field :name, :class => 'form-control' %>
|
17
|
+
<% end %>
|
18
|
+
<%= form.field_container :email, class: ['form-group'] do %>
|
19
|
+
<%= form.label :email, Spree::Supplier.human_attribute_name(:email) %>:<br />
|
20
|
+
<%= form.email_field :email, :class => 'form-control' %>
|
21
|
+
<%# email validation %>
|
22
|
+
<%= error_message_on :user, :email %>
|
23
|
+
<% end %>
|
24
|
+
<%= form.field_container :url, class: ['form-group'] do %>
|
25
|
+
<%= form.label :url, Spree::Supplier.human_attribute_name(:url) %>:<br />
|
26
|
+
<%= form.text_field :url, :class => 'form-control' %>
|
27
|
+
<% end %>
|
28
|
+
<%= form.field_container :tax_id, class: ['form-group'] do %>
|
29
|
+
<%= form.label :tax_id, Spree::Supplier.human_attribute_name(:tax_id) %>:<br />
|
30
|
+
<%= form.text_field :tax_id, :class => 'form-control' %>
|
31
|
+
<% end %>
|
32
|
+
<% if spree_current_user.admin? %>
|
33
|
+
<%= form.field_container :commission_flat_rate, class: ['form-group'] do %>
|
34
|
+
<%= form.label :commission_flat_rate, Spree::Supplier.human_attribute_name(:commission_flat_rate) %>:<br />
|
35
|
+
<%= form.text_field :commission_flat_rate, :class => 'form-control' %>
|
36
|
+
<% end %>
|
37
|
+
<%= form.field_container :commission_percentage , class: ['form-group'] do %>
|
38
|
+
<%= form.label :commission_percentage, Spree::Supplier.human_attribute_name(:commission_percentage) %>:<br />
|
39
|
+
<%= form.text_field :commission_percentage, :class => 'form-control' %>
|
40
|
+
<% end %>
|
41
|
+
<%= form.field_container :users, class: ['form-group'] do %>
|
42
|
+
<%= form.label :users %><br/>
|
43
|
+
<%= hidden_field_tag 'supplier[user_ids_string]', form.object.user_ids.join(','), class: 'user_picker' %>
|
44
|
+
<% end %>
|
45
|
+
<%= form.field_container :active, class: ['form-group'] do %>
|
46
|
+
<div class="checkbox">
|
47
|
+
<%= label_tag :active do %>
|
48
|
+
<%= form.check_box :active %>
|
49
|
+
<%= Spree::Supplier.human_attribute_name(:active) %>
|
50
|
+
<% end %>
|
51
|
+
</div>
|
52
|
+
<% end %>
|
53
|
+
<% end %>
|
54
|
+
<%# This moved to _edit(new)_resource_links.html.erb %>
|
55
|
+
<!--<div class='center'>-->
|
56
|
+
<%# if form.object.new_record? %>
|
57
|
+
<%#= button Spree.t('create') %>
|
58
|
+
<%# else %>
|
59
|
+
<%#= button Spree.t('update') %>
|
60
|
+
<%# end %>
|
61
|
+
<%#= Spree.t('or') %>
|
62
|
+
<%# if can? :index, Spree::Supplier %>
|
63
|
+
<%#= link_to Spree.t('cancel'), collection_url %>
|
64
|
+
<%# else %>
|
65
|
+
<%#= link_to Spree.t('cancel'), spree.account_path %>
|
66
|
+
<%# end %>
|
67
|
+
<!--</div>-->
|
68
|
+
</fieldset>
|
69
|
+
</div>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<% if can? :index, Spree::Supplier %>
|
2
|
+
<% content_for :page_actions do %>
|
3
|
+
<%= button_link_to Spree.t('back_to_suppliers'), spree.admin_suppliers_path, icon: 'arrow-left' %>
|
4
|
+
<% end %>
|
5
|
+
<% end %>
|
6
|
+
|
7
|
+
<% content_for :page_title do %>
|
8
|
+
<%== Spree.t(:editing_supplier) + " “#{@object.name}”".html_safe %>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<%= render 'spree/shared/error_messages', target: @object %>
|
12
|
+
|
13
|
+
<%= form_for [:admin, @object] do |f| %>
|
14
|
+
<%= render "form", form: f %>
|
15
|
+
<div data-hook="supplier_right_column_wrapper" class="col-md-4"></div>
|
16
|
+
<%# render 'update' and 'cancel' buttons %>
|
17
|
+
<div class="col-md-8">
|
18
|
+
<%= render :partial => 'spree/admin/shared/edit_resource_links' %>
|
19
|
+
</div>
|
20
|
+
<% end %>
|
21
|
+
|
22
|
+
|
@@ -0,0 +1,71 @@
|
|
1
|
+
<%# Updated icon %>
|
2
|
+
<% content_for :page_actions do %>
|
3
|
+
<%= button_link_to Spree.t('new_supplier'), new_object_url, icon: 'add', class: 'btn-success' %>
|
4
|
+
<% end %>
|
5
|
+
|
6
|
+
<% content_for :page_title do %>
|
7
|
+
<%= Spree.t(:listing_suppliers) %>
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<% content_for :table_filter_title do %>
|
11
|
+
<%= Spree.t(:search) %>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<% content_for :table_filter do %>
|
15
|
+
<div data-hook='admin_suppliers_filter'>
|
16
|
+
<%= search_form_for [:admin, @search] do |f| %>
|
17
|
+
<div class="form-group">
|
18
|
+
<%= f.label :name_cont, Spree.t(:name) %>
|
19
|
+
<%= f.text_field :name_cont, :size => 15, class: "form-control" %>
|
20
|
+
</div>
|
21
|
+
<div class="clear"></div>
|
22
|
+
<div class="form-actions" data-hook="admin_suppliers_index_search_buttons">
|
23
|
+
<%= button Spree.t(:search), 'search' %>
|
24
|
+
</div>
|
25
|
+
<% end %>
|
26
|
+
</div>
|
27
|
+
<% end %>
|
28
|
+
|
29
|
+
<%# This is a new paginate! %>
|
30
|
+
<%= render :partial => 'spree/admin/shared/index_table_options', :locals => { :collection => @collection } %>
|
31
|
+
|
32
|
+
<% if @collection.any? %>
|
33
|
+
<table class="table" id="listing_suppliers">
|
34
|
+
<thead>
|
35
|
+
<tr data-hook='admin_suppliers_index_headers'>
|
36
|
+
<th><%= sort_link @search, :name, Spree::Supplier.human_attribute_name(:name) %></th>
|
37
|
+
<th><%= sort_link @search, :email, Spree::Supplier.human_attribute_name(:email) %></th>
|
38
|
+
<th><%= Spree.t(:users) %></th>
|
39
|
+
<th><%= sort_link @search, :active, Spree::Supplier.human_attribute_name(:active) %></th>
|
40
|
+
<th data-hook="admin_suppliers_index_header_actions" class="actions"></th>
|
41
|
+
</tr>
|
42
|
+
</thead>
|
43
|
+
<tbody>
|
44
|
+
<%# Updated classes! %>
|
45
|
+
<%- @collection.each do |supplier| %>
|
46
|
+
<tr <%= "style='color: red;'" if supplier.deleted? %> id="<%= spree_dom_id supplier %>" data-hook="admin_suppliers_index_rows" class="<%= cycle('odd', 'even') %>">
|
47
|
+
<!--todo: Fix this link!-->
|
48
|
+
<td><%= link_to supplier.name, edit_object_url(supplier) %></td>
|
49
|
+
<td><%= mail_to supplier.email %></td>
|
50
|
+
<td><%= supplier.users.pluck(:email).join(', ') %></td>
|
51
|
+
<td><%= supplier.active %></td>
|
52
|
+
<td class='actions actions-3' data-hook='admin_suppliers_index_row_actions'>
|
53
|
+
<% unless supplier.deleted? %>
|
54
|
+
<%= link_to_edit supplier, :no_text => true, :class => 'edit' %>
|
55
|
+
<%= link_to_delete supplier, :no_text => true %>
|
56
|
+
<% end %>
|
57
|
+
</td>
|
58
|
+
</tr>
|
59
|
+
<% end %>
|
60
|
+
</tbody>
|
61
|
+
</table>
|
62
|
+
<% else %>
|
63
|
+
<%# New alert with link to add new supplier %>
|
64
|
+
<div class="alert alert-info no-objects-found">
|
65
|
+
<%= Spree.t(:no_resource_found, resource: Spree::Supplier.model_name.human(count: :many)) %>,
|
66
|
+
<%= link_to Spree.t(:add_one), spree.new_admin_supplier_path %>!
|
67
|
+
</div>
|
68
|
+
<% end %>
|
69
|
+
|
70
|
+
<%# This is a new paginate! %>
|
71
|
+
<%= render :partial => 'spree/admin/shared/index_table_options', :locals => { :collection => @collection } %>
|