spree_invoice 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2012 [name of plugin creator]
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Spree nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ SpreeInvoice
2
+ =======
3
+ This gem provides model responsible for generating pdf from html file.
4
+
5
+
6
+ Basic Installation
7
+ ------------------
8
+
9
+ 1. Add the following to your Gemfile
10
+ <pre>
11
+ gem 'spree_invoice', '~> 1.1.0'
12
+ </pre>
13
+ 2. Run `bundle install`
14
+ 3. To copy and apply migrations run:
15
+ <pre>
16
+ rails g spree_invoice:install
17
+ </pre>
18
+
19
+
20
+ Configuration
21
+ -----
22
+
23
+ In file config/initializers/spree_invoice.rb please check your configuration for wkhtmltopdf bin path.
24
+ For more see: [wicked_pdf](https://github.com/mileszs/wicked_pdf)
25
+
26
+
27
+ Usage
28
+ -----
29
+
30
+ 1. Print Invoice directly
31
+ <pre>
32
+ Spree::Invoice.find_by_order_id('some id').try(:generate_pdf)
33
+ </pre>
34
+ 2. Print Invoice from order
35
+ <pre>
36
+ Order.last.invoice.generate_pdf
37
+ </pre>
38
+ 3. Print Invoice from User
39
+ <pre>
40
+ pdfs = []
41
+ User.last.invoices.each { |e| pdfs << e.generate_pdf }
42
+ </pre>
43
+
44
+ You can also check how many times invoice was generated - column: counter
45
+
46
+ Copyright (c) 2012 [Damiano Giacomello], released under the New BSD License
@@ -0,0 +1,23 @@
1
+ module Spree
2
+ class InvoiceController < Spree::BaseController
3
+
4
+ def show
5
+ order_id = params[:order_id].to_i
6
+ @order = Order.find_by_id(order_id)
7
+ @address = @order.bill_address
8
+ @invoice_print = current_user.has_role?(:admin) ? Spree::Invoice.find_or_create_by_order_id({:order_id => order_id, :user_id => @order ? @order.user_id : nil}) : current_user.invoices.find_or_create_by_order_id(order_id)
9
+ if @invoice_print
10
+ respond_to do |format|
11
+ format.pdf { send_data @invoice_print.generate_pdf, :filename => "#{@invoice_print.invoice_number}.pdf", :type => 'application/pdf' }
12
+ format.html { render :file => SpreeInvoice.invoice_template_path.to_s, :layout => false }
13
+ end
14
+ else
15
+ if current_user.has_role?(:admin)
16
+ return redirect_to(admin_orders_path, :notice => t(:no_such_order_found, :scope => :spree))
17
+ else
18
+ return redirect_to(orders_path, :alert => t(:no_such_order_found, :scope => :spree))
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ OrderMailer.class_eval do
3
+
4
+ def confirm_email(order, resend = false)
5
+ if SpreeInvoice.on_confirm_email && !SpreeInvoice.except_payment.include?(order.payment_method.type)
6
+ inv_print = Spree::Invoice.find_or_create_by_order_id({:order_id => order.id, :user_id => order.user_id})
7
+ attachments["#{inv_print.invoice_number}.pdf"] = {
8
+ :content => inv_print.generate_pdf,
9
+ :mime_type => 'application/pdf'
10
+ } if inv_print
11
+ end
12
+ @order = order
13
+ subject = (resend ? "[#{t(:resend).upcase}] " : "")
14
+ subject += "#{Config[:site_name]} #{t('order_mailer.confirm_email.subject')} ##{order.number}"
15
+ mail(:to => order.email, :subject => subject)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,42 @@
1
+ module Spree
2
+ class Invoice < ActiveRecord::Base
3
+ belongs_to :user
4
+ belongs_to :order
5
+
6
+ before_create :generate_invoice_number
7
+
8
+ scope :from_current_year, where(["created_at > ? AND created_at < ?", Time.now.at_beginning_of_year, Time.now.at_end_of_year])
9
+
10
+ attr_accessible :user, :order, :order_id, :user_id, :invoice_number, :counter
11
+
12
+ def generate_pdf
13
+ self.update_attribute(:counter, self.counter + 1)
14
+ WickedPdf.new.pdf_from_string(
15
+ StaticRender.render_erb(SpreeInvoice.invoice_template_path, {
16
+ :@order => self.order,
17
+ :@address => self.order.bill_address,
18
+ :@invoice_print => self
19
+ }), {
20
+ :margin => SpreeInvoice.wkhtmltopdf_margin
21
+ }
22
+ )
23
+ end
24
+
25
+ private
26
+ def generate_invoice_number
27
+ write_attribute(:invoice_number, SpreeInvoice.invoice_number_generation_method.call(Spree::Invoice.from_current_year.length + 1))
28
+ end
29
+ end
30
+
31
+ class StaticRender < ActionController::Base
32
+ def self.render_erb(template_path, locals = {})
33
+ view = ActionView::Base.new(ActionController::Base.view_paths, {})
34
+ class << view
35
+ include ApplicationHelper
36
+ include WickedPdfHelper::Assets
37
+ include Spree::BaseHelper
38
+ end
39
+ view.render(:file => template_path, :locals => locals, :layout => nil)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,11 @@
1
+ Spree::Order.class_eval do
2
+ has_one :invoice, :dependent => :destroy
3
+ after_update :add_invoice
4
+
5
+ private
6
+ def add_invoice
7
+ # Only create an invoice if the order is completed!
8
+ # And only create it if there is no invoice yet.
9
+ self.create_invoice(user: user) if self.completed? && self.invoice.blank?
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ Spree::User.class_eval do
2
+ has_many :invoice
3
+ end
@@ -0,0 +1,15 @@
1
+ # Admin Panel buttons
2
+ Deface::Override.new(:virtual_path => %q{spree/admin/orders/index},
3
+ :insert_after => "[data-hook='admin_orders_index_header_actions']",
4
+ :name => "invoice_print_header",
5
+ :text => "<th><%= t(:invoice, :scope => :spree) %></th>")
6
+
7
+ Deface::Override.new(:virtual_path => %q{spree/admin/orders/index},
8
+ :insert_after => "[data-hook='admin_orders_index_row_actions']",
9
+ :name => "invoice_print_link",
10
+ :text => %q{<td><%= link_to "#{image_tag('admin/icons/receipt.png')} #{t(:show, :scope => :spree)}".html_safe, pdf_invoice_path(:order_id => order.id, :format => :html), :onclick => "window.open(this.href, '#{t(:invoice, :scope => :spree)}', 'width=745,height=892,left=100,top=100,menubar=no,toolbar=yes,scrollbars=yes,location=no,hotkeys=yes'); return false;" %>&nbsp;<%= link_to "#{image_tag('admin/icons/pdf.png')} #{t(:download, :scope => :spree)}".html_safe, pdf_invoice_path(:order_id => order.id, :format => :pdf) %></td>})
11
+
12
+ Deface::Override.new(:virtual_path => %q{spree/admin/orders/show},
13
+ :insert_bottom => "[data-hook='admin_order_show_buttons']",
14
+ :name => "invoice_print_show_link",
15
+ :text => %q{<%= button_link_to t(:print_invoice, :scope => :spree), pdf_invoice_path(:order_id => @order.id, :format => :pdf), :icon => 'pdf' %>})
@@ -0,0 +1,10 @@
1
+ # User Show Account buttons
2
+ Deface::Override.new(:virtual_path => %q{spree/users/show},
3
+ :insert_after => "table.order-summary thead tr th:last",
4
+ :name => "invoice_print_user_header",
5
+ :text => "<th><%= t(:invoice, :scope => :spree) %></th>")
6
+
7
+ Deface::Override.new(:virtual_path => %q{spree/users/show},
8
+ :insert_after => "table.order-summary tbody tr td:last",
9
+ :name => "invoice_print_user_link",
10
+ :text => %q{<td><%= link_to t(:show, :scope => :spree), pdf_invoice_path(:order_id => order.id, :format => :html), :onclick => "window.open(this.href, '#{t(:invoice, :scope => :spree)}', 'width=745,height=892,left=100,top=100,menubar=no,toolbar=yes,scrollbars=yes,location=no,hotkeys=yes'); return false;" %><%= link_to t(:download, :scope => :spree), pdf_invoice_path(:order_id => order.id, :format => :pdf) %></td>})
@@ -0,0 +1,7 @@
1
+ en:
2
+ spree:
3
+ invoice: Invoice
4
+ show: show
5
+ download: PDF
6
+ print_invoice: Print Invoice
7
+ no_such_order_found: "No such order found."
@@ -0,0 +1,7 @@
1
+ it:
2
+ spree:
3
+ invoice: Fattura
4
+ show: visualizza
5
+ download: PDF
6
+ print_invoice: Stampa fattura
7
+ no_such_order_found: "Questo ordine non è stato trovato."
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ Spree::Core::Engine.routes.draw do
2
+ match '/invoice/show/:order_id' => 'invoice#show', :as => :pdf_invoice
3
+ end
@@ -0,0 +1,17 @@
1
+ class CreateInvoices < ActiveRecord::Migration
2
+ def up
3
+ create_table :spree_invoices do |t|
4
+ t.integer :counter, :default => 0
5
+ t.string :invoice_number
6
+
7
+ t.references :order, :user
8
+
9
+ t.timestamps
10
+ end
11
+ add_index :spree_invoice, :invoice_number
12
+ end
13
+
14
+ def down
15
+ drop_table :spree_invoice
16
+ end
17
+ end
@@ -0,0 +1,44 @@
1
+ module SpreeInvoice
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ source_root File.expand_path("../templates", __FILE__)
5
+ def self.source_root
6
+ @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
7
+ end
8
+
9
+ def add_migrations
10
+ run 'bundle exec rake railties:install:migrations FROM=spree_invoice'
11
+ end
12
+
13
+ def run_migrations
14
+ res = ask ">> Would you like to run the migrations now? [Y/n]"
15
+ if res == "" || res.downcase == "y"
16
+ run 'bundle exec rake db:migrate'
17
+ else
18
+ puts ">> Skiping rake db:migrate, don't forget to run it!"
19
+ end
20
+ end
21
+
22
+ def copy_templates_file
23
+ puts ">> Copy invoice template"
24
+ copy_file "invoice_template.html.erb", "app/views/spree/invoices/invoice_template.html.erb"
25
+ end
26
+
27
+ def copy_initializer_file
28
+ puts ">> Copy config file"
29
+ copy_file "initializer.rb", "config/initializers/spree_invoice.rb"
30
+ puts "\n>>> Don't forget to check your config file! <<<"
31
+ end
32
+
33
+ def generate_missing_records
34
+ res = ask ">> Would you like to run the generating missing orders now? [Y/n]"
35
+ if res == "" || res.downcase == "y"
36
+ puts ">> Generating missing records..."
37
+ run 'bundle exec rake spree_invoice:generate'
38
+ else
39
+ puts ">> Skiping rake spree_invoice:generate, don't forget to run it!"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,30 @@
1
+ require 'wicked_pdf'
2
+
3
+ WickedPdf.config = {
4
+ :exe_path => SpreeInvoice::WKHTMLToPDF.bin_path
5
+ }
6
+
7
+ SpreeInvoice.setup do |config|
8
+ config.on_confirm_email = true
9
+ config.invoice_number_generation_method = lambda { |next_invoice_count|
10
+ number = "%04d" % next_invoice_count.to_s
11
+ "R-#{Time.now.year}-#{number}"
12
+ }
13
+
14
+ config.invoice_template_path = "app/views/spree/invoices/invoice_template.html.erb"
15
+ config.except_payment = ['Spree::PaymentMethod::Check']
16
+ config.wkhtmltopdf_margin = {
17
+ :top => 10,
18
+ :bottom => 10,
19
+ :left => 15,
20
+ :right => 15
21
+ }
22
+ config.invoice_seller_details = %Q|
23
+ Spree Demo
24
+ P.IVA: 12345678901
25
+ C.F.: 12345678901
26
+ Street Address, 12
27
+ 00000 City (STATE)
28
+ |
29
+ config.invoice_seller_logo = Spree::Config[:admin_interface_logo]
30
+ end
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
7
+ </head>
8
+ <body>
9
+ <div id="wrapper">
10
+ <div id="header">
11
+ <%= wicked_pdf_image_tag(SpreeInvoice.invoice_seller_logo) %>
12
+ </div>
13
+ <div id="content">
14
+ <%= SpreeInvoice.invoice_seller_details %><br />
15
+ <%= @order.id %>
16
+ </div>
17
+ </div>
18
+ </body>
19
+ </html>
@@ -0,0 +1,29 @@
1
+ # move it to main file responsible for require
2
+ require File.join(File.dirname(__FILE__), 'wkhtmltopdf')
3
+
4
+ module SpreeInvoice
5
+ class Engine < Rails::Engine
6
+ require 'spree/core'
7
+ isolate_namespace Spree
8
+ engine_name 'spree_invoice'
9
+
10
+ config.autoload_paths += %W(#{config.root}/lib)
11
+
12
+ # use rspec for tests
13
+ config.generators do |g|
14
+ g.test_framework :rspec
15
+ end
16
+
17
+ def self.activate
18
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
19
+ Rails.configuration.cache_classes ? require(c) : load(c)
20
+ end
21
+
22
+ Dir.glob(File.join(File.dirname(__FILE__), "../../app/overrides/*.rb")) do |c|
23
+ Rails.application.config.cache_classes ? require(c) : load(c)
24
+ end
25
+ end
26
+
27
+ config.to_prepare &method(:activate).to_proc
28
+ end
29
+ end
@@ -0,0 +1,10 @@
1
+ require 'spree_invoice'
2
+ require 'rails'
3
+
4
+ module SpreeInvoice
5
+ class Railtie < Rails::Railtie
6
+ rake_tasks do
7
+ require '../tasks/spree_invoice.rake'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module SpreeInvoice
2
+ VERSION = "1.1.0"
3
+ end
@@ -0,0 +1,10 @@
1
+ module SpreeInvoice
2
+
3
+ module WKHTMLToPDF
4
+ def self.bin_path
5
+ bin_path = `which wkhtmltopdf`
6
+ raise LoadError, "WKHTMLtoPDF not found. Please install it first (http://code.google.com/p/wkhtmltopdf/)" if bin_path.empty?
7
+ bin_path.gsub(/\n/, '')
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,33 @@
1
+ require 'spree_core'
2
+ require 'spree_invoice/engine'
3
+
4
+ module SpreeInvoice
5
+ ## CONFIGURATION OPTIONS
6
+ mattr_accessor :on_confirm_email
7
+ @@on_confirm_email = true
8
+
9
+ mattr_accessor :invoice_seller_details
10
+ @@invoice_seller_details = nil
11
+
12
+ mattr_accessor :invoice_seller_logo
13
+ @@invoice_seller_logo = nil
14
+
15
+ mattr_accessor :invoice_template_path
16
+ @@invoice_template_path = "app/views/spree/invoices/invoice_template.html.erb"
17
+
18
+ mattr_accessor :except_payment
19
+ @@except_payment = ['Spree::PaymentMethod::Check']
20
+
21
+ mattr_accessor :wkhtmltopdf_margin
22
+ @@wkhtmltopdf_margin = {:top => 10, :bottom => 10, :left => 15, :right => 15}
23
+
24
+ mattr_accessor :invoice_number_generation_method
25
+ @@invoice_number_generation_method = lambda { |next_invoice_count|
26
+ number = "%04d" % next_invoice_count.to_s
27
+ "R-#{Time.now.year}-#{number}"
28
+ }
29
+
30
+ def self.setup
31
+ yield self
32
+ end
33
+ end
@@ -0,0 +1,14 @@
1
+ namespace :spree_invoice do
2
+ desc "Migrating and connecting Spree::Orders with InvoicePrints"
3
+ task :generate => :environment do
4
+ sum = Spree::Order.count
5
+ counter = 0
6
+ Spree::Order.all.each do |e|
7
+ e.send(:add_invoice)
8
+ counter += 1
9
+ print "\r#{counter}/#{sum}"
10
+ end
11
+
12
+ print "\nDone.\n"
13
+ end
14
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spree_invoice
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Damiano Giacomello
9
+ - Peter Gębala
10
+ - Thomas von Deyen
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2012-11-06 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: spree_core
18
+ requirement: !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ! '>='
22
+ - !ruby/object:Gem::Version
23
+ version: '0'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ! '>='
30
+ - !ruby/object:Gem::Version
31
+ version: '0'
32
+ - !ruby/object:Gem::Dependency
33
+ name: wicked_pdf
34
+ requirement: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec-rails
50
+ requirement: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ description: This gem provides invoice pdf generation from a html template via wkhtmltopdf.
65
+ email:
66
+ - damiano.giacomello@diginess.it
67
+ executables: []
68
+ extensions: []
69
+ extra_rdoc_files: []
70
+ files:
71
+ - README.md
72
+ - LICENSE
73
+ - lib/generators/spree_invoice/install/install_generator.rb
74
+ - lib/generators/spree_invoice/install/templates/initializer.rb
75
+ - lib/generators/spree_invoice/install/templates/invoice_template.html.erb
76
+ - lib/spree_invoice/engine.rb
77
+ - lib/spree_invoice/railtie.rb
78
+ - lib/spree_invoice/version.rb
79
+ - lib/spree_invoice/wkhtmltopdf.rb
80
+ - lib/spree_invoice.rb
81
+ - lib/tasks/spree_invoice.rake
82
+ - app/assets/images/admin/icons/receipt.png
83
+ - app/controllers/spree/invoice_controller.rb
84
+ - app/mailers/spree/order_mailer_decorator.rb
85
+ - app/models/spree/invoice.rb
86
+ - app/models/spree/order_decorator.rb
87
+ - app/models/spree/user_decorator.rb
88
+ - app/overrides/add_button_to_admin_panel.rb
89
+ - app/overrides/add_button_to_customer_panel.rb
90
+ - db/migrate/20120207124038_create_invoices.rb
91
+ - config/locales/en.yml
92
+ - config/locales/it.yml
93
+ - config/routes.rb
94
+ homepage: https://github.com/damianogiacomello/spree_invoice_generator
95
+ licenses: []
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: 1.8.7
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements:
113
+ - wkhtmltopdf
114
+ rubyforge_project:
115
+ rubygems_version: 1.8.22
116
+ signing_key:
117
+ specification_version: 3
118
+ summary: Spree invoice PDF generation extension.
119
+ test_files: []