spree-point-of-sale 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +16 -0
- data/Gemfile +20 -0
- data/LICENSE +23 -0
- data/README.md +71 -0
- data/Rakefile +29 -0
- data/Versionfile +11 -0
- data/app/assets/images/admin/pos/customer.png +0 -0
- data/app/assets/images/admin/pos/del_16.png +0 -0
- data/app/assets/images/admin/pos/plus_16.png +0 -0
- data/app/assets/images/admin/pos/select.jpg +0 -0
- data/app/assets/javascripts/admin/spree_pos.js +20 -0
- data/app/assets/stylesheets/admin/html-label.css +20 -0
- data/app/assets/stylesheets/admin/spree_pos.css +25 -0
- data/app/controllers/spree/admin/barcode_controller.rb +49 -0
- data/app/controllers/spree/admin/checkout_controller_decorator.rb +7 -0
- data/app/controllers/spree/admin/pos_controller.rb +205 -0
- data/app/controllers/spree/admin/stock_locations_controller_decorator.rb +13 -0
- data/app/helpers/admin/barcode_helper.rb +31 -0
- data/app/models/spree/order_decorator.rb +38 -0
- data/app/models/spree/payment_decorator.rb +10 -0
- data/app/models/spree/payment_method/point_of_sale.rb +30 -0
- data/app/models/spree/shipment_decorator.rb +29 -0
- data/app/models/spree/stock/coordinator_decorator.rb +10 -0
- data/app/models/spree/stock_location_decorator.rb +18 -0
- data/app/models/spree/user_decorator.rb +10 -0
- data/app/models/spree/variant_decorator.rb +3 -0
- data/app/overrides/add_barcode_link_for_products_and_variants.rb +21 -0
- data/app/overrides/add_is_pos_filter_to_admin_orders.rb +11 -0
- data/app/overrides/add_pos_button.rb +5 -0
- data/app/overrides/add_store_to_spree_stock_locations.rb +11 -0
- data/app/overrides/admin_adds_pos_config.rb +7 -0
- data/app/overrides/codes.rb +10 -0
- data/app/overrides/pos_tab.rb +6 -0
- data/app/views/spree/admin/barcode/basic.html.erb +28 -0
- data/app/views/spree/admin/invoice/_line_items_invoice.html.erb +34 -0
- data/app/views/spree/admin/invoice/_receipt_header.html.erb +13 -0
- data/app/views/spree/admin/invoice/_totals_receipt.html.erb +25 -0
- data/app/views/spree/admin/invoice/receipt.html.erb +26 -0
- data/app/views/spree/admin/orders/_admin_pos_config.html.erb +5 -0
- data/app/views/spree/admin/orders/_pos_button.html.erb +1 -0
- data/app/views/spree/admin/pos/find.html.erb +81 -0
- data/app/views/spree/admin/pos/show.html.erb +137 -0
- data/app/views/spree/admin/pos/update_stock_location.js.erb +5 -0
- data/app/views/spree/admin/products/_barcode_product_link.html.erb +3 -0
- data/app/views/spree/admin/products/_barcode_variant_link.html.erb +3 -0
- data/config/application.rb +23 -0
- data/config/boot.rb +5 -0
- data/config/initializers/constants.rb +4 -0
- data/config/locales/codes-fi.yml +3 -0
- data/config/locales/en.yml +16 -0
- data/config/locales/fi.yml +8 -0
- data/config/routes.rb +21 -0
- data/db/migrate/20130723140316_add_delivered_at_and_canceled_at_to_spree_shipments.rb +6 -0
- data/db/migrate/20130730102503_add_store_and_address_id_in_spree_stock_locations.rb +8 -0
- data/db/migrate/20131014053417_add_is_pos_to_spree_orders.rb +6 -0
- data/db/migrate/20131025110309_add_card_name_to_spree_payments.rb +5 -0
- data/lib/generators/spree_pos/install/install_generator.rb +27 -0
- data/lib/spree_pos.rb +2 -0
- data/lib/spree_pos/configuration.rb +7 -0
- data/lib/spree_pos/engine.rb +29 -0
- data/spec/constants_spec.rb +8 -0
- data/spec/controllers/spree/admin/barcode_controller_spec.rb +86 -0
- data/spec/controllers/spree/admin/pos_controller_spec.rb +849 -0
- data/spec/models/spree/order_decorator_spec.rb +178 -0
- data/spec/models/spree/payment_decorator_spec.rb +115 -0
- data/spec/models/spree/payment_method/point_of_sale_spec.rb +25 -0
- data/spec/models/spree/shipment_decorator_spec.rb +172 -0
- data/spec/models/spree/stock/coordinator_spec.rb +31 -0
- data/spec/models/spree/stock_location_decorator_spec.rb +43 -0
- data/spec/models/spree/user_decorator_spec.rb +24 -0
- data/spec/models/spree/varaint_decorator_spec.rb +31 -0
- data/spec/spec_helper.rb +67 -0
- data/spree-point-of-sale.gemspec +32 -0
- metadata +183 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
gem 'rails', '3.2.16'
|
3
|
+
gem 'mysql2'
|
4
|
+
|
5
|
+
|
6
|
+
gem 'spree', :git => 'git://github.com/spree/spree.git', :tag => 'v2.0.3'
|
7
|
+
gem 'spree_html_invoice' , :git => 'git://github.com/dancinglightning/spree-html-invoice.git'
|
8
|
+
|
9
|
+
# Provides basic authentication functionality for testing parts of your engine
|
10
|
+
gem 'spree_auth_devise', github: 'spree/spree_auth_devise', :branch => '2-0-stable'
|
11
|
+
|
12
|
+
gemspec
|
13
|
+
|
14
|
+
group :test do
|
15
|
+
gem 'rspec-rails', '~> 2.10'
|
16
|
+
gem 'shoulda-matchers', '2.2.0'
|
17
|
+
gem 'simplecov', :require => false
|
18
|
+
gem 'database_cleaner'
|
19
|
+
gem 'rspec-html-matchers'
|
20
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Redistribution and use in source and binary forms, with or without modification,
|
2
|
+
are permitted provided that the following conditions are met:
|
3
|
+
|
4
|
+
* Redistributions of source code must retain the above copyright notice,
|
5
|
+
this list of conditions and the following disclaimer.
|
6
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
7
|
+
this list of conditions and the following disclaimer in the documentation
|
8
|
+
and/or other materials provided with the distribution.
|
9
|
+
* Neither the name of the Rails Dog LLC nor the names of its
|
10
|
+
contributors may be used to endorse or promote products derived from this
|
11
|
+
software without specific prior written permission.
|
12
|
+
|
13
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
14
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
15
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
16
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
17
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
18
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
19
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
20
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
21
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
22
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
23
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
SpreePos
|
2
|
+
===============
|
3
|
+
SpreePos hooks into the Admin Tab and is meant to be used to sell at a shop.
|
4
|
+
|
5
|
+
Allows you to search and add items available at the selected stock location.
|
6
|
+
Apply discount on items, associate the order to customer email and save the details of payment to finally finish the order with an invoice ready to print.
|
7
|
+
|
8
|
+
|
9
|
+
Dependencies
|
10
|
+
============
|
11
|
+
1)spree_html_invoice(optional)
|
12
|
+
|
13
|
+
By default POS relies on html-invoice to print a receipt. You can configure this away by setting :pos_printing to the url where you want to redirect after print.
|
14
|
+
|
15
|
+
2)barby
|
16
|
+
|
17
|
+
3)prawn
|
18
|
+
|
19
|
+
4)chunky_png
|
20
|
+
|
21
|
+
|
22
|
+
SET UP
|
23
|
+
=======
|
24
|
+
To your Gemfile add:
|
25
|
+
|
26
|
+
1) gem "spree_pos", :git => "git://github.com/vinsol/spree-point-of-sale.git"
|
27
|
+
|
28
|
+
2) If you DONT change the :pos_printing config as described above, you must also add
|
29
|
+
|
30
|
+
gem 'spree_html_invoice' , :git => 'git://github.com/dancinglightning/spree-html-invoice.git'
|
31
|
+
|
32
|
+
and run bundler.
|
33
|
+
|
34
|
+
Finally for migrations, css and javascript do
|
35
|
+
|
36
|
+
bundle exec rails g spree_pos:install
|
37
|
+
|
38
|
+
|
39
|
+
Configure
|
40
|
+
=========
|
41
|
+
You must configure:
|
42
|
+
|
43
|
+
1)ShippingMethod : Create a shipping method for pos and set it from the admin end via general settings.
|
44
|
+
Usually something like "pickup" with cost 0.
|
45
|
+
|
46
|
+
2)Payment Methods : They can be added under PointOfSale payment method from admin end itself.
|
47
|
+
|
48
|
+
3)Store : Make sure atleast one of your stock locations is marked as store.
|
49
|
+
|
50
|
+
|
51
|
+
Order
|
52
|
+
=========
|
53
|
+
The order is linked to the admin creating the order to keep a track of pos orders initiated by a particular admin.
|
54
|
+
|
55
|
+
Admin won't be allowed to update a paid order or even to create a new order when there is an order pending to be paid.
|
56
|
+
|
57
|
+
|
58
|
+
Stock Location and Inventory
|
59
|
+
=========
|
60
|
+
By default the first active stock location is picked up considering a single stock location. In case of multiple stock locations you can easily switch them.
|
61
|
+
|
62
|
+
Stock Locations available to be selected can be easily configured by re-defining user_stock_locations for pos_controller.
|
63
|
+
|
64
|
+
The inventory is updated along with addition and removal of items from the order.
|
65
|
+
|
66
|
+
|
67
|
+
Barcode printing and SKU
|
68
|
+
========
|
69
|
+
Barcode printing relies on sku to be provided for variants.
|
70
|
+
|
71
|
+
There are links provided to print barcodes for individual variants in the variants index for a product or barcodes for all variants can be printed from the product listings as well.
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/packagetask'
|
4
|
+
require 'rubygems/package_task'
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
require 'spree_core/testing_support/common_rake'
|
7
|
+
|
8
|
+
RSpec::Core::RakeTask.new
|
9
|
+
|
10
|
+
task :default => [:spec, :cucumber ]
|
11
|
+
|
12
|
+
spec = eval(File.read('spree_pos.gemspec'))
|
13
|
+
|
14
|
+
Gem::PackageTask.new(spec) do |p|
|
15
|
+
p.gem_spec = spec
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "Release to gemcutter"
|
19
|
+
task :release => :package do
|
20
|
+
require 'rake/gemcutter'
|
21
|
+
Rake::Gemcutter::Tasks.new(spec).define
|
22
|
+
Rake::Task['gem:push'].invoke
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Generates a dummy app for testing"
|
26
|
+
task :test_app do
|
27
|
+
ENV['LIB_NAME'] = 'spree_pos'
|
28
|
+
Rake::Task['common:test_app'].invoke
|
29
|
+
end
|
data/Versionfile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# This file is used to designate compatibilty with different versions of Spree
|
2
|
+
# Please see http://spreecommerce.com/documentation/extensions.html#versionfile for details
|
3
|
+
|
4
|
+
"0.70.x" => { :ref => "793ca3ad2822877babf60c5e3d3bd7b3f39be3db"}
|
5
|
+
# note: the 1.0 version was in never in production use as I had server crashes with 1.0 and upgraded immediately to 1.1
|
6
|
+
"1.0.x" => { :ref => "7075b1b483faa183679761f060072515e45dcaf7"}
|
7
|
+
|
8
|
+
"1.1.x" => { :branch => "master" }
|
9
|
+
|
10
|
+
|
11
|
+
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,20 @@
|
|
1
|
+
$( document ).ready(function() {
|
2
|
+
$('#sku').focus();
|
3
|
+
$( "#pos-tabs" ).tabs();
|
4
|
+
|
5
|
+
$( "#associate_user_toggle" ).click(function() {
|
6
|
+
$( "#associate_user" ).slideToggle( "slow", function() {
|
7
|
+
});
|
8
|
+
});
|
9
|
+
|
10
|
+
$('#update_payment input[type=radio]').click(function() {
|
11
|
+
$('#card_name_options').val('');
|
12
|
+
$('#card_name_options').hide();
|
13
|
+
});
|
14
|
+
|
15
|
+
$('#update_payment input[type=radio][data-name ~= card],#update_payment input[type=radio][data-name ~= Card]').click(function() {
|
16
|
+
$('#card_name_options').show();
|
17
|
+
});
|
18
|
+
$("#update_payment input[name='payment_method_id']:first").click();
|
19
|
+
$( "#associate_user" ).toggle();
|
20
|
+
});
|
@@ -0,0 +1,20 @@
|
|
1
|
+
@page {
|
2
|
+
margin-left:1mm;
|
3
|
+
margin-right:1mm;
|
4
|
+
margin-top:1mm;
|
5
|
+
margin-bottom:1mm;
|
6
|
+
}
|
7
|
+
|
8
|
+
body {
|
9
|
+
font-family:"Helvetica";
|
10
|
+
color:#000000;
|
11
|
+
width:200px;
|
12
|
+
}
|
13
|
+
|
14
|
+
.label-name {
|
15
|
+
font-size:13px;
|
16
|
+
}
|
17
|
+
|
18
|
+
.label-price {
|
19
|
+
font-size:13px;
|
20
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#pos-tabs { border:none; padding:20px 0px; float:left; width:100%; }
|
2
|
+
#pos-tabs .ui-tabs-nav { display:inline-block; width:100%; border:none; background:none; border-radius:3px; background:#5498DA;}
|
3
|
+
#pos-tabs .ui-tabs-nav .ui-state-default { float:left; width:50%; text-align:center; border:none; background:none;}
|
4
|
+
#pos-tabs .ui-tabs-nav .ui-state-default .ui-tabs-anchor { display:block; padding:10px; font-weight:normal; text-transform:uppercase; font-size:11px; color:#fff !important; position:relative;}
|
5
|
+
#pos-tabs .ui-tabs-nav .ui-state-active .ui-tabs-anchor { background:#9FC820; border-radius:3px;}
|
6
|
+
#pos-tabs .ui-tabs-nav .ui-state-active .ui-tabs-anchor:after {
|
7
|
+
content: '';
|
8
|
+
position: absolute;
|
9
|
+
border-left: 10px solid transparent;
|
10
|
+
border-right: 10px solid transparent;
|
11
|
+
border-top: 5px solid #9fc820;
|
12
|
+
bottom: 0px;
|
13
|
+
margin-bottom: -5px;
|
14
|
+
left: 50%;
|
15
|
+
margin-left: -10px;
|
16
|
+
z-index: 1;
|
17
|
+
}
|
18
|
+
#pos-tabs .commonfieldset .row { margin:0;}
|
19
|
+
#pos-tabs .commonfieldset p { padding-bottom:10px;}
|
20
|
+
#pos-tabs .ui-widget-content { border:none; }
|
21
|
+
table#pos-order-table th { border-top: 1px solid #cee1f4;}
|
22
|
+
table#pos-order-table { padding-top: 10px;}
|
23
|
+
table#pos-order-table td.discount input.submit{ margin: 2px 0 0 10px;}
|
24
|
+
fieldset.no-bottom-margin { margin-bottom: 0px;}
|
25
|
+
a#create_pos_order { float:right; padding:4px 9px;}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'barby'
|
2
|
+
require 'prawn'
|
3
|
+
require 'prawn/measurement_extensions'
|
4
|
+
require 'barby/barcode/code_128'
|
5
|
+
require 'barby/barcode/ean_13'
|
6
|
+
require 'barby/outputter/png_outputter'
|
7
|
+
|
8
|
+
class Spree::Admin::BarcodeController < Spree::Admin::BaseController
|
9
|
+
include Admin::BarcodeHelper
|
10
|
+
|
11
|
+
before_filter :load, :only => [:print]
|
12
|
+
before_filter :load_product_and_variants, :only => [:print_variants_barcodes]
|
13
|
+
layout :false
|
14
|
+
|
15
|
+
def print_variants_barcodes
|
16
|
+
if @variants.present?
|
17
|
+
pdf = @variants.inject(empty_pdf({:height => 120})) { |pdf, variant| append_barcode_to_pdf_for_variant(variant, pdf) }
|
18
|
+
send_data pdf.render , :type => "application/pdf" , :filename => "#{@product.name}.pdf"
|
19
|
+
else
|
20
|
+
#just to have @variant so that print can be called directly without a request skipping load method
|
21
|
+
@variant = @product.master
|
22
|
+
print
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# moved to pdf as html has uncontrollable margins
|
27
|
+
def print
|
28
|
+
pdf = append_barcode_to_pdf_for_variant(@variant)
|
29
|
+
send_data pdf.render , :type => "application/pdf" , :filename => "#{@variant.name}.pdf"
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# leave this in here maybe for later, not used anymore
|
35
|
+
# def code
|
36
|
+
# barcode = get_barcode
|
37
|
+
# return unless barcode
|
38
|
+
# send_data barcode.to_png(:xdim => 5) , :type => 'image/png', :disposition => 'inline'
|
39
|
+
# end
|
40
|
+
|
41
|
+
def load
|
42
|
+
@variant = Spree::Variant.where(:id => params[:id]).first
|
43
|
+
end
|
44
|
+
|
45
|
+
def load_product_and_variants
|
46
|
+
@product = Spree::Product.where(:id => params[:id]).first
|
47
|
+
@variants = @product.variants
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
class Spree::Admin::PosController < Spree::Admin::BaseController
|
2
|
+
before_filter :load_order, :ensure_pos_order, :ensure_unpaid_order, :except => [:new]
|
3
|
+
helper_method :user_stock_locations
|
4
|
+
before_filter :load_variant, :only => [:add, :remove]
|
5
|
+
before_filter :ensure_pos_shipping_method, :only => [:new]
|
6
|
+
before_filter :ensure_payment_method, :only => [:update_payment]
|
7
|
+
before_filter :ensure_existing_user, :only => [:associate_user]
|
8
|
+
before_filter :check_unpaid_pos_order, :only => :new
|
9
|
+
before_filter :check_discount_request, :only => :apply_discount
|
10
|
+
before_filter :load_line_item, :only => [:update_line_item_quantity, :apply_discount]
|
11
|
+
before_filter :clean_and_reload_order, :only => [:update_stock_location]
|
12
|
+
|
13
|
+
def new
|
14
|
+
init_pos
|
15
|
+
redirect_to admin_pos_show_order_path(:number => @order.number)
|
16
|
+
end
|
17
|
+
|
18
|
+
def find
|
19
|
+
init_search
|
20
|
+
|
21
|
+
stock_location = @order.shipment.stock_location
|
22
|
+
@search = Spree::Variant.includes([:product]).available_at_stock_location(stock_location.id).ransack(params[:q])
|
23
|
+
@variants = @search.result(:distinct => true).page(params[:page]).per(PRODUCTS_PER_SEARCH_PAGE)
|
24
|
+
end
|
25
|
+
|
26
|
+
def add
|
27
|
+
@item = add_variant(@variant) if @variant.present?
|
28
|
+
flash[:notice] = Spree.t('product_added') if @item.errors.blank?
|
29
|
+
flash[:error] = @item.errors.full_messages.to_sentence if @item.errors.present?
|
30
|
+
redirect_to admin_pos_show_order_path(:number => @order.number)
|
31
|
+
end
|
32
|
+
|
33
|
+
def remove
|
34
|
+
line_item = @order.contents.remove(@variant, 1, @order.shipment)
|
35
|
+
@order.assign_shipment_for_pos if @order.reload.shipments.blank?
|
36
|
+
flash.notice = line_item.quantity.zero? ? Spree.t('product_removed') : 'Quantity Updated'
|
37
|
+
redirect_to admin_pos_show_order_path(:number => @order.number)
|
38
|
+
end
|
39
|
+
|
40
|
+
def update_line_item_quantity
|
41
|
+
@item.quantity = params[:quantity]
|
42
|
+
@item.save
|
43
|
+
|
44
|
+
flash[:notice] = 'Quantity Updated' if @item.errors.blank?
|
45
|
+
flash[:error] = @item.errors.full_messages.to_sentence if @item.errors.present?
|
46
|
+
redirect_to admin_pos_show_order_path(:number => @order.number)
|
47
|
+
end
|
48
|
+
|
49
|
+
def apply_discount
|
50
|
+
@item.price = @item.variant.price * ( 1.0 - @discount/100.0 )
|
51
|
+
@item.save
|
52
|
+
redirect_to admin_pos_show_order_path(:number => @order.number)
|
53
|
+
end
|
54
|
+
|
55
|
+
def clean_order
|
56
|
+
@order.clean!
|
57
|
+
redirect_to admin_pos_show_order_path(:number => @order.number), :notice => "Removed all items"
|
58
|
+
end
|
59
|
+
|
60
|
+
def associate_user
|
61
|
+
@user = @order.associate_user_for_pos(params[:email].present? ? params[:email] : params[:new_email])
|
62
|
+
if @user.errors.present?
|
63
|
+
add_error "Could not add the user:#{@user.errors.full_messages.to_sentence}"
|
64
|
+
else
|
65
|
+
@order.save!
|
66
|
+
flash[:notice] = 'Successfully Associated User'
|
67
|
+
end
|
68
|
+
|
69
|
+
redirect_to admin_pos_show_order_path(:number => @order.number)
|
70
|
+
end
|
71
|
+
|
72
|
+
def update_payment
|
73
|
+
@payment_method_id = params[:payment_method_id]
|
74
|
+
@payment = @order.save_payment_for_pos(params[:payment_method_id], params[:card_name])
|
75
|
+
if @payment.errors.blank?
|
76
|
+
print
|
77
|
+
else
|
78
|
+
add_error @payment.errors.full_messages.to_sentence
|
79
|
+
redirect_to admin_pos_show_order_path(:number => @order.number)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def update_stock_location
|
84
|
+
@order.shipment.stock_location = user_stock_locations(spree_current_user).where(:id => params[:stock_location_id]).first
|
85
|
+
if @order.shipment.save
|
86
|
+
flash[:notice] = "Updated Successfully"
|
87
|
+
else
|
88
|
+
flash[:error] = @order.shipment.errors.full_messages.to_sentence
|
89
|
+
end
|
90
|
+
redirect_to admin_pos_show_order_path(:number => @order.number)
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def clean_and_reload_order
|
96
|
+
@order.clean!
|
97
|
+
load_order
|
98
|
+
end
|
99
|
+
|
100
|
+
def check_discount_request
|
101
|
+
@discount = params[:discount].try(:to_f)
|
102
|
+
redirect_to admin_pos_show_order_path(:number => @order.number), :flash => { :error => 'Please enter a valid discount' } unless VALID_DISCOUNT_REGEX.match(params[:discount]) || @discount >= 100
|
103
|
+
end
|
104
|
+
|
105
|
+
def ensure_pos_order
|
106
|
+
unless @order.is_pos?
|
107
|
+
flash[:error] = 'This is not a pos order'
|
108
|
+
render :show
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def ensure_unpaid_order
|
113
|
+
if @order.paid?
|
114
|
+
flash[:error] = 'This order is already completed. Please use a new one.'
|
115
|
+
render :show
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def load_line_item
|
120
|
+
@item = @order.line_items.where(:id => params[:line_item_id]).first
|
121
|
+
end
|
122
|
+
|
123
|
+
def check_unpaid_pos_order
|
124
|
+
if spree_current_user.unpaid_pos_orders.present?
|
125
|
+
add_error("You have an unpaid/empty order. Please either complete it or update items in the same order.")
|
126
|
+
redirect_to admin_pos_show_order_path(:number => spree_current_user.unpaid_pos_orders.first.number)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def ensure_existing_user
|
131
|
+
invalid_user_message = "No user with email #{params[:email]}" if params[:email].present? && Spree::User.where(:email => params[:email]).blank?
|
132
|
+
invalid_user_message = "User Already exists for the email #{params[:new_email]}" if params[:new_email].present? && Spree::User.where(:email => params[:new_email]).present?
|
133
|
+
redirect_to admin_pos_show_order_path(:number => @order.number), :flash => { :error => invalid_user_message } if invalid_user_message
|
134
|
+
end
|
135
|
+
|
136
|
+
def ensure_pos_shipping_method
|
137
|
+
redirect_to '/', :flash => { :error => 'No shipping method available for POS orders. Please assign one.'} and return unless Spree::ShippingMethod.where(:name => SpreePos::Config[:pos_shipping]).first
|
138
|
+
end
|
139
|
+
|
140
|
+
def load_order
|
141
|
+
@order = Spree::Order.by_number(params[:number]).includes([{ :line_items => [{ :variant => [:default_price, { :product => [:master] } ] }] } , { :adjustments => :adjustable }] ).first
|
142
|
+
raise "No order found for -#{params[:number]}-" unless @order
|
143
|
+
end
|
144
|
+
|
145
|
+
def load_variant
|
146
|
+
@variant = Spree::Variant.where(:id => params[:item]).first
|
147
|
+
unless @variant
|
148
|
+
flash[:error] = "No variant"
|
149
|
+
render :show
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def check_valid_order
|
154
|
+
if @order.paid? || !@order.is_pos?
|
155
|
+
flash[:error] = 'This order is already completed. Please use a new one.' if @order.paid?
|
156
|
+
flash[:error] = 'This is not a pos order' unless @order.is_pos?
|
157
|
+
render :show
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def ensure_payment_method
|
162
|
+
if Spree::PaymentMethod.where(:id => params[:payment_method_id]).blank?
|
163
|
+
flash[:error] = 'Please select a payment method'
|
164
|
+
redirect_to admin_pos_show_order_path(:number => @order.number)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def init_pos
|
169
|
+
@order = Spree::Order.new(:state => "complete", :is_pos => true, :completed_at => Time.current, :payment_state => 'balance_due')
|
170
|
+
@order.associate_user!(spree_current_user)
|
171
|
+
@order.save!
|
172
|
+
@order.assign_shipment_for_pos
|
173
|
+
@order.save!
|
174
|
+
session[:pos_order] = @order.number
|
175
|
+
end
|
176
|
+
|
177
|
+
def add_error error_message
|
178
|
+
flash[:error] = "" unless flash[:error]
|
179
|
+
flash[:error] << error_message
|
180
|
+
end
|
181
|
+
|
182
|
+
def add_variant var , quant = 1
|
183
|
+
line_item = @order.contents.add(var, quant, nil, @order.shipment)
|
184
|
+
var.product.save
|
185
|
+
line_item
|
186
|
+
end
|
187
|
+
|
188
|
+
def user_stock_locations(user)
|
189
|
+
# use this code when stock managers implemented
|
190
|
+
# @stock_location ||= (user.has_spree_role?('pos_admin') ? Spree::StockLocation.active.stores : user.stock_locations.active.store)
|
191
|
+
Spree::StockLocation.active.stores
|
192
|
+
end
|
193
|
+
|
194
|
+
def init_search
|
195
|
+
params[:q] ||= {}
|
196
|
+
params[:q].merge!(:meta_sort => "product_name asc", :deleted_at_null => "1", :product_deleted_at_null => "1", :published_at_not_null => "1")
|
197
|
+
params[:q][:product_name_cont].try(:strip!)
|
198
|
+
end
|
199
|
+
|
200
|
+
def print
|
201
|
+
@order.complete_via_pos
|
202
|
+
url = SpreePos::Config[:pos_printing].sub("number" , @order.number.to_s)
|
203
|
+
redirect_to url
|
204
|
+
end
|
205
|
+
end
|