spree-point-of-sale 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/.gitignore +16 -0
  2. data/Gemfile +20 -0
  3. data/LICENSE +23 -0
  4. data/README.md +71 -0
  5. data/Rakefile +29 -0
  6. data/Versionfile +11 -0
  7. data/app/assets/images/admin/pos/customer.png +0 -0
  8. data/app/assets/images/admin/pos/del_16.png +0 -0
  9. data/app/assets/images/admin/pos/plus_16.png +0 -0
  10. data/app/assets/images/admin/pos/select.jpg +0 -0
  11. data/app/assets/javascripts/admin/spree_pos.js +20 -0
  12. data/app/assets/stylesheets/admin/html-label.css +20 -0
  13. data/app/assets/stylesheets/admin/spree_pos.css +25 -0
  14. data/app/controllers/spree/admin/barcode_controller.rb +49 -0
  15. data/app/controllers/spree/admin/checkout_controller_decorator.rb +7 -0
  16. data/app/controllers/spree/admin/pos_controller.rb +205 -0
  17. data/app/controllers/spree/admin/stock_locations_controller_decorator.rb +13 -0
  18. data/app/helpers/admin/barcode_helper.rb +31 -0
  19. data/app/models/spree/order_decorator.rb +38 -0
  20. data/app/models/spree/payment_decorator.rb +10 -0
  21. data/app/models/spree/payment_method/point_of_sale.rb +30 -0
  22. data/app/models/spree/shipment_decorator.rb +29 -0
  23. data/app/models/spree/stock/coordinator_decorator.rb +10 -0
  24. data/app/models/spree/stock_location_decorator.rb +18 -0
  25. data/app/models/spree/user_decorator.rb +10 -0
  26. data/app/models/spree/variant_decorator.rb +3 -0
  27. data/app/overrides/add_barcode_link_for_products_and_variants.rb +21 -0
  28. data/app/overrides/add_is_pos_filter_to_admin_orders.rb +11 -0
  29. data/app/overrides/add_pos_button.rb +5 -0
  30. data/app/overrides/add_store_to_spree_stock_locations.rb +11 -0
  31. data/app/overrides/admin_adds_pos_config.rb +7 -0
  32. data/app/overrides/codes.rb +10 -0
  33. data/app/overrides/pos_tab.rb +6 -0
  34. data/app/views/spree/admin/barcode/basic.html.erb +28 -0
  35. data/app/views/spree/admin/invoice/_line_items_invoice.html.erb +34 -0
  36. data/app/views/spree/admin/invoice/_receipt_header.html.erb +13 -0
  37. data/app/views/spree/admin/invoice/_totals_receipt.html.erb +25 -0
  38. data/app/views/spree/admin/invoice/receipt.html.erb +26 -0
  39. data/app/views/spree/admin/orders/_admin_pos_config.html.erb +5 -0
  40. data/app/views/spree/admin/orders/_pos_button.html.erb +1 -0
  41. data/app/views/spree/admin/pos/find.html.erb +81 -0
  42. data/app/views/spree/admin/pos/show.html.erb +137 -0
  43. data/app/views/spree/admin/pos/update_stock_location.js.erb +5 -0
  44. data/app/views/spree/admin/products/_barcode_product_link.html.erb +3 -0
  45. data/app/views/spree/admin/products/_barcode_variant_link.html.erb +3 -0
  46. data/config/application.rb +23 -0
  47. data/config/boot.rb +5 -0
  48. data/config/initializers/constants.rb +4 -0
  49. data/config/locales/codes-fi.yml +3 -0
  50. data/config/locales/en.yml +16 -0
  51. data/config/locales/fi.yml +8 -0
  52. data/config/routes.rb +21 -0
  53. data/db/migrate/20130723140316_add_delivered_at_and_canceled_at_to_spree_shipments.rb +6 -0
  54. data/db/migrate/20130730102503_add_store_and_address_id_in_spree_stock_locations.rb +8 -0
  55. data/db/migrate/20131014053417_add_is_pos_to_spree_orders.rb +6 -0
  56. data/db/migrate/20131025110309_add_card_name_to_spree_payments.rb +5 -0
  57. data/lib/generators/spree_pos/install/install_generator.rb +27 -0
  58. data/lib/spree_pos.rb +2 -0
  59. data/lib/spree_pos/configuration.rb +7 -0
  60. data/lib/spree_pos/engine.rb +29 -0
  61. data/spec/constants_spec.rb +8 -0
  62. data/spec/controllers/spree/admin/barcode_controller_spec.rb +86 -0
  63. data/spec/controllers/spree/admin/pos_controller_spec.rb +849 -0
  64. data/spec/models/spree/order_decorator_spec.rb +178 -0
  65. data/spec/models/spree/payment_decorator_spec.rb +115 -0
  66. data/spec/models/spree/payment_method/point_of_sale_spec.rb +25 -0
  67. data/spec/models/spree/shipment_decorator_spec.rb +172 -0
  68. data/spec/models/spree/stock/coordinator_spec.rb +31 -0
  69. data/spec/models/spree/stock_location_decorator_spec.rb +43 -0
  70. data/spec/models/spree/user_decorator_spec.rb +24 -0
  71. data/spec/models/spree/varaint_decorator_spec.rb +31 -0
  72. data/spec/spec_helper.rb +67 -0
  73. data/spree-point-of-sale.gemspec +32 -0
  74. metadata +183 -0
