spree-point-of-sale 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
- SpreePos
2
- ===============
1
+ Spree Pos [![Code Climate](https://codeclimate.com/github/vinsol/spree-point-of-sale.png)](https://codeclimate.com/github/vinsol/spree-point-of-sale)
2
+ =========
3
3
  SpreePos hooks into the Admin Tab and is meant to be used to sell at a shop.
4
4
 
5
5
  Allows you to search and add items available at the selected stock location.
@@ -26,13 +26,13 @@ To your Gemfile add:
26
26
  Add spree-point-of-sale to your Gemfile:
27
27
 
28
28
  ```ruby
29
- gem "spree-point-of-sale", require: 'spree_pos'
29
+ gem "spree-point-of-sale", require: 'spree_pos'
30
30
  ```
31
31
 
32
32
  If you DONT change the :pos_printing config as described above, you must also add
33
33
 
34
34
  ```ruby
35
- gem 'spree_html_invoice' , :git => 'git://github.com/dancinglightning/spree-html-invoice.git'
35
+ gem 'spree_html_invoice' , :git => 'git://github.com/dancinglightning/spree-html-invoice.git'
36
36
  ```
37
37
 
38
38
  ```ruby
@@ -2,7 +2,7 @@ class Spree::Admin::PosController < Spree::Admin::BaseController
2
2
  before_filter :load_order, :ensure_pos_order, :ensure_unpaid_order, :except => [:new]
3
3
  helper_method :user_stock_locations
4
4
  before_filter :load_variant, :only => [:add, :remove]
5
- before_filter :ensure_active_store, :ensure_pos_shipping_method, :only => [:new]
5
+ before_filter :ensure_active_store, :ensure_pos_shipping_method
6
6
  before_filter :ensure_payment_method, :only => [:update_payment]
7
7
  before_filter :ensure_existing_user, :only => [:associate_user]
8
8
  before_filter :check_unpaid_pos_order, :only => :new
@@ -49,6 +49,7 @@ class Spree::Admin::PosController < Spree::Admin::BaseController
49
49
  def apply_discount
50
50
  @item.price = @item.variant.price * ( 1.0 - @discount/100.0 )
51
51
  @item.save
52
+ flash[:error] = @item.errors.full_messages.to_sentence if @item.errors.present?
52
53
  redirect_to admin_pos_show_order_path(:number => @order.number)
53
54
  end
54
55
 
@@ -0,0 +1,9 @@
1
+ Spree::LineItem.class_eval do
2
+ validates_with Spree::Stock::PosAvailabilityValidator, :if => "order.is_pos?"
3
+
4
+ #remove the validation of Spree::Stock::Avilability and then re assign it to be for only non-pos orders
5
+ _validators[nil].reject! { |v| v.class == Spree::Stock::AvailabilityValidator }
6
+ _validate_callbacks.reject! { |c| c.raw_filter.class == Spree::Stock::AvailabilityValidator }
7
+
8
+ validates_with Spree::Stock::AvailabilityValidator, :unless => "order.is_pos?"
9
+ end
@@ -0,0 +1,16 @@
1
+ module Spree
2
+ module Stock
3
+ class PosAvailabilityValidator < ActiveModel::Validator
4
+ def validate(line_item)
5
+ variant = line_item.variant
6
+ stock_location = line_item.order.shipment.try(:stock_location)
7
+ quantity_required = line_item.quantity - line_item.quantity_was.to_i
8
+ if !stock_location || !stock_location.active? || !stock_location.store?
9
+ line_item.errors[:stock_location] << 'No Active Store Associated'
10
+ elsif !stock_location.can_supply?(quantity_required, variant)
11
+ line_item.errors[:quantity] << 'Adding More Than Available'
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -10,6 +10,11 @@ module Spree
10
10
 
11
11
  validates_associated :address
12
12
 
13
+ def can_supply?(quantity, variant)
14
+ stock_item = stock_items.where(:variant_id => variant.id).first
15
+ quantity <= stock_item.count_on_hand
16
+ end
17
+
13
18
  private
14
19
  def associate_address
15
20
  self.address = Spree::Address.where(:firstname => name, :lastname => '(Store)', :state_id => state_id, :country_id => country_id, :address1 => address1, :address2 => address2, :phone => phone, :zipcode => zipcode, :city => city).first_or_initialize if respond_to?(:state_id) && store?
@@ -3,7 +3,7 @@ require File.expand_path('../boot', __FILE__)
3
3
  require 'rails/all'
4
4
 
5
5
  Bundler.require(*Rails.groups)
6
- require "spree_pos"
6
+ require "spree-point-of-sale"
7
7
 
8
8
  module SpreePointOfSale
9
9
  class Application < Rails::Application
@@ -31,6 +31,8 @@ describe Spree::Admin::PosController do
31
31
 
32
32
  context 'before filters' do
33
33
  before do
34
+ controller.stub(:ensure_pos_shipping_method).and_return(true)
35
+ controller.stub(:ensure_active_store).and_return(true)
34
36
  @orders = [order]
35
37
  Spree::Order.stub(:by_number).with(order.number).and_return(@orders)
36
38
  @orders.stub(:includes).with([{ :line_items => [{ :variant => [:default_price, { :product => [:master] } ] }] } , { :adjustments => :adjustable }]).and_return(@orders)
@@ -107,6 +109,7 @@ describe Spree::Admin::PosController do
107
109
  end
108
110
 
109
111
  describe 'ensure_active_store' do
112
+ before { controller.unstub(:ensure_active_store) }
110
113
  def send_request(params = {})
111
114
  get :new, params.merge!(:use_route => 'spree')
112
115
  end
@@ -154,6 +157,7 @@ describe Spree::Admin::PosController do
154
157
 
155
158
  describe 'ensure_pos_shipping_method' do
156
159
  before do
160
+ controller.unstub(:ensure_pos_shipping_method)
157
161
  @shipping_method = mock_model(Spree::ShippingMethod, :name => 'pos-shipping')
158
162
  SpreePos::Config[:pos_shipping] = @shipping_method.name
159
163
  @stock_location = mock_model(Spree::StockLocation)
@@ -335,7 +339,7 @@ describe Spree::Admin::PosController do
335
339
  context 'actions' do
336
340
  before do
337
341
  controller.stub(:ensure_pos_shipping_method).and_return(true)
338
- controller.stub(:ensure_payment_method).and_return(true)
342
+ controller.stub(:ensure_active_store).and_return(true)
339
343
  Spree::StockLocation.stub_chain(:active,:stores,:first,:address).and_return(address)
340
344
  controller.instance_variable_set(:@order,order)
341
345
  controller.stub(:check_valid_order).and_return(true)
@@ -362,6 +366,7 @@ describe Spree::Admin::PosController do
362
366
  end
363
367
 
364
368
  context 'before filters' do
369
+ it { controller.should_receive(:ensure_active_store).and_return(true) }
365
370
  it { controller.should_receive(:ensure_pos_shipping_method).and_return(true) }
366
371
  it { controller.should_not_receive(:ensure_payment_method) }
367
372
  it { controller.should_not_receive(:check_valid_order) }
@@ -428,7 +433,8 @@ describe Spree::Admin::PosController do
428
433
  context 'update_line_item_quantity' do
429
434
  it { controller.should_receive(:ensure_pos_order).and_return(true) }
430
435
  it { controller.should_receive(:ensure_unpaid_order).and_return(true) }
431
- it { controller.should_not_receive(:ensure_pos_shipping_method) }
436
+ it { controller.should_receive(:ensure_active_store).and_return(true) }
437
+ it { controller.should_receive(:ensure_pos_shipping_method).and_return(true) }
432
438
  it { controller.should_not_receive(:ensure_payment_method) }
433
439
  it { order.should_receive(:line_items).and_return(@line_items) }
434
440
  it { line_item.should_receive(:quantity=).with('2').and_return(true) }
@@ -473,6 +479,12 @@ describe Spree::Admin::PosController do
473
479
  line_item.stub(:price=).with(18.0).and_return(true)
474
480
  end
475
481
 
482
+ it { controller.should_receive(:ensure_unpaid_order).and_return(true) }
483
+ it { controller.should_receive(:ensure_pos_order).and_return(true) }
484
+ it { controller.should_receive(:ensure_pos_shipping_method).and_return(true) }
485
+ it { controller.should_receive(:ensure_active_store).and_return(true) }
486
+ it { controller.should_not_receive(:ensure_payment_method) }
487
+
476
488
  it { order.should_receive(:line_items).and_return(@line_items) }
477
489
  it { line_item.should_receive(:variant).and_return(variant) }
478
490
  it { line_item.should_receive(:save).and_return(true) }
@@ -504,7 +516,8 @@ describe Spree::Admin::PosController do
504
516
 
505
517
  it { controller.should_receive(:ensure_pos_order).and_return(true) }
506
518
  it { controller.should_receive(:ensure_unpaid_order).and_return(true) }
507
- it { controller.should_not_receive(:ensure_pos_shipping_method) }
519
+ it { controller.should_receive(:ensure_pos_shipping_method).and_return(true) }
520
+ it { controller.should_receive(:ensure_active_store).and_return(true) }
508
521
  it { controller.should_not_receive(:ensure_payment_method) }
509
522
  it { order.should_receive(:shipment).and_return(@shipment) }
510
523
  it { @shipment.should_receive(:stock_location).and_return(@stock_location) }
@@ -562,7 +575,8 @@ describe Spree::Admin::PosController do
562
575
  describe 'adds to order' do
563
576
  it { controller.should_receive(:ensure_pos_order).and_return(true) }
564
577
  it { controller.should_receive(:ensure_unpaid_order).and_return(true) }
565
- it { controller.should_not_receive(:ensure_pos_shipping_method) }
578
+ it { controller.should_receive(:ensure_pos_shipping_method).and_return(true) }
579
+ it { controller.should_receive(:ensure_active_store).and_return(true) }
566
580
  it { controller.should_not_receive(:ensure_payment_method) }
567
581
 
568
582
  it { order.should_receive(:contents).and_return(@order_contents) }
@@ -630,7 +644,8 @@ describe Spree::Admin::PosController do
630
644
  describe 'removes from order' do
631
645
  it { controller.should_receive(:ensure_pos_order).and_return(true) }
632
646
  it { controller.should_receive(:ensure_unpaid_order).and_return(true) }
633
- it { controller.should_not_receive(:ensure_pos_shipping_method) }
647
+ it { controller.should_receive(:ensure_pos_shipping_method).and_return(true) }
648
+ it { controller.should_receive(:ensure_active_store).and_return(true) }
634
649
  it { controller.should_not_receive(:ensure_payment_method) }
635
650
 
636
651
  it { order.should_receive(:contents).and_return(@order_contents) }
@@ -691,7 +706,8 @@ describe Spree::Admin::PosController do
691
706
  context 'before filters' do
692
707
  it { controller.should_receive(:ensure_unpaid_order).and_return(true) }
693
708
  it { controller.should_receive(:ensure_pos_order).and_return(true) }
694
- it { controller.should_not_receive(:ensure_pos_shipping_method) }
709
+ it { controller.should_receive(:ensure_pos_shipping_method).and_return(true) }
710
+ it { controller.should_receive(:ensure_active_store).and_return(true) }
695
711
  it { controller.should_not_receive(:ensure_payment_method) }
696
712
  after { send_request({:number => order.number}) }
697
713
  end
@@ -728,7 +744,8 @@ describe Spree::Admin::PosController do
728
744
  context 'before filters' do
729
745
  it { controller.should_receive(:ensure_unpaid_order).and_return(true) }
730
746
  it { controller.should_receive(:ensure_pos_order).and_return(true) }
731
- it { controller.should_not_receive(:ensure_pos_shipping_method) }
747
+ it { controller.should_receive(:ensure_pos_shipping_method).and_return(true) }
748
+ it { controller.should_receive(:ensure_active_store).and_return(true) }
732
749
  it { controller.should_not_receive(:ensure_payment_method) }
733
750
  after { send_request(:number => order.number, :new_email =>'test-user@pos.com') }
734
751
  end
@@ -790,7 +807,8 @@ describe Spree::Admin::PosController do
790
807
  end
791
808
 
792
809
  context 'before filters' do
793
- it { controller.should_not_receive(:ensure_pos_shipping_method) }
810
+ it { controller.should_receive(:ensure_active_store).and_return(true) }
811
+ it { controller.should_receive(:ensure_pos_shipping_method).and_return(true) }
794
812
  it { controller.should_receive(:ensure_payment_method).and_return(true) }
795
813
  it { controller.should_receive(:ensure_pos_order).and_return(true) }
796
814
  it { controller.should_receive(:ensure_unpaid_order).and_return(true) }
@@ -868,7 +886,8 @@ describe Spree::Admin::PosController do
868
886
  it { @shipment.should_receive(:stock_location=).with(@stock_location).and_return(@stock_location) }
869
887
  it { order.should_receive(:shipment).and_return(@shipment) }
870
888
  it { @shipment.should_receive(:save).and_return(true) }
871
- it { controller.should_not_receive(:ensure_pos_shipping_method) }
889
+ it { controller.should_receive(:ensure_pos_shipping_method).and_return(true) }
890
+ it { controller.should_receive(:ensure_active_store).and_return(true) }
872
891
  it { controller.should_not_receive(:ensure_payment_method) }
873
892
  it { controller.should_receive(:ensure_unpaid_order).and_return(true) }
874
893
  it { controller.should_receive(:ensure_pos_order).and_return(true) }
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::LineItem do
4
+ describe 'validations' do
5
+ it 'validates through Spree::Stock::PosAvailabilityValidator for pos orders' do
6
+ subject._validators[nil].select do |validator|
7
+ validator.class == Spree::Stock::PosAvailabilityValidator && validator.options[:if] == "order.is_pos?"
8
+ end.should_not be_blank
9
+ end
10
+
11
+ it 'removes validation through Spree::Stock::AvailabilityValidator' do
12
+ subject._validators[nil].select do |validator|
13
+ validator.class == Spree::Stock::AvailabilityValidator && validator.options.blank?
14
+ end.should be_blank
15
+ end
16
+
17
+ it 'removes callback for Spree::Stock::AvailabilityValidator' do
18
+ subject._validate_callbacks.select do |callback|
19
+ callback.raw_filter.class == Spree::Stock::AvailabilityValidator && callback.options.blank?
20
+ end.should be_blank
21
+ end
22
+
23
+ it 'validates through Spree::Stock::AvailabilityValidator for non pos orders' do
24
+ subject._validators[nil].select do |validator|
25
+ validator.class == Spree::Stock::AvailabilityValidator && validator.options[:unless] == "order.is_pos?"
26
+ end.should_not be_blank
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Stock::PosAvailabilityValidator do
4
+ let(:country) { Spree::Country.create!(:name => 'mk_country', :iso_name => "mk") }
5
+ let(:state) { country.states.create!(:name => 'mk_state') }
6
+ let(:store) { Spree::StockLocation.create!(:name => 'store', :store => true, :address1 => "home", :address2 => "town", :city => "delhi", :zipcode => "110034", :country_id => country.id, :state_id => state.id, :phone => "07777676767") }
7
+
8
+ before do
9
+ @order = Spree::Order.create!(:is_pos => true)
10
+ @product = Spree::Product.create!(:name => 'test-product', :price => 10)
11
+ @variant = @product.master
12
+ @line_item = @order.line_items.build(:variant_id => @variant.id, :price => @product.price, :quantity => 3)
13
+ @shipment = @order.shipments.create!
14
+ @line_item.stub(:order).and_return(@order)
15
+ @order.stub(:shipment).and_return(@shipment)
16
+ end
17
+
18
+ describe 'ensures stock location' do
19
+ it 'presence' do
20
+ @line_item.order.shipment.stock_location.should be_nil
21
+ @line_item.save
22
+ @line_item.errors[:stock_location].should eq(['No Active Store Associated'])
23
+ end
24
+
25
+ it 'as active' do
26
+ store.update_attributes(:active => false, :store => true)
27
+ @shipment.stub(:stock_location).and_return(store)
28
+ @line_item.save
29
+ @line_item.errors[:stock_location].should eq(['No Active Store Associated'])
30
+ end
31
+
32
+ it 'as store' do
33
+ store.update_attributes(:active => true, :store => false)
34
+ @shipment.stub(:stock_location).and_return(store)
35
+ @line_item.save
36
+ @line_item.errors[:stock_location].should eq(['No Active Store Associated'])
37
+ end
38
+
39
+ it 'as store' do
40
+ store.update_attributes(:active => true, :store => true)
41
+ @shipment.stub(:stock_location).and_return(store)
42
+ @line_item.save
43
+ @line_item.errors[:stock_location].should be_blank
44
+ end
45
+ end
46
+
47
+ describe 'checks for supply' do
48
+ before do
49
+ store.update_attributes(:active => true, :store => true)
50
+ @shipment.stub(:stock_location).and_return(store)
51
+ end
52
+
53
+ it 'adds error if cant supply' do
54
+ @line_item.save
55
+ @line_item.errors[:quantity].should eq(['Adding More Than Available'])
56
+ end
57
+
58
+ it 'no error if can supply' do
59
+ store.stock_items.update_all(:count_on_hand => 4)
60
+ @line_item.save!
61
+ @line_item.errors[:quantity].should be_blank
62
+ end
63
+
64
+ it 'finds out quantity difference' do
65
+ @line_item.should_receive(:quantity_was).and_return(nil)
66
+ @line_item.save
67
+ end
68
+ end
69
+ end
@@ -40,4 +40,17 @@ describe Spree::StockLocation do
40
40
  it { @invalid_store.errors[:address].should eq(['is invalid']) }
41
41
  end
42
42
  end
43
+
44
+ describe '#can_supply?' do
45
+ before do
46
+ @product = Spree::Product.create!(:name => 'test-product', :price => 10)
47
+ @variant = @product.master
48
+ @stock_item = store.stock_items.where(:variant_id => @variant.id).first
49
+ @stock_item.update_column(:count_on_hand, 2)
50
+ end
51
+
52
+ it { store.can_supply?(1,@variant).should be_true }
53
+ it { store.can_supply?(2,@variant).should be_true }
54
+ it { store.can_supply?(3,@variant).should be_false }
55
+ end
43
56
  end
@@ -6,7 +6,7 @@ require 'rspec/rails'
6
6
 
7
7
  require 'rubygems'
8
8
  require 'bundler/setup'
9
- require 'spree_pos'
9
+ require 'spree-point-of-sale'
10
10
  require 'database_cleaner'
11
11
 
12
12
  # Requires supporting ruby files with custom matchers and macros, etc,
@@ -3,7 +3,7 @@
3
3
  Gem::Specification.new do |s|
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.name = "spree-point-of-sale"
6
- s.version = "1.0.2"
6
+ s.version = "1.0.3"
7
7
 
8
8
  s.authors = ["Torsten R, Nishant Tuteja, Manish Kangia"]
9
9
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree-point-of-sale
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-01-23 00:00:00.000000000 Z
12
+ date: 2014-01-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: spree_core
@@ -100,11 +100,13 @@ files:
100
100
  - app/controllers/spree/admin/pos_controller.rb
101
101
  - app/controllers/spree/admin/stock_locations_controller_decorator.rb
102
102
  - app/helpers/admin/barcode_helper.rb
103
+ - app/models/spree/line_item_decorator.rb
103
104
  - app/models/spree/order_decorator.rb
104
105
  - app/models/spree/payment_decorator.rb
105
106
  - app/models/spree/payment_method/point_of_sale.rb
106
107
  - app/models/spree/shipment_decorator.rb
107
108
  - app/models/spree/stock/coordinator_decorator.rb
109
+ - app/models/spree/stock/pos_availability_validator.rb
108
110
  - app/models/spree/stock_location_decorator.rb
109
111
  - app/models/spree/user_decorator.rb
110
112
  - app/models/spree/variant_decorator.rb
@@ -145,11 +147,13 @@ files:
145
147
  - spec/constants_spec.rb
146
148
  - spec/controllers/spree/admin/barcode_controller_spec.rb
147
149
  - spec/controllers/spree/admin/pos_controller_spec.rb
150
+ - spec/models/spree/line_item_decorator_spec.rb
148
151
  - spec/models/spree/order_decorator_spec.rb
149
152
  - spec/models/spree/payment_decorator_spec.rb
150
153
  - spec/models/spree/payment_method/point_of_sale_spec.rb
151
154
  - spec/models/spree/shipment_decorator_spec.rb
152
155
  - spec/models/spree/stock/coordinator_spec.rb
156
+ - spec/models/spree/stock/pos_availability_validator_spec.rb
153
157
  - spec/models/spree/stock_location_decorator_spec.rb
154
158
  - spec/models/spree/user_decorator_spec.rb
155
159
  - spec/models/spree/varaint_decorator_spec.rb