spree_html_invoice 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown ADDED
@@ -0,0 +1,61 @@
1
+ SUMMARY
2
+ =======
3
+
4
+ This extension provides a "Print Invoice" button on the Admin Orders view screen which opens a prinatble html page with the order details.
5
+
6
+ You have to set up your computer for printing, or PDF generation. Off course, if you cave a mac that is as easy as pressing the print + save as pdf buttons.
7
+
8
+ If you need server-side pdf generation, use the spree-print-invoice extension.
9
+
10
+ INSTALLATION
11
+ ============
12
+
13
+ For spree 0.7, ie using deface and rails 3.1. There is a brach 0.60 for an older version.
14
+ As I don't release gems, for better version control you may wish to clone the repository.
15
+ If you have improvements, please send pull though.
16
+
17
+ 1. To install you need to add the following lines to your Gemfile (no external dependendies)
18
+
19
+ gem 'spree_html_invoice' , :git => 'git://github.com/dancinglightning/spree-html-invoice.git'
20
+
21
+ 2. run bundler
22
+
23
+ bundle install
24
+
25
+ 3. Configure your logo and footer text or more. It's easy as it's html.
26
+
27
+ 4. Enjoy!
28
+
29
+
30
+ Configuration
31
+ ==============
32
+
33
+ 1. Set the logo path preference to include your store / company logo.
34
+
35
+ Spree::Config.set(:html_invoice_logo_path => "company-logo.png")
36
+
37
+ Somewhere in your asset path
38
+
39
+ 2. Add your own own footer texts to the locale. The current footer works with :footer_left , :footer_left2 and :footer_right, :footer_right2 where the 1 version is on the left in bold, and the 2 version the "value" on the right.
40
+
41
+ 3. Override any of the partial templates. they are address, footer, totals, header, thanks , and the line_items. The whole tanks is wrapped in a thanks hook, so replace or add at will.
42
+
43
+ 4. Set :suppress_anonymous_address option to get blank addresses for anonymous email addresses (as created by my spree_last_address extension for empty/unknown user info)
44
+
45
+ 5. Enable packaging slips, by setting
46
+
47
+ Spree::Config.set(:html_buttons => "invoice,packaging_slip" #comma separated list
48
+
49
+ Use above feature for your own template if you want. For each button_name, define a subsection with header, print, and thanks, in your locale.
50
+
51
+
52
+ Extra
53
+ =====
54
+
55
+ There is now a receipt template, for a normal receipt printer (ie 70mm). This works for us, but is not quite finished.
56
+
57
+ Barcodes have gone to their own package spree-product-barcodes a(and they are starting to work too)
58
+
59
+ Contributions welcome
60
+
61
+ Torsten
@@ -0,0 +1,108 @@
1
+ /* @override http://localhost:3000/stylesheets/admin/html-invoice.css */
2
+
3
+ div.a4 {
4
+ width: 620px;
5
+ font-size: 12px;
6
+ font-family: helvetica, verdana, serif;
7
+
8
+ }
9
+ div.header {
10
+ width: 620px;
11
+ height: 150px;
12
+ }
13
+ div.address {
14
+ width: 620px;
15
+ border-top:1px solid grey;
16
+ margin-bottom: 10px;
17
+ padding: 6px;
18
+
19
+ }
20
+ .line_items {
21
+ width: 620px;
22
+ }
23
+ div.wrapper {
24
+ width: 620px;
25
+ height: 540px;
26
+ border-top:1px solid grey;
27
+ padding: 6px;
28
+
29
+ }
30
+
31
+ div.thanks {
32
+ width: 620px;
33
+ margin-top: 20px;
34
+ }
35
+ div.spacer {
36
+ width: 620px;
37
+ }
38
+ div.totals {
39
+ height: 100px;
40
+ margin-bottom: 20px;
41
+ float: right;
42
+ }
43
+
44
+ .totals .cell {
45
+ width: 130px;
46
+ }
47
+
48
+ div.footer {
49
+ width: 620px;
50
+ border-top:1px solid grey;
51
+ padding: 6px;
52
+ }
53
+
54
+ .footer .bold {
55
+ width: 100px;
56
+ }
57
+ .footer .cell {
58
+ width: 220px;
59
+ }
60
+
61
+
62
+ .title { font-weight: bold; color: #FF9933; font-size: 18px; }
63
+ .bold { font-weight: bold; }
64
+ .price { width: 55px ; }
65
+
66
+ table.address{
67
+ width: 620px;
68
+ }
69
+ table.index th {
70
+ background: #cdcdcd top left repeat-x;
71
+ padding: 7px 10px;
72
+ border-left: 1px solid #ddd;
73
+ border-top: 1px solid #ddd;
74
+ border-right: 1px solid #aaa;
75
+ border-bottom: 1px solid #aaa;
76
+ text-shadow: #efefef 1px 1px 0px; }
77
+ table.index th .right {
78
+ float:right;
79
+ font-weight:normal;
80
+ }
81
+ table.index th.id-col {
82
+ text-align: center; }
83
+ table.index td {
84
+ border-bottom:1px solid #ddd;
85
+ padding: 3px 10px;
86
+ }
87
+ table.index td.lbl-col {
88
+ width: 12%; }
89
+ table.index td.val-col {
90
+ width: 38%; }
91
+ table.index tr.alt td {
92
+ background-color: #efefef; }
93
+ table.index.green th {
94
+ background: #cfefa7 top left repeat-x;
95
+ border-left: 1px solid #E4FDB4;
96
+ border-top: 1px solid #E4FDB4;
97
+ border-right: 1px solid #B7CB90;
98
+ border-bottom: 1px solid #B7CB90; }
99
+ table.index.green td {
100
+ background-color: #efe; }
101
+ table.index.order-summary {
102
+ clear: both; }
103
+ table.index.order-summary tr.totals th {
104
+ background: transparent;
105
+ text-align: right;
106
+ border: none; }
107
+ table.index td.actions {text-align:right;}
108
+
@@ -0,0 +1,59 @@
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:"Trebuchet MS";
10
+ font-size:17px;
11
+ color:#000000;
12
+ width: 310px;
13
+ }
14
+
15
+
16
+ div.header {
17
+ text-align: center;
18
+ padding: 6px;
19
+ line-height: 1.3;
20
+ width: 330px;
21
+ }
22
+
23
+ .shop { font-weight: bold; font-size: 30px; line-height: 1.2;}
24
+ .info { padding: 6px; font-size: 15px; text-align: center; line-height: 1.3; width: 330px;}
25
+
26
+ .line_items {
27
+ width: 300px;
28
+ }
29
+
30
+ div.wrapper {
31
+ width: 300px;
32
+ padding: 2px;
33
+ text-align: left;
34
+ }
35
+
36
+ div.totals {
37
+ margin-bottom: 20px;
38
+ padding: 6px;
39
+ }
40
+
41
+ .totals .cell {
42
+ width: 180px;
43
+ }
44
+
45
+ div.footer {
46
+ width: 300px;
47
+ padding: 6px;
48
+ text-align: center;
49
+ }
50
+
51
+ .footer .bold {
52
+ width: 100px;
53
+ }
54
+ .footer .cell {
55
+ width: 220px;
56
+ }
57
+
58
+
59
+
@@ -0,0 +1,11 @@
1
+ Spree::Admin::OrdersController.class_eval do
2
+
3
+ def invoice
4
+ template = params[:template]
5
+ load_order
6
+ eval "@#{template} = true"
7
+ @order = Spree::Order.find_by_number(params[:id])
8
+ render template , :layout => false
9
+ end
10
+
11
+ end
@@ -0,0 +1,5 @@
1
+ Spree::LineItem.class_eval do
2
+ def tax_price
3
+ return self.price
4
+ end
5
+ end
@@ -0,0 +1,24 @@
1
+ Spree::Variant.class_eval do
2
+ def full_name
3
+ "#{self.name} #{options_text}"
4
+ end
5
+
6
+ def options_text
7
+ return "" unless option_values.first
8
+ self.option_values.map { |ov| "#{ov.presentation}" }.to_sentence({:words_connector => ", ", :two_words_connector => ", "})
9
+ end
10
+
11
+ def presentation
12
+ on = option_values.first
13
+ on ? on.presentation : nil
14
+ end
15
+
16
+ def presentation= val
17
+ on = option_values.first
18
+ if on
19
+ on.name = val
20
+ on.presentation = val
21
+ on.save!
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ Deface::Override.new(:virtual_path => "spree/admin/shared/_order_tabs",
2
+ :name => "Add buttons to sidebar on order show",
3
+ :insert_after => ".sidebar",
4
+ :partial => "spree/admin/orders/html_buttons",
5
+ :disabled => false)
@@ -0,0 +1,36 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
5
+ <%= stylesheet_link_tag "admin/html-invoice.css" , :media => "all" %>
6
+ <title><%= I18n.t("#{params[:template]}.header") %></title>
7
+ </head>
8
+
9
+ <body>
10
+ <div class="a4">
11
+ <div class="header">
12
+ <%= render :partial => "header" %>
13
+ </div>
14
+ <div class="address">
15
+ <%= render :partial => "address" %>
16
+ </div>
17
+ <div class="wrapper">
18
+ <div class="line_items">
19
+ <%= render :partial => "line_items" %>
20
+ </div>
21
+ <div class="thanks">
22
+ <%= render :partial => "thanks" %>
23
+ </div>
24
+ <div class="spacer"> &nbsp;
25
+ </div>
26
+ <div class="totals">
27
+ <%= render :partial => "totals" %>
28
+ </div>
29
+ </div>
30
+ <div class="footer">
31
+ <%= render :partial => "footer" %>
32
+ </div>
33
+ </div>
34
+ </body>
35
+ </html>
36
+
@@ -0,0 +1,30 @@
1
+ <%
2
+ bill_address = @order.bill_address
3
+ ship_address = @order.ship_address
4
+ anonymous = @order.email =~ /@example.net$/
5
+ if (anonymous and Spree::Config[:suppress_anonymous_address]) or !bill_address
6
+ addresses = [[" "," "]] * 5
7
+ else
8
+ addresses = [[ "#{bill_address.firstname} #{bill_address.lastname}", "#{ship_address.firstname} #{ship_address.lastname}"]]
9
+ addresses << [ bill_address.address1 , ship_address.address1 ]
10
+ addresses << [ bill_address.address2 , ship_address.address2 ] unless bill_address.address2.blank? or ship_address.address2.blank? or (bill_address.address2 =~ /\d{3,6}-\d/) or (ship_address.address2 =~ /\d{3,6}-\d/)
11
+ addresses << [ "#{bill_address.zipcode} #{bill_address.city}, #{bill_address.state.abbr}", "#{ship_address.zipcode} #{ship_address.city}, , #{ship_address.state.abbr}" ]
12
+ addresses << [ bill_address.country.name , ship_address.country.name ]
13
+ addresses << [ bill_address.phone , ship_address.phone ]
14
+ end
15
+ %>
16
+ <table class="address">
17
+ <tr>
18
+ <td width="45%" class="billing_header bold"><%=I18n.t(:billing_address)%></td>
19
+ <td width="17%"></td>
20
+ <td width="45%" class="shiping_header bold"><%=I18n.t(:shipping_address)%></td>
21
+ </tr>
22
+ <% addresses.each do |row| %>
23
+ <tr>
24
+ <td height="15px" width="45%" class="billing" class="cell"><%=row[0]%> </td>
25
+ <td width="17%"></td>
26
+ <td height="15px" width="45%" class="shiping_header" class="cell"><%=row[1]%> </td>
27
+ </tr>
28
+ <%end%>
29
+ </table>
30
+
@@ -0,0 +1,8 @@
1
+ <table class="footer">
2
+ <tr>
3
+ <td valign="top" class="cel1 bold"><%==I18n.t(:footer_left)%></td>
4
+ <td valign="top" class="cel2 cell"><%==I18n.t(:footer_left2)%></td>
5
+ <td valign="top" class="cel3 bold"><%==I18n.t(:footer_right)%> </td>
6
+ <td valign="top" class="cel4 cell"><%==I18n.t(:footer_right2)%></td>
7
+ </tr>
8
+ </table>
@@ -0,0 +1,10 @@
1
+ <table class="header">
2
+ <tr>
3
+ <td width="345"><img src="<%= asset_path 'lmm_logo_w312_h58.png'%> alt="logo" width="280"/></td>
4
+ <td width="345"><div align="right">
5
+ <p class="title"><%= I18n.t("#{params[:template]}.header") %></p>
6
+ <p class="bold"><%= I18n.t(:order_number).to_s + " " + @order.number %></p>
7
+ <p class="bold"> <%= I18n.l(@order.completed_at.to_date) if @order.completed_at %></p>
8
+ </div></td>
9
+ </tr>
10
+ </table>
@@ -0,0 +1,6 @@
1
+ <% buttons = "invoice,packaging_slip"
2
+ buttons = buttons.split(",").collect{|b| b.strip } %>
3
+ <% buttons.each do |button| %>
4
+ <%= button_link_to(I18n.t(button.to_s+".print"), invoice_admin_order_path(@order) + "?template=#{button}" ,
5
+ :target => "_blank") %>
6
+ <%end%>
@@ -0,0 +1,21 @@
1
+ <table class="line_items" >
2
+ <tr>
3
+ <td class="sku bold"><%= I18n.t(:sku) unless @receipt %></td>
4
+ <td class="desc bold"><%= I18n.t(:item_description) %></td>
5
+ <td class="price bold"><%=I18n.t(:price) unless @packaging_slip or @receipt%></td>
6
+ <td class="qty bold"><%=I18n.t(:qty) %> </td>
7
+ <td class="total bold" align="right"><%=I18n.t(:total) unless @packaging_slip%></td>
8
+ </tr>
9
+ <% @order.line_items.each do |item| %>
10
+ <tr>
11
+ <td class="cell"><%=item.variant.product.sku unless @receipt%></td>
12
+ <td class="cell"><%=item.variant.full_name%></td>
13
+ <td class="cell"><%=number_to_currency(item.tax_price) unless @packaging_slip or @receipt%></td>
14
+ <td class="cell"><%=item.quantity %></td>
15
+ <td class="cell" align="right"><%=number_to_currency(item.tax_price * item.quantity) unless
16
+ @packaging_slip%></td>
17
+ </tr>
18
+ <% end %>
19
+ </table>
20
+
21
+
@@ -0,0 +1,3 @@
1
+ www.auringostaitaan.fi<br>
2
+ info@auringostaitaan.fi<br>
3
+ puh 09- 621 7001<br><br>&nbsp;</div>
@@ -0,0 +1,6 @@
1
+ <div><br>
2
+ <%= image_tag "store/kauppa/aikl-logo.gif" , :width => "270" , :alt => "logo" %>
3
+ </div>
4
+ <br>
5
+ <span class="shop">Auringosta Itään, <br>Kuusta Länteen</span><br>
6
+ <br>Fredrikinkatu 19 (Viiskulma)<br>00120 Helsinki<br>
@@ -0,0 +1,10 @@
1
+ <table class="thanks_table">
2
+ <tr>
3
+ <td class="cell" cellspan="2"> </td>
4
+ <td class="cell">&nbsp;</td>
5
+ </tr>
6
+ <tr>
7
+ <td class="thanks cell" cellspan="2"><%=I18n.t("#{params[:template]}.thanks" , :order => @order)%> </td>
8
+ <td class="cell">&nbsp;</td>
9
+ </tr>
10
+ </table>
@@ -0,0 +1,18 @@
1
+ <% # Inside line_items table with 5 columns
2
+ sub = I18n.t(:subtotal)
3
+ totals = [ [ sub , number_to_currency(@order.item_total)]]
4
+ @order.adjustments.each do |charge|
5
+ totals << [ charge.label , number_to_currency(charge.amount) ] unless (charge.amount == 0 && @receipt)
6
+ end
7
+ totals << [ I18n.t(:order_total) , number_to_currency(@order.total) ]
8
+ totals = [] if @packaging_slip
9
+ %>
10
+
11
+ <table class="totals">
12
+ <% totals.each do |label , value| %>
13
+ <tr>
14
+ <td class="cel1 bold"> <%= label %>: </td>
15
+ <td class="cel2 cell" align="right"><%= value %> </td>
16
+ </tr>
17
+ <%end%>
18
+ </table>
@@ -0,0 +1,2 @@
1
+ <%== render :partial => "a4" %>
2
+
@@ -0,0 +1,3 @@
1
+ <% @packaging_slip = (params[:template] == "packaging_slip") %>
2
+
3
+ <%= render :partial => "a4" %>
@@ -0,0 +1,34 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
5
+ <%= stylesheet_link_tag "admin/html-receipt" , :media => "all" %>
6
+ <title><%= I18n.t("#{params[:template]}.header") %></title>
7
+ </head>
8
+
9
+ <body onLoad="self.print()">
10
+ <div class="receipt">
11
+ <div class="header">
12
+ <%= render :partial => "r_header" %>
13
+ </div>
14
+ <div class="info">
15
+ <%=I18n.l(@order.completed_at.to_date) if @order.completed_at %>&nbsp;/&nbsp;
16
+ kuitti <%=@order.number%> <!-- myyjä Minna --><br>
17
+ </div>
18
+ <div class="wrapper">
19
+ <div class="line_items">
20
+ <%= render :partial => "line_items" %>
21
+ </div>
22
+ <div class="spacer"> &nbsp;
23
+ </div>
24
+ <div class="totals">
25
+ <%= render :partial => "totals" %>
26
+ </div>
27
+ </div>
28
+ <div class="footer">
29
+ <%= render :partial => "r_footer" %>
30
+ </div>
31
+ </div>
32
+ </body>
33
+ </html>
34
+
@@ -0,0 +1,2 @@
1
+ <%= render :partial => "a4" %>
2
+
data/config/routes.rb ADDED
@@ -0,0 +1,11 @@
1
+ Spree::Core::Engine.routes.prepend do
2
+
3
+ namespace :admin do
4
+ resources :orders do
5
+ member do
6
+ get :invoice
7
+ end
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,18 @@
1
+ module HtmlInvoice
2
+ class Engine < Rails::Engine
3
+ engine_name 'spree_html_invoice'
4
+
5
+ def self.activate
6
+ Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator*.rb")) do |c|
7
+ Rails.application.config.cache_classes ? require(c) : load(c)
8
+ end
9
+ Dir.glob(File.join(File.dirname(__FILE__), "../app/overrides/**/*.rb")) do |c|
10
+ Rails.application.config.cache_classes ? require(c) : load(c)
11
+ end
12
+ end
13
+
14
+ config.to_prepare &method(:activate).to_proc
15
+
16
+ config.autoload_paths += %W(#{config.root}/lib)
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spree_html_invoice
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nicholas Watson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-01 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: spree_core
16
+ requirement: &70124241893420 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70124241893420
25
+ - !ruby/object:Gem::Dependency
26
+ name: spree_auth
27
+ requirement: &70124241924680 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70124241924680
36
+ description: HTML Invoice Template for spree
37
+ email: nick@entropi.co
38
+ executables: []
39
+ extensions: []
40
+ extra_rdoc_files: []
41
+ files:
42
+ - README.markdown
43
+ - lib/spree_html_invoice.rb
44
+ - app/assets/stylesheets/admin/html-invoice.css
45
+ - app/assets/stylesheets/admin/html-receipt.css
46
+ - app/controllers/admin/orders_controller_decorator.rb
47
+ - app/models/line_item_decorator.rb
48
+ - app/models/variant_decorator.rb
49
+ - app/overrides/add_html_invoice_to_admin.rb
50
+ - app/views/spree/admin/orders/_a4.html.erb
51
+ - app/views/spree/admin/orders/_address.html.erb
52
+ - app/views/spree/admin/orders/_footer.html.erb
53
+ - app/views/spree/admin/orders/_header.html.erb
54
+ - app/views/spree/admin/orders/_html_buttons.html.erb
55
+ - app/views/spree/admin/orders/_line_items.html.erb
56
+ - app/views/spree/admin/orders/_r_footer.html.erb
57
+ - app/views/spree/admin/orders/_r_header.html.erb
58
+ - app/views/spree/admin/orders/_thanks.html.erb
59
+ - app/views/spree/admin/orders/_totals.html.erb
60
+ - app/views/spree/admin/orders/invoice.html.erb
61
+ - app/views/spree/admin/orders/packaging_slip.html.erb
62
+ - app/views/spree/admin/orders/receipt.html.erb
63
+ - app/views/spree/admin/orders/reminder.html.erb
64
+ - config/routes.rb
65
+ homepage: http://github.com/entropillc/spree-html-invoice
66
+ licenses: []
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements:
84
+ - none
85
+ rubyforge_project:
86
+ rubygems_version: 1.8.17
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: HTML Invoice Template for spree
90
+ test_files: []