@@ -0,0 +1,137 @@
1
+ <% content_for :sidebar do %>
2
+ <% if user_stock_locations(spree_current_user).count > 1 %>
3
+
4
+ <div class="stock_locations">
5
+ <fieldset>
6
+ <legend>Change Stock Location</legend>
7
+ <%= form_tag "/admin/pos/update_stock_location/#{@order.number}", :class => 'modify_stock_location_form' do %>
8
+ <% user_stock_locations(spree_current_user).all.each do |stock_location| %>
9
+ <%= radio_button_tag :stock_location_id, stock_location.id, (stock_location.id == @order.shipment.stock_location.id), :id => "stock_location_#{ stock_location.id }", :class => 'stock_location_checkbox' %><%= stock_location.name %><br />
10
+ <% end %>
11
+ <br />
12
+ <%= submit_tag 'Update', :confirm => 'The Order will be cleaned. Are you sure?' %>
13
+ <% end %>
14
+ </fieldset>
15
+ </div>
16
+ <% end %>
17
+ <div class="search">
18
+ <legend>Search & Add Product </legend>
19
+ <%= form_tag("/admin/pos/find/#{@order.number}", :method => :get, :id => "product_search") do %>
20
+ <input type="hidden" value="1" name="index">
21
+ <div class="box">
22
+ <p> <%= text_field_tag :sku, "" , :size => 15 %> <%= button Spree.t("search") %> </p>
23
+ </div>
24
+ <% end %>
25
+ </div>
26
+ <br/><br/><br/><br/>
27
+ <a href="/admin/pos/export" target="_blank">
28
+ <% image_tag("admin/pos/export.jpg" ) #if Spree::Config[:pos_export] %>
29
+ </a>
30
+ <%end%>
31
+
32
+ <h5>Order No: <%= @order.number %>
33
+ <a href="/admin/pos/new" onClick="javascript:if (newwindow) newwindow.close()" id="create_pos_order" class="button">
34
+ Create New Order
35
+ </a>
36
+ </h5>
37
+
38
+ <h5>Order For: <%= @order.email %></h5>
39
+
40
+ <div>
41
+ <a href="javascript:void(0);" id="associate_user_toggle" class="button">
42
+ Change User
43
+ </a>
44
+ </div>
45
+ <%= form_tag "/admin/pos/associate_user/#{@order.number}", :id => "associate_user" do %>
46
+ <div id="pos-tabs">
47
+ <ul>
48
+ <li><a href="#associate_email">Search User by email</a></li>
49
+ <li><a href="#associate_new_user">Add a new user</a></li>
50
+ </ul>
51
+ <div id="associate_email" class="commonfieldset">
52
+ <div class="row">
53
+ <div class="four columns alpha">
54
+ <div class="field">
55
+ <label>Email</label>
56
+ <%= text_field_tag :email, '', :size => 25 %> <br/>
57
+ </div>
58
+ </div>
59
+ </div>
60
+ </div>
61
+ <!-- <div class="or_separator"><span>OR</span></div> -->
62
+ <div id="associate_new_user" class="commonfieldset">
63
+ <div class="row">
64
+ <div class="four columns alpha">
65
+ <div class="field">
66
+ <label>New Email</label>
67
+ <%= text_field_tag :new_email, nil, :size => 25 %> <br/>
68
+ </div>
69
+ </div>
70
+ </div>
71
+ </div>
72
+ <div class="four columns alpha">
73
+ <div class="field">
74
+ <%= button "Associate User" %> </div>
75
+ </div>
76
+ </div>
77
+ <% end %>
78
+ <table id='pos-order-table' class="index">
79
+ <tr>
80
+ <th><%= Spree.t('item_description') %></th>
81
+ <th><%= Spree.t('quantity') %></th>
82
+ <th>Actual Price</th>
83
+ <th class="discount_price"><%= Spree.t('discount') %> (%)</th>
84
+ <th class="price"><%= Spree.t('price') %></th>
85
+ <th><%= Spree.t('remove') + "/"+ Spree.t('add') %></th>
86
+ <th><%= Spree.t('update_discount') %></th>
87
+ </tr>
88
+ <% @order.line_items.each do | item | %>
89
+ <tr>
90
+ <td width="220"><%= image_tag item.variant.product.images.first.attachment.url(:mini) if item.variant.product.images.first %> <%= "#{item.variant.name} #{item.variant.options_text}"%><br/>
91
+ <%="(SKU:#{item.variant.sku})" %></td>
92
+ <td><%= form_tag("/admin/pos/update_line_item_quantity/#{@order.number}") do %> <%= hidden_field_tag(:line_item_id, item.id) %> <%= select_tag("quantity" , options_for_select( (1..20).to_a , item.quantity), :onchange => 'this.form.submit()')%>
93
+ <%end%></td>
94
+ <td><%= item.variant.price %></td>
95
+ <td><%= (((item.variant.price - item.price)/item.variant.price)*100).round(1) %></td>
96
+ <td class="price"><big> <%= form_tag do %> <%= hidden_field_tag(:price, item.id) %>
97
+ <input type="submit" style="display:none"/>
98
+ <%= text_field_tag "price#{item.id}" , item.price , :readonly => true %>
99
+ <% end %>
100
+ </big></td>
101
+ <td align="center"><%= link_to image_tag("admin/pos/del_16.png") , "/admin/pos/remove/#{@order.number}/#{item.variant.id}" %> <%= link_to image_tag("admin/pos/plus_16.png") , "/admin/pos/add/#{@order.number}/#{item.variant.id}" %></td>
102
+ <td class='discount'><big> <%= form_tag("/admin/pos/apply_discount/#{@order.number}") do %> <%= hidden_field_tag(:line_item_id, item.id) %> <%= text_field_tag("discount") %> <%= submit_tag 'update', :class => 'submit' %>
103
+ <%end%>
104
+ </big></td>
105
+ </tr>
106
+ <% end %>
107
+ <% @order.adjustments.eligible.each do |adjustment| %>
108
+ <tr id="order-charges" class="total">
109
+ <td><strong><%= adjustment.label %></strong></td>
110
+ <td colspan="6" class="total"><span><%= adjustment.display_amount.to_html %></span></td>
111
+ </tr>
112
+ <% end %>
113
+ <tr class="total">
114
+ <td ><b><%= Spree.t('order_total') %>:</b></td>
115
+ <td colspan="6" class="total"><span id="order_total"><%= @order.display_total.to_html %></span></td>
116
+ </tr>
117
+ </table>
118
+
119
+ <div class="belowtable row"> <%= button_to "Remove All Items", admin_pos_clean_order_path(:number => @order.number) , data: { confirm: "Are you sure?" } %> </div>
120
+
121
+ <div class="row">
122
+
123
+ <%= form_tag "/admin/pos/update_payment/#{@order.number}", :id => "update_payment" do %>
124
+ <div class="four rows alpha">
125
+ <div class="field">
126
+ <p>
127
+ <% Spree::PaymentMethod.where("type='Spree::PaymentMethod::PointOfSale'").each do |method| %>
128
+ <label> <%= radio_button_tag :payment_method_id, method.id, false, 'data-name' => method.name %> <%= Spree.t(method.name, :scope => :payment_methods, :default => method.name) %> </label>
129
+ <% end %>
130
+ </p>
131
+ </div>
132
+
133
+ <div id="card_name" class="rows"> <%= select_tag(:card_name, options_for_select(Spree::Order::CARD_TYPE, "#{@order.payments.first.try(:card_name)}"), include_blank: true, :id => 'card_name_options') %> <%= button_tag "Confirm And Print", :class => "fr", :data => { :confirm =>"Are you sure you want to confirm this order?"} %>
134
+ </div>
135
+ </div>
136
+ <% end %>
137
+ </div>
@@ -0,0 +1,5 @@
1
+ <% if @order.shipment.errors.full_messages.present? %>
2
+ alert('Stock Location is not updated.');
3
+ <% else %>
4
+ alert('Stock Location is updated.');
5
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <a href="/admin/barcode/print/<%=@product.master.id%>" class="button">
2
+ <span> <%= t :product_label %> </span> </a>
3
+
@@ -0,0 +1,3 @@
1
+ <a href="/admin/barcode/print/<%=@variant.id%>" class="button">
2
+ <span> <%= t :variant_label %> </span> </a>
3
+
@@ -0,0 +1,23 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require 'rails/all'
4
+
5
+ Bundler.require(*Rails.groups)
6
+ require "spree_pos"
7
+
8
+ module SpreePointOfSale
9
+ class Application < Rails::Application
10
+ # Settings in config/environments/* take precedence over those specified here.
11
+ # Application configuration should go into files in config/initializers
12
+ # -- all .rb files in that directory are automatically loaded.
13
+
14
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
15
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
16
+ # config.time_zone = 'Central Time (US & Canada)'
17
+
18
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
19
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
20
+ # config.i18n.default_locale = :de
21
+ end
22
+ end
23
+
data/config/boot.rb ADDED
@@ -0,0 +1,5 @@
1
+ # Set up gems listed in the Gemfile.
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
3
+
4
+ require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
5
+ $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)
@@ -0,0 +1,4 @@
1
+ CARD_TYPE = ['Visa', 'MasterCard', 'Verve', 'AmericanExpress', 'China UnionPay']
2
+ VALID_DISCOUNT_REGEX = /^\d*\.?\d+$/
3
+ RANDOM_PASS_REGEX = [*('A'..'Z'),*(1..9)]
4
+ PRODUCTS_PER_SEARCH_PAGE = 20
@@ -0,0 +1,3 @@
1
+ fi:
2
+ product_label: Tuoten Tarra
3
+ variant_label: Variantin Tarra
@@ -0,0 +1,16 @@
1
+ en:
2
+ order_number: Order Number
3
+ item_description: Item Description
4
+ qty: Quantity
5
+ total: Total
6
+ order_total: Order Total
7
+ spree:
8
+ pos: POS
9
+ product_added: Product added
10
+ product_removed: Product removed
11
+ quantity_changed: "Quantity changed"
12
+ price_change: Price changed
13
+ order_total: 'Order Total'
14
+ item_description: 'Item Description'
15
+ select: Select
16
+ master_price: Master Price
@@ -0,0 +1,8 @@
1
+ fi:
2
+ pos: POS
3
+ product_added: "Tuote lisätty"
4
+ quantity_changed: "Määrä muutettu"
5
+ product_removed: "Tuote poistettu"
6
+ price_changed: "Hinta muutettu"
7
+ discount: Alennus
8
+ quantity: Määrä
data/config/routes.rb ADDED
@@ -0,0 +1,21 @@
1
+ Spree::Core::Engine.routes.prepend do
2
+ namespace :admin do
3
+ match "barcode/print_variants_barcodes/:id" => "barcode#print_variants_barcodes"
4
+ match "barcode/print/:id" => "barcode#print"
5
+
6
+ match "pos/new" => "pos#new"
7
+ match "pos/show/:number" => "pos#show", :as => :pos_show_order
8
+ match "pos/clean/:number" => "pos#clean_order", :as => :pos_clean_order
9
+ match "pos/find/:number" => "pos#find"
10
+ match "pos/add/:number/:item" => "pos#add"
11
+ match "pos/remove/:number/:item" => "pos#remove"
12
+ match "pos/associate_user/:number" => "pos#associate_user"
13
+ match "pos/update_payment/:number" => "pos#update_payment"
14
+ match "pos/update_line_item_quantity/:number" => "pos#update_line_item_quantity"
15
+ match "pos/apply_discount/:number" => "pos#apply_discount"
16
+
17
+ match "pos/index" => "pos#new"
18
+ match "pos/update_stock_location/:number" => "pos#update_stock_location"
19
+ get "pos" , :to => "pos#new"
20
+ end
21
+ end
@@ -0,0 +1,6 @@
1
+ class AddDeliveredAtAndCanceledAtToSpreeShipments < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_shipments, :delivered_at, :datetime
4
+ add_column :spree_shipments, :canceled_at, :datetime
5
+ end
6
+ end
@@ -0,0 +1,8 @@
1
+ class AddStoreAndAddressIdInSpreeStockLocations < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_stock_locations, :store, :boolean, :default => false
4
+ add_column :spree_stock_locations, :address_id, :integer
5
+ add_index :spree_stock_locations, :store, :name => "index_spree_stock_locations_on_store"
6
+ add_index :spree_stock_locations, :address_id, :name => "index_spree_stock_locations_on_address_id"
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ class AddIsPosToSpreeOrders < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_orders, :is_pos, :boolean, :default => false
4
+ add_index :spree_orders, :is_pos
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class AddCardNameToSpreePayments < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_payments, :card_name, :string
4
+ end
5
+ end
@@ -0,0 +1,27 @@
1
+ module SpreePos
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+
5
+ def add_javascripts
6
+ append_file 'app/assets/javascripts/admin/all.js', "//= require admin/spree_pos\n"
7
+ end
8
+
9
+ def add_stylesheets
10
+ inject_into_file 'app/assets/stylesheets/admin/all.css', " *= require admin/spree_pos\n", :before => /\*\//, :verbose => true
11
+ end
12
+
13
+ def add_migrations
14
+ run 'bundle exec rake railties:install:migrations FROM=spree_pos'
15
+ end
16
+
17
+ def run_migrations
18
+ res = ask "Would you like to run the migrations now? [Y/n]"
19
+ if res == "" || res.downcase == "y"
20
+ run 'bundle exec rake db:migrate'
21
+ else
22
+ puts "Skiping rake db:migrate, don't forget to run it!"
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
data/lib/spree_pos.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "spree/core"
2
+ require "spree_pos/engine"
@@ -0,0 +1,7 @@
1
+ require "spree/core"
2
+ module SpreePos
3
+ class Configuration < Spree::Preferences::Configuration
4
+ preference :pos_shipping, :string
5
+ preference :pos_printing, :string , :default => "/admin/invoice/number/receipt"
6
+ end
7
+ end
@@ -0,0 +1,29 @@
1
+ module SpreePos
2
+
3
+ class Engine < Rails::Engine
4
+ engine_name 'spree_pos'
5
+
6
+ config.autoload_paths += %W(#{config.root}/lib)
7
+
8
+ initializer "spree.spree_pos.preferences", :after => "spree.environment" do |app|
9
+ SpreePos::Config = SpreePos::Configuration.new
10
+ ::CARD_TYPE = ['Visa', 'MasterCard', 'Verve', 'AmericanExpress', 'China UnionPay']
11
+ app.config.spree.payment_methods << Spree::PaymentMethod::PointOfSale
12
+ end
13
+
14
+ def self.activate
15
+
16
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
17
+ Rails.configuration.cache_classes ? require(c) : load(c)
18
+ end
19
+ Dir.glob(File.join(File.dirname(__FILE__), '../../../app/overrides/*.rb')) do |c|
20
+ Rails.configuration.cache_classes ? require(c) : load(c)
21
+ end
22
+ Spree::Product.class_eval do
23
+ delegate_belongs_to :master, :ean
24
+ end
25
+ end
26
+
27
+ config.to_prepare &method(:activate).to_proc
28
+ end
29
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Constants" do
4
+ it { CARD_TYPE.should eq(['Visa', 'MasterCard', 'Verve', 'AmericanExpress', 'China UnionPay']) }
5
+ it { VALID_DISCOUNT_REGEX.should eq(/^\d*\.?\d+$/) }
6
+ it { RANDOM_PASS_REGEX.should eq([*('A'..'Z'),*(1..9)]) }
7
+ it { PRODUCTS_PER_SEARCH_PAGE.should eq(20) }
8
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Admin::BarcodeController do
4
+ let(:product) { mock_model(Spree::Product, :name => 'test-product') }
5
+ let(:variant) { mock_model(Spree::Variant, :name => 'test-variant') }
6
+ let(:user) { mock_model(Spree::User) }
7
+ let(:role) { mock_model(Spree::Role) }
8
+ let(:roles) { [role] }
9
+
10
+ before do
11
+ controller.stub(:spree_current_user).and_return(user)
12
+ controller.stub(:authorize_admin).and_return(true)
13
+ controller.stub(:authorize!).and_return(true)
14
+ user.stub(:generate_spree_api_key!).and_return(true)
15
+ user.stub(:roles).and_return(roles)
16
+ roles.stub(:includes).and_return(roles)
17
+ role.stub(:ability).and_return(true)
18
+ end
19
+
20
+ describe 'print_variants_barcodes' do
21
+ def send_request(params = {})
22
+ get :print_variants_barcodes, params.merge!({:use_route => 'spree'})
23
+ end
24
+
25
+ before do
26
+ Spree::Product.stub(:where).with(:id => product.id.to_s).and_return([product])
27
+ controller.stub(:empty_pdf).and_return([])
28
+ @pdf_object = Object.new
29
+ @pdf_object.stub(:render).and_return('123')
30
+ end
31
+
32
+ context 'when variants present' do
33
+ before do
34
+ product.stub(:variants).and_return([variant])
35
+ controller.stub(:append_barcode_to_pdf_for_variant).with(variant, []).and_return(@pdf_object)
36
+ controller.stub(:send_data).with('123' , :type => "application/pdf" , :filename => "#{product.name}.pdf").and_return{controller.render :nothing => true}
37
+ end
38
+
39
+ it { product.should_receive(:variants).and_return([variant]) }
40
+ it { product.should_not_receive(:master) }
41
+ it { controller.should_not_receive(:print) }
42
+ it { Spree::Product.should_receive(:where).with(:id => product.id.to_s).and_return([product]) }
43
+ it { controller.should_receive(:append_barcode_to_pdf_for_variant).with(variant, []).and_return(@pdf_object) }
44
+ it { controller.should_receive(:send_data).with('123' , :type => "application/pdf" , :filename => "#{product.name}.pdf").and_return{controller.render :nothing => true} }
45
+
46
+ after { send_request({:id => product.id}) }
47
+ end
48
+
49
+ context 'when variants not present' do
50
+ before do
51
+ product.stub(:variants).and_return([])
52
+ product.stub(:master).and_return(variant)
53
+ controller.stub(:append_barcode_to_pdf_for_variant).with(variant).and_return(@pdf_object)
54
+ controller.stub(:send_data).with('123' , :type => "application/pdf" , :filename => "#{variant.name}.pdf").and_return{controller.render :nothing => true}
55
+ end
56
+
57
+ it { product.should_receive(:variants).and_return([]) }
58
+ it { product.should_receive(:master).and_return(variant) }
59
+ it { Spree::Product.should_receive(:where).with(:id => product.id.to_s).and_return([product]) }
60
+ it { controller.should_receive(:append_barcode_to_pdf_for_variant).with(variant).and_return(@pdf_object) }
61
+ it { controller.should_receive(:send_data).with('123' , :type => "application/pdf" , :filename => "#{variant.name}.pdf").and_return{controller.render :nothing => true} }
62
+
63
+ after { send_request({:id => product.id}) }
64
+ end
65
+ end
66
+
67
+ describe 'print' do
68
+ def send_request(params = {})
69
+ get :print, params.merge!({:use_route => 'spree'})
70
+ end
71
+
72
+ before do
73
+ @pdf_object = Object.new
74
+ @pdf_object.stub(:render).and_return('123')
75
+ Spree::Variant.stub(:where).with(:id => variant.id.to_s).and_return([variant])
76
+ controller.stub(:append_barcode_to_pdf_for_variant).with(variant).and_return(@pdf_object)
77
+ controller.stub(:send_data).with('123' , :type => "application/pdf" , :filename => "#{variant.name}.pdf").and_return{controller.render :nothing => true}
78
+ end
79
+
80
+ it { Spree::Variant.should_receive(:where).with(:id => variant.id.to_s).and_return([variant]) }
81
+ it { controller.should_receive(:append_barcode_to_pdf_for_variant).with(variant).and_return(@pdf_object) }
82
+ it { controller.should_receive(:send_data).with('123' , :type => "application/pdf" , :filename => "#{variant.name}.pdf").and_return{controller.render :nothing => true} }
83
+
84
+ after { send_request({:id => variant.id}) }
85
+ end
86
+ end