polish_invoicer 0.0.5 → 0.0.6
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +3 -2
- data/LICENSE.txt +1 -1
- data/README.md +6 -5
- data/Rakefile +4 -4
- data/doc/invoice.rb +2 -3
- data/doc/proforma.rb +2 -3
- data/lib/polish_invoicer/invoice.rb +21 -20
- data/lib/polish_invoicer/presenter.rb +31 -31
- data/lib/polish_invoicer/validator.rb +63 -87
- data/lib/polish_invoicer/vat.rb +11 -10
- data/lib/polish_invoicer/version.rb +1 -1
- data/lib/polish_invoicer/writer.rb +11 -10
- data/lib/polish_invoicer.rb +7 -11
- data/polish_invoicer.gemspec +14 -13
- data/test/invoice_test.rb +9 -10
- data/test/presenter_test.rb +3 -4
- data/test/test_generator.rb +4 -3
- data/test/test_helper.rb +2 -2
- data/test/validator_test.rb +12 -33
- data/test/vat_test.rb +1 -1
- data/test/writer_test.rb +3 -4
- data/tpl/invoice.slim +5 -1
- metadata +39 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 312fe8f98e08534aee77cd955333f5ef46d71254
|
4
|
+
data.tar.gz: 4b95737c8385e6443fd496367fd4a8504cd99b75
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ec09c10060ec883d524c1504f433ec3dfcbfbfe8a46e17ef4d8e8a9fdad515e0d62582ad130539de30fe779809792d148724e246ce43d2a2158a0815baa1a5c
|
7
|
+
data.tar.gz: 6d04f34ebf85cdc467f49b3541bd98baaa8fb220430c697830b507c412f2f1292f96e3d9ea4e1281458bdb4591e36ec8e416b6fefebfc02d0ee3a860965fc5fe
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -3,9 +3,9 @@
|
|
3
3
|
PolishInvoicer gem creates polish invoices and proforms as HTML or PDF files.
|
4
4
|
Gem description will be in polish language because of specific case of this gem.
|
5
5
|
|
6
|
-
Gem jest zgodny z nową [ustawą o podatku VAT](http://www.przepisy.gofin.pl/przepisy,
|
6
|
+
Gem jest zgodny z nową [ustawą o podatku VAT](http://www.przepisy.gofin.pl/przepisy,2,32,32,670,,,ustawa-z-dnia-11032004-r-o-podatku-od-towarow-i-uslug.html), która weszła w życie z dniem 1 stycznia 2017.
|
7
7
|
|
8
|
-
[Krótkie podsumowanie zmian w wystawianiu faktur](
|
8
|
+
[Krótkie podsumowanie zmian w wystawianiu faktur](https://www.jzk.pl/2017).
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
@@ -28,7 +28,7 @@ Or install it yourself as:
|
|
28
28
|
```ruby
|
29
29
|
require 'polish_invoicer'
|
30
30
|
|
31
|
-
invoice = PolishInvoicer::Invoice.new(
|
31
|
+
invoice = PolishInvoicer::Invoice.new(
|
32
32
|
number: '1/2014', # numer faktury
|
33
33
|
create_date: Date.today, # data wystawienia
|
34
34
|
trade_date: Date.today, # data wykonania usługi
|
@@ -45,7 +45,7 @@ invoice = PolishInvoicer::Invoice.new({
|
|
45
45
|
payment_date: Date.today + 14, # data płatności
|
46
46
|
proforma: true, # znacznik proformy
|
47
47
|
paid: false, # znacznik opłacenia usługi
|
48
|
-
|
48
|
+
)
|
49
49
|
if invoice.valid?
|
50
50
|
invoice.save_to_html('/path/to/proforma.html')
|
51
51
|
invoice.save_to_pdf('/path/to/proforma.pdf')
|
@@ -98,6 +98,7 @@ invoice.save_to_pdf('/path/to/invoice.pdf')
|
|
98
98
|
### Parametry dodatkowe
|
99
99
|
|
100
100
|
:buyer_nip, # NIP nabywcy (string)
|
101
|
+
:recipient, # odbiorca faktury (tablica stringów)
|
101
102
|
:comments, # uwagi (string lub tablica stringów)
|
102
103
|
:pkwiu, # numer PKWiU (string)
|
103
104
|
:no_vat_reason, # podstawa prawna zwolnienia z VAT (string)
|
@@ -128,7 +129,7 @@ puts invoice.errors.inspect
|
|
128
129
|
{
|
129
130
|
:vat=>"Stawka VAT spoza listy dopuszczalnych wartości",
|
130
131
|
:create_date=>"Data wystawienia nie może być późniejsza niż 15 dzień następnego miesiąca po wykonaniu usługi"
|
131
|
-
|
132
|
+
}
|
132
133
|
|
133
134
|
## Dodatkowe metody
|
134
135
|
|
data/Rakefile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
3
|
|
4
4
|
Rake::TestTask.new(:test) do |t|
|
5
|
-
t.libs <<
|
5
|
+
t.libs << 'test'
|
6
6
|
t.test_files = FileList['test/*_test.rb']
|
7
7
|
end
|
8
8
|
|
9
|
-
task :
|
9
|
+
task default: :test
|
data/doc/invoice.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
require 'polish_invoicer'
|
3
2
|
|
4
|
-
invoice = PolishInvoicer::Invoice.new(
|
3
|
+
invoice = PolishInvoicer::Invoice.new(
|
5
4
|
number: '1/2014', # numer faktury
|
6
5
|
create_date: Date.today, # data wystawienia
|
7
6
|
trade_date: Date.today, # data wykonania usługi
|
@@ -16,6 +15,6 @@ invoice = PolishInvoicer::Invoice.new({
|
|
16
15
|
item_name: 'Usługi programistyczne', # nazwa usługi
|
17
16
|
price: 3500, # cena (domyślnie brutto)
|
18
17
|
payment_date: Date.today + 14, # data płatności
|
19
|
-
|
18
|
+
)
|
20
19
|
invoice.save_to_html('/tmp/invoice.html')
|
21
20
|
invoice.save_to_pdf('/tmp/invoice.pdf')
|
data/doc/proforma.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
require 'polish_invoicer'
|
3
2
|
|
4
|
-
invoice = PolishInvoicer::Invoice.new(
|
3
|
+
invoice = PolishInvoicer::Invoice.new(
|
5
4
|
number: '1/2014/PROFORMA', # numer faktury
|
6
5
|
create_date: Date.today, # data wystawienia
|
7
6
|
trade_date: Date.today, # data wykonania usługi
|
@@ -18,6 +17,6 @@ invoice = PolishInvoicer::Invoice.new({
|
|
18
17
|
payment_date: Date.today + 14, # data płatności
|
19
18
|
proforma: true,
|
20
19
|
paid: false
|
21
|
-
|
20
|
+
)
|
22
21
|
invoice.save_to_html('/tmp/proforma.html')
|
23
22
|
invoice.save_to_pdf('/tmp/proforma.pdf')
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
module PolishInvoicer
|
3
2
|
class Invoice
|
4
3
|
AVAILABLE_PARAMS = [
|
@@ -9,6 +8,7 @@ module PolishInvoicer
|
|
9
8
|
:seller_nip, # NIP sprzedawcy (string)
|
10
9
|
:buyer, # adres nabywcy (tablica stringów)
|
11
10
|
:buyer_nip, # NIP nabywcy (string)
|
11
|
+
:recipient, # odbiorca faktury (tablica stringów)
|
12
12
|
:item_name, # nazwa usługi (string)
|
13
13
|
:price, # cena w złotych (float)
|
14
14
|
:gross_price, # znacznik rodzaju ceny (netto/brutto), domyślnie: true (boolean)
|
@@ -21,19 +21,19 @@ module PolishInvoicer
|
|
21
21
|
:footer, # treść umieszczana w stopce faktury (string)
|
22
22
|
:proforma, # znacznik faktury pro-forma, domyślnie: false (boolean)
|
23
23
|
:no_vat_reason, # podstawa prawna zwolnienia z VAT (string)
|
24
|
-
]
|
24
|
+
].freeze
|
25
25
|
|
26
|
-
attr_accessor
|
26
|
+
attr_accessor(*AVAILABLE_PARAMS)
|
27
27
|
attr_accessor :template_path
|
28
28
|
attr_accessor :logger, :wkhtmltopdf_path, :wkhtmltopdf_command
|
29
29
|
|
30
|
-
def initialize(params={})
|
30
|
+
def initialize(params = {})
|
31
31
|
set_defaults
|
32
32
|
params.each do |k, v|
|
33
33
|
raise "Nierozpoznany parametr #{k}" unless AVAILABLE_PARAMS.include?(k)
|
34
34
|
send("#{k}=", v)
|
35
35
|
end
|
36
|
-
@validator = Validator.new(self)
|
36
|
+
@validator = PolishInvoicer::Validator.new(self)
|
37
37
|
end
|
38
38
|
|
39
39
|
def errors
|
@@ -47,7 +47,7 @@ module PolishInvoicer
|
|
47
47
|
# cena/wartość netto
|
48
48
|
def net_value
|
49
49
|
return price unless gross_price
|
50
|
-
price / (1 + Vat.to_i(vat)/100.0)
|
50
|
+
price / (1 + Vat.to_i(vat) / 100.0)
|
51
51
|
end
|
52
52
|
|
53
53
|
# kwota VAT
|
@@ -58,7 +58,7 @@ module PolishInvoicer
|
|
58
58
|
# cena/wartość brutto
|
59
59
|
def gross_value
|
60
60
|
return price if gross_price
|
61
|
-
price + price * Vat.to_i(vat)/100.0
|
61
|
+
price + price * Vat.to_i(vat) / 100.0
|
62
62
|
end
|
63
63
|
|
64
64
|
def save_to_html(path)
|
@@ -76,19 +76,20 @@ module PolishInvoicer
|
|
76
76
|
Presenter.new(self).data
|
77
77
|
end
|
78
78
|
|
79
|
-
|
80
|
-
def set_defaults
|
81
|
-
@gross_price = true
|
82
|
-
@vat = 23
|
83
|
-
@payment_type = 'Przelew'
|
84
|
-
@paid = true
|
85
|
-
@proforma = false
|
86
|
-
end
|
79
|
+
private
|
87
80
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
81
|
+
def set_defaults
|
82
|
+
@gross_price = true
|
83
|
+
@vat = 23
|
84
|
+
@payment_type = 'Przelew'
|
85
|
+
@paid = true
|
86
|
+
@proforma = false
|
87
|
+
end
|
88
|
+
|
89
|
+
def validate!
|
90
|
+
return if valid?
|
91
|
+
error_messages = errors.map { |k, v| "#{k}: #{v}" }.join(', ')
|
92
|
+
raise "Parametry do wystawienia faktury są nieprawidłowe: #{error_messages}"
|
93
|
+
end
|
93
94
|
end
|
94
95
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
module PolishInvoicer
|
3
2
|
class Presenter
|
4
3
|
attr_accessor :invoice
|
@@ -19,45 +18,46 @@ module PolishInvoicer
|
|
19
18
|
@out
|
20
19
|
end
|
21
20
|
|
22
|
-
|
23
|
-
def copy_available_params
|
24
|
-
Invoice::AVAILABLE_PARAMS.each do |field|
|
25
|
-
@out[field] = @invoice.send(field)
|
26
|
-
end
|
27
|
-
end
|
21
|
+
private
|
28
22
|
|
29
|
-
|
30
|
-
|
23
|
+
def copy_available_params
|
24
|
+
Invoice::AVAILABLE_PARAMS.each do |field|
|
25
|
+
@out[field] = @invoice.send(field)
|
31
26
|
end
|
27
|
+
end
|
32
28
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
37
|
-
end
|
29
|
+
def remove_redundand_params
|
30
|
+
@out.delete(:price)
|
31
|
+
end
|
38
32
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
next unless v
|
43
|
-
@out[field.to_sym] = v.strftime "%d.%m.%Y"
|
44
|
-
end
|
33
|
+
def copy_additional_params
|
34
|
+
%w(net_value vat_value gross_value).each do |field|
|
35
|
+
@out[field.to_sym] = @invoice.send(field)
|
45
36
|
end
|
37
|
+
end
|
46
38
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
39
|
+
def format_dates
|
40
|
+
%w(trade_date create_date payment_date).each do |field|
|
41
|
+
v = @invoice.send(field)
|
42
|
+
next unless v
|
43
|
+
@out[field.to_sym] = v.strftime '%d.%m.%Y'
|
53
44
|
end
|
45
|
+
end
|
54
46
|
|
55
|
-
|
56
|
-
|
47
|
+
def format_prices
|
48
|
+
%w(net_value vat_value gross_value).each do |field|
|
49
|
+
v = @invoice.send(field)
|
50
|
+
next unless v
|
51
|
+
@out[field.to_sym] = sprintf('%02.2f', v).tr('.', ',')
|
57
52
|
end
|
53
|
+
end
|
58
54
|
|
59
|
-
|
60
|
-
|
61
|
-
|
55
|
+
def format_comments
|
56
|
+
@out[:comments] = [@invoice.comments].flatten.compact
|
57
|
+
end
|
58
|
+
|
59
|
+
def format_vat
|
60
|
+
@out[:vat] = Vat.to_s(@invoice.vat)
|
61
|
+
end
|
62
62
|
end
|
63
63
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
module PolishInvoicer
|
3
2
|
class Validator
|
4
3
|
attr_reader :errors
|
@@ -18,107 +17,84 @@ module PolishInvoicer
|
|
18
17
|
check_price
|
19
18
|
check_vat
|
20
19
|
check_proforma
|
21
|
-
check_create_and_trade_date_correlation
|
22
20
|
@errors.empty?
|
23
21
|
end
|
24
22
|
|
25
|
-
|
26
|
-
def check_presence
|
27
|
-
check_blank(:number, 'Numer nie może być pusty')
|
28
|
-
check_blank(:create_date, 'Data wystawienia nie może być pusta')
|
29
|
-
check_blank(:trade_date, 'Data sprzedaży nie może być pusta')
|
30
|
-
check_blank(:seller, 'Sprzedawca nie może być pusty')
|
31
|
-
check_blank(:buyer, 'Nabywca nie może być pusty')
|
32
|
-
check_blank(:item_name, 'Nazwa usługi nie może być pusta')
|
33
|
-
check_blank(:price, 'Cena nie może być pusta')
|
34
|
-
check_blank(:vat, 'Stawka VAT nie może być pusta')
|
35
|
-
check_blank(:payment_type, 'Rodzaj płatności nie może być pusty')
|
36
|
-
check_blank(:payment_date, 'Termin płatności nie może być pusty')
|
37
|
-
check_blank(:seller_nip, 'NIP sprzedawcy nie może być pusty')
|
38
|
-
end
|
39
|
-
|
40
|
-
def check_not_nil
|
41
|
-
@errors[:gross_price] = 'Konieczne jest ustawienie znacznika rodzaju ceny (netto/brutto)' if @invoice.gross_price.nil?
|
42
|
-
@errors[:paid] = 'Konieczne jest ustawienie znacznika opłacenia faktury' if @invoice.paid.nil?
|
43
|
-
end
|
23
|
+
private
|
44
24
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
25
|
+
def check_presence
|
26
|
+
check_blank(:number, 'Numer nie może być pusty')
|
27
|
+
check_blank(:create_date, 'Data wystawienia nie może być pusta')
|
28
|
+
check_blank(:trade_date, 'Data sprzedaży nie może być pusta')
|
29
|
+
check_blank(:seller, 'Sprzedawca nie może być pusty')
|
30
|
+
check_blank(:buyer, 'Nabywca nie może być pusty')
|
31
|
+
check_blank(:item_name, 'Nazwa usługi nie może być pusta')
|
32
|
+
check_blank(:price, 'Cena nie może być pusta')
|
33
|
+
check_blank(:vat, 'Stawka VAT nie może być pusta')
|
34
|
+
check_blank(:payment_type, 'Rodzaj płatności nie może być pusty')
|
35
|
+
check_blank(:payment_date, 'Termin płatności nie może być pusty')
|
36
|
+
check_blank(:seller_nip, 'NIP sprzedawcy nie może być pusty')
|
37
|
+
end
|
49
38
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
unless [true, false].include?(@invoice.paid)
|
55
|
-
@errors[:paid] = 'Znacznik opłacenia faktury musi być podany jako boolean'
|
56
|
-
end
|
57
|
-
unless [true, false].include?(@invoice.proforma)
|
58
|
-
@errors[:proforma] = 'Znacznik faktury pro-forma musi być podany jako boolean'
|
59
|
-
end
|
60
|
-
end
|
39
|
+
def check_not_nil
|
40
|
+
@errors[:gross_price] = 'Konieczne jest ustawienie znacznika rodzaju ceny (netto/brutto)' if @invoice.gross_price.nil?
|
41
|
+
@errors[:paid] = 'Konieczne jest ustawienie znacznika opłacenia faktury' if @invoice.paid.nil?
|
42
|
+
end
|
61
43
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
44
|
+
def check_arrays
|
45
|
+
@errors[:seller] = 'Sprzedawca musi być podany jako tablica stringów' unless @invoice.seller.is_a?(Array)
|
46
|
+
@errors[:buyer] = 'Nabywca musi być podany jako tablica stringów' unless @invoice.buyer.is_a?(Array)
|
47
|
+
end
|
67
48
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
else
|
72
|
-
@errors[:price] = 'Cena musi być liczbą dodatnią' unless @invoice.price > 0
|
73
|
-
end
|
49
|
+
def check_booleans
|
50
|
+
unless [true, false].include?(@invoice.gross_price)
|
51
|
+
@errors[:gross_price] = 'Znacznik rodzaju ceny musi być podany jako boolean'
|
74
52
|
end
|
75
|
-
|
76
|
-
|
77
|
-
unless Vat.valid?(@invoice.vat)
|
78
|
-
@errors[:vat] = 'Stawka VAT spoza listy dopuszczalnych wartości'
|
79
|
-
else
|
80
|
-
if Vat.zw?(@invoice.vat) and blank?(@invoice.no_vat_reason)
|
81
|
-
@errors[:no_vat_reason] = 'Konieczne jest podanie podstawy prawnej zwolnienia z podatku VAT'
|
82
|
-
end
|
83
|
-
end
|
53
|
+
unless [true, false].include?(@invoice.paid)
|
54
|
+
@errors[:paid] = 'Znacznik opłacenia faktury musi być podany jako boolean'
|
84
55
|
end
|
85
|
-
|
86
|
-
|
87
|
-
return unless @invoice.proforma
|
88
|
-
return unless @invoice.paid
|
89
|
-
@errors[:paid] = 'Proforma nie może być opłacona'
|
56
|
+
unless [true, false].include?(@invoice.proforma)
|
57
|
+
@errors[:proforma] = 'Znacznik faktury pro-forma musi być podany jako boolean'
|
90
58
|
end
|
59
|
+
end
|
91
60
|
|
92
|
-
|
93
|
-
|
94
|
-
|
61
|
+
def check_dates
|
62
|
+
@errors[:create_date] = 'Data wystawienia musi być typu Date' unless @invoice.create_date.is_a?(Date)
|
63
|
+
@errors[:trade_date] = 'Data sprzedaży musi być typu Date' unless @invoice.trade_date.is_a?(Date)
|
64
|
+
@errors[:payment_date] = 'Termin płatności musi być typu Date' unless @invoice.payment_date.is_a?(Date)
|
65
|
+
end
|
95
66
|
|
96
|
-
|
97
|
-
|
98
|
-
@errors[
|
67
|
+
def check_price
|
68
|
+
unless @invoice.price.is_a?(Numeric)
|
69
|
+
@errors[:price] = 'Cena musi być liczbą'
|
70
|
+
else
|
71
|
+
@errors[:price] = 'Cena musi być liczbą dodatnią' unless @invoice.price > 0
|
99
72
|
end
|
73
|
+
end
|
100
74
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
if cd < td and (td - cd > 30)
|
108
|
-
msg = 'Data wystawienia nie może być wcześniejsza niż ' +
|
109
|
-
'30 dni przed wykonaniem usługi'
|
110
|
-
@errors[:create_date] = msg
|
111
|
-
end
|
112
|
-
# data wystawienie max 15 dnia następnego miesiąca po wykonaniu usługi
|
113
|
-
if cd > td
|
114
|
-
td_nm = td.next_month
|
115
|
-
cd_dl = Date.new(td_nm.year, td_nm.month, 15)
|
116
|
-
if cd > cd_dl
|
117
|
-
msg = 'Data wystawienia nie może być późniejsza niż ' +
|
118
|
-
'15 dzień następnego miesiąca po wykonaniu usługi'
|
119
|
-
@errors[:create_date] = msg
|
120
|
-
end
|
75
|
+
def check_vat
|
76
|
+
unless Vat.valid?(@invoice.vat)
|
77
|
+
@errors[:vat] = 'Stawka VAT spoza listy dopuszczalnych wartości'
|
78
|
+
else
|
79
|
+
if Vat.zw?(@invoice.vat) && blank?(@invoice.no_vat_reason)
|
80
|
+
@errors[:no_vat_reason] = 'Konieczne jest podanie podstawy prawnej zwolnienia z podatku VAT'
|
121
81
|
end
|
122
82
|
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def check_proforma
|
86
|
+
return unless @invoice.proforma
|
87
|
+
return unless @invoice.paid
|
88
|
+
@errors[:paid] = 'Proforma nie może być opłacona'
|
89
|
+
end
|
90
|
+
|
91
|
+
def blank?(value)
|
92
|
+
value.to_s.strip == ''
|
93
|
+
end
|
94
|
+
|
95
|
+
def check_blank(key, msg)
|
96
|
+
value = @invoice.send(key)
|
97
|
+
@errors[key] = msg if blank?(value)
|
98
|
+
end
|
123
99
|
end
|
124
100
|
end
|
data/lib/polish_invoicer/vat.rb
CHANGED
@@ -19,18 +19,19 @@ module PolishInvoicer
|
|
19
19
|
|
20
20
|
# Potrzebne do obliczeń netto/vat/brutto
|
21
21
|
def self.to_i(rate)
|
22
|
-
|
22
|
+
rate != -1 ? rate : 0
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
h
|
25
|
+
private
|
26
|
+
|
27
|
+
def self.hash
|
28
|
+
h = {}
|
29
|
+
rates.each do |r|
|
30
|
+
name = "#{r}%"
|
31
|
+
name = 'zw.' if r == -1
|
32
|
+
h[name] = r
|
34
33
|
end
|
34
|
+
h
|
35
|
+
end
|
35
36
|
end
|
36
37
|
end
|
@@ -22,15 +22,16 @@ module PolishInvoicer
|
|
22
22
|
@writer.save_to_pdf(path)
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
25
|
+
private
|
26
|
+
|
27
|
+
def create_writer
|
28
|
+
@writer = Slim2pdf::Writer.new(template_path)
|
29
|
+
@writer.wkhtmltopdf_path = wkhtmltopdf_path
|
30
|
+
@writer.wkhtmltopdf_command = wkhtmltopdf_command
|
31
|
+
@writer.logger = logger
|
32
|
+
data = @invoice.to_hash
|
33
|
+
@writer.data = data
|
34
|
+
@writer.footer_text = data[:footer]
|
35
|
+
end
|
35
36
|
end
|
36
37
|
end
|
data/lib/polish_invoicer.rb
CHANGED
@@ -1,14 +1,10 @@
|
|
1
|
-
require
|
1
|
+
require 'date'
|
2
2
|
require 'pathname'
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
4
|
+
require 'polish_invoicer/version'
|
5
|
+
require 'polish_invoicer/vat'
|
6
|
+
require 'polish_invoicer/validator'
|
7
7
|
require 'slim2pdf'
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
|
12
|
-
module PolishInvoicer
|
13
|
-
# Your code goes here...
|
14
|
-
end
|
8
|
+
require 'polish_invoicer/writer'
|
9
|
+
require 'polish_invoicer/presenter'
|
10
|
+
require 'polish_invoicer/invoice'
|
data/polish_invoicer.gemspec
CHANGED
@@ -1,26 +1,27 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
lib = File.expand_path('../lib', __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require 'polish_invoicer/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
6
|
+
spec.name = 'polish_invoicer'
|
8
7
|
spec.version = PolishInvoicer::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.description =
|
12
|
-
spec.summary =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
8
|
+
spec.authors = ['Piotr Macuk']
|
9
|
+
spec.email = ['piotr@macuk.pl']
|
10
|
+
spec.description = 'Creates polish invoices and proforms as HTML or PDF files'
|
11
|
+
spec.summary = 'Creates polish invoices and proforms as HTML or PDF files'
|
12
|
+
spec.homepage = ''
|
13
|
+
spec.license = 'MIT'
|
15
14
|
|
16
15
|
spec.files = `git ls-files`.split($/)
|
17
16
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
18
|
+
spec.require_paths = ['lib']
|
20
19
|
|
21
|
-
spec.add_development_dependency
|
22
|
-
spec.add_development_dependency
|
23
|
-
spec.add_development_dependency
|
20
|
+
spec.add_development_dependency 'bundler'
|
21
|
+
spec.add_development_dependency 'rake'
|
22
|
+
spec.add_development_dependency 'minitest'
|
23
|
+
spec.add_development_dependency 'simplecov'
|
24
|
+
spec.add_development_dependency 'rubocop'
|
24
25
|
|
25
|
-
spec.add_dependency 'slim2pdf'
|
26
|
+
spec.add_dependency 'slim2pdf'
|
26
27
|
end
|
data/test/invoice_test.rb
CHANGED
@@ -1,20 +1,19 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
require 'test_helper'
|
3
2
|
|
4
3
|
module PolishInvoicer
|
5
|
-
class InvoiceTest <
|
4
|
+
class InvoiceTest < Minitest::Test
|
6
5
|
def test_init
|
7
6
|
i = Invoice.new
|
8
7
|
assert i.is_a?(Invoice)
|
9
8
|
end
|
10
9
|
|
11
10
|
def test_set_available_param
|
12
|
-
i = Invoice.new(
|
11
|
+
i = Invoice.new(number: '1/2014')
|
13
12
|
assert_equal '1/2014', i.number
|
14
13
|
end
|
15
14
|
|
16
15
|
def test_set_unavailable_param
|
17
|
-
assert_raises(RuntimeError) {
|
16
|
+
assert_raises(RuntimeError) { Invoice.new(test: 'abc') }
|
18
17
|
end
|
19
18
|
|
20
19
|
def test_validation_delegation
|
@@ -27,7 +26,7 @@ module PolishInvoicer
|
|
27
26
|
end
|
28
27
|
|
29
28
|
def test_net_value
|
30
|
-
i = Invoice.new(
|
29
|
+
i = Invoice.new(price: 123.45, gross_price: false, vat: 23)
|
31
30
|
assert_in_delta 123.45, i.net_value, 0.01
|
32
31
|
i.gross_price = true
|
33
32
|
assert_in_delta 100.37, i.net_value, 0.01
|
@@ -43,7 +42,7 @@ module PolishInvoicer
|
|
43
42
|
end
|
44
43
|
|
45
44
|
def test_vat_value
|
46
|
-
i = Invoice.new(
|
45
|
+
i = Invoice.new(price: 123.45, gross_price: false, vat: 23)
|
47
46
|
assert_in_delta 28.39, i.vat_value, 0.01
|
48
47
|
i.gross_price = true
|
49
48
|
assert_in_delta 23.08, i.vat_value, 0.01
|
@@ -54,7 +53,7 @@ module PolishInvoicer
|
|
54
53
|
end
|
55
54
|
|
56
55
|
def test_gross_value
|
57
|
-
i = Invoice.new(
|
56
|
+
i = Invoice.new(price: 123.45, gross_price: false, vat: 23)
|
58
57
|
assert_in_delta 151.84, i.gross_value, 0.01
|
59
58
|
i.gross_price = true
|
60
59
|
assert_in_delta 123.45, i.gross_value, 0.01
|
@@ -92,7 +91,7 @@ module PolishInvoicer
|
|
92
91
|
i = create_valid_invoice
|
93
92
|
path = '/tmp/test.html'
|
94
93
|
i.save_to_html(path)
|
95
|
-
assert File.
|
94
|
+
assert File.exist?(path)
|
96
95
|
File.unlink(path)
|
97
96
|
end
|
98
97
|
|
@@ -100,12 +99,12 @@ module PolishInvoicer
|
|
100
99
|
i = create_valid_invoice
|
101
100
|
path = '/tmp/test.pdf'
|
102
101
|
i.save_to_pdf(path)
|
103
|
-
assert File.
|
102
|
+
assert File.exist?(path)
|
104
103
|
File.unlink(path)
|
105
104
|
end
|
106
105
|
|
107
106
|
def test_to_hash
|
108
|
-
i = Invoice.new(
|
107
|
+
i = Invoice.new(price: 123.45, gross_price: false)
|
109
108
|
h = i.to_hash
|
110
109
|
assert h[:paid] # default
|
111
110
|
assert_equal false, h[:gross_price] # params
|
data/test/presenter_test.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
require 'test_helper'
|
3
2
|
|
4
3
|
module PolishInvoicer
|
5
|
-
class PresenterTest <
|
4
|
+
class PresenterTest < Minitest::Test
|
6
5
|
require 'ostruct'
|
7
6
|
|
8
7
|
def setup
|
@@ -36,9 +35,9 @@ module PolishInvoicer
|
|
36
35
|
@invoice.comments = 'Test'
|
37
36
|
data = Presenter.new(@invoice).data
|
38
37
|
assert_equal ['Test'], data[:comments]
|
39
|
-
@invoice.comments =
|
38
|
+
@invoice.comments = %w(A B)
|
40
39
|
data = Presenter.new(@invoice).data
|
41
|
-
assert_equal
|
40
|
+
assert_equal %w(A B), data[:comments]
|
42
41
|
end
|
43
42
|
|
44
43
|
def test_vat
|
data/test/test_generator.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
require 'polish_invoicer'
|
3
2
|
|
4
|
-
i = PolishInvoicer::Invoice.new(
|
3
|
+
i = PolishInvoicer::Invoice.new(
|
5
4
|
number: '1/2014', create_date: Date.today, trade_date: Date.today,
|
6
5
|
seller: ['Abaka sp. z o.o.', 'ul. Jasna 10', '10-234 Kraków'],
|
7
6
|
buyer: ['Fabryki słodyczy S.A.', 'ul. Słodka 12/34', '12-345 Warszawa'],
|
@@ -9,9 +8,11 @@ i = PolishInvoicer::Invoice.new({
|
|
9
8
|
price: 123.45, payment_date: Date.today,
|
10
9
|
comments: 'Test uwag', footer: 'Stopka faktury plus tekst promocyjny',
|
11
10
|
seller_nip: '123-456-78-90', buyer_nip: '987-654-32-10'
|
12
|
-
|
11
|
+
)
|
13
12
|
|
14
13
|
i.save_to_pdf('/tmp/invoice-default.pdf')
|
14
|
+
i.recipient = ['Szkoła Podstawowa Nr 1', 'ul. Zielona 10', '81-222 Gdynia', 'Nr ewid: SP1/2017']
|
15
|
+
i.save_to_pdf('/tmp/invoice-with-recipient.pdf')
|
15
16
|
i.paid = false
|
16
17
|
i.save_to_pdf('/tmp/invoice-not-paid.pdf')
|
17
18
|
i.proforma = true
|
data/test/test_helper.rb
CHANGED
@@ -8,12 +8,12 @@ require 'polish_invoicer'
|
|
8
8
|
require 'minitest/autorun'
|
9
9
|
|
10
10
|
def create_valid_invoice
|
11
|
-
invoice = PolishInvoicer::Invoice.new(
|
11
|
+
invoice = PolishInvoicer::Invoice.new(
|
12
12
|
number: '1/2014', create_date: Date.today, trade_date: Date.today,
|
13
13
|
seller: ['Seller'], buyer: ['Buyer'],
|
14
14
|
seller_nip: '123-123-22-33', buyer_nip: '554-333-22-11',
|
15
15
|
item_name: 'Title', price: 123.45, payment_date: Date.today
|
16
|
-
|
16
|
+
)
|
17
17
|
assert invoice.valid?
|
18
18
|
invoice
|
19
19
|
end
|
data/test/validator_test.rb
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
module PolishInvoicer
|
4
|
-
class ValidatorTest <
|
4
|
+
class ValidatorTest < Minitest::Test
|
5
5
|
require 'ostruct'
|
6
6
|
|
7
7
|
def setup
|
8
8
|
@invoice = OpenStruct.new
|
9
9
|
end
|
10
10
|
|
11
|
-
def check_error(field, value=nil)
|
11
|
+
def check_error(field, value = nil)
|
12
12
|
@invoice.send("#{field}=", value)
|
13
13
|
v = Validator.new(@invoice)
|
14
14
|
v.valid?
|
15
15
|
assert v.errors[field]
|
16
16
|
end
|
17
17
|
|
18
|
-
def check_ok(field, value=nil)
|
18
|
+
def check_ok(field, value = nil)
|
19
19
|
@invoice.send("#{field}=", value)
|
20
20
|
v = Validator.new(@invoice)
|
21
21
|
v.valid?
|
@@ -129,47 +129,26 @@ module PolishInvoicer
|
|
129
129
|
check_ok(:buyer_nip, '123')
|
130
130
|
end
|
131
131
|
|
132
|
-
def check_dates_ok(create_date, trade_date, msg=nil)
|
132
|
+
def check_dates_ok(create_date, trade_date, msg = nil)
|
133
133
|
@invoice.create_date = Date.parse(create_date)
|
134
134
|
@invoice.trade_date = Date.parse(trade_date)
|
135
|
-
v = Validator.new(@invoice)
|
135
|
+
v = Validator.new(@invoice)
|
136
|
+
v.valid?
|
136
137
|
assert_nil v.errors[:create_date], msg
|
137
138
|
end
|
138
139
|
|
139
|
-
def check_dates_error(create_date, trade_date, msg=nil)
|
140
|
-
@invoice.create_date = Date.parse(create_date)
|
141
|
-
@invoice.trade_date = Date.parse(trade_date)
|
142
|
-
v = Validator.new(@invoice); v.valid?
|
143
|
-
assert v.errors[:create_date], msg
|
144
|
-
end
|
145
|
-
|
146
|
-
# data wystawienia max 30 dni przed wykonaniem usługi
|
147
|
-
def test_create_and_trade_date_correlation_before_trade
|
148
|
-
check_dates_ok('2014-01-01', '2014-01-01', 'B1')
|
149
|
-
check_dates_ok('2014-01-01', '2014-01-31', 'B2')
|
150
|
-
check_dates_error('2014-01-01', '2014-02-01', 'B3')
|
151
|
-
check_dates_ok('2014-01-02', '2014-02-01', 'B4')
|
152
|
-
end
|
153
|
-
|
154
|
-
# data wystawienie max 15 dnia następnego miesiąca po wykonaniu usługi
|
155
|
-
def test_create_and_trade_date_correlation_after_trade
|
156
|
-
check_dates_ok('2014-02-15', '2014-01-01', 'A1')
|
157
|
-
check_dates_error('2014-02-16', '2014-01-01', 'A2')
|
158
|
-
check_dates_error('2014-02-16', '2014-01-02', 'A3')
|
159
|
-
check_dates_error('2014-02-16', '2014-01-31', 'A4')
|
160
|
-
check_dates_ok('2014-02-15', '2014-01-31', 'A5')
|
161
|
-
check_dates_ok('2014-03-15', '2014-02-15', 'A6')
|
162
|
-
end
|
163
|
-
|
164
140
|
def test_no_vat_reason_presence
|
165
141
|
@invoice.vat = 23
|
166
|
-
v = Validator.new(@invoice)
|
142
|
+
v = Validator.new(@invoice)
|
143
|
+
v.valid?
|
167
144
|
assert_nil v.errors[:no_vat_reason]
|
168
145
|
@invoice.vat = -1
|
169
|
-
v = Validator.new(@invoice)
|
146
|
+
v = Validator.new(@invoice)
|
147
|
+
v.valid?
|
170
148
|
assert v.errors[:no_vat_reason]
|
171
149
|
@invoice.no_vat_reason = 'reason'
|
172
|
-
v = Validator.new(@invoice)
|
150
|
+
v = Validator.new(@invoice)
|
151
|
+
v.valid?
|
173
152
|
assert_nil v.errors[:no_vat_reason]
|
174
153
|
end
|
175
154
|
end
|
data/test/vat_test.rb
CHANGED
data/test/writer_test.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
require 'test_helper'
|
3
2
|
|
4
3
|
module PolishInvoicer
|
5
|
-
class WriterTest <
|
4
|
+
class WriterTest < Minitest::Test
|
6
5
|
def test_save_to_html
|
7
6
|
invoice = create_valid_invoice
|
8
7
|
writer = Writer.new(invoice)
|
9
8
|
path = '/tmp/test.html'
|
10
9
|
writer.save_to_html(path)
|
11
|
-
assert File.
|
10
|
+
assert File.exist?(path)
|
12
11
|
File.unlink(path)
|
13
12
|
end
|
14
13
|
|
@@ -17,7 +16,7 @@ module PolishInvoicer
|
|
17
16
|
writer = Writer.new(invoice)
|
18
17
|
path = '/tmp/test.pdf'
|
19
18
|
writer.save_to_pdf(path)
|
20
|
-
assert File.
|
19
|
+
assert File.exist?(path)
|
21
20
|
File.unlink(path)
|
22
21
|
end
|
23
22
|
|
data/tpl/invoice.slim
CHANGED
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polish_invoicer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Macuk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-04-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: simplecov
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,20 +66,34 @@ dependencies:
|
|
52
66
|
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: slim2pdf
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
58
86
|
requirements:
|
59
|
-
- - "
|
87
|
+
- - ">="
|
60
88
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0
|
89
|
+
version: '0'
|
62
90
|
type: :runtime
|
63
91
|
prerelease: false
|
64
92
|
version_requirements: !ruby/object:Gem::Requirement
|
65
93
|
requirements:
|
66
|
-
- - "
|
94
|
+
- - ">="
|
67
95
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0
|
96
|
+
version: '0'
|
69
97
|
description: Creates polish invoices and proforms as HTML or PDF files
|
70
98
|
email:
|
71
99
|
- piotr@macuk.pl
|
@@ -122,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
150
|
version: '0'
|
123
151
|
requirements: []
|
124
152
|
rubyforge_project:
|
125
|
-
rubygems_version: 2.
|
153
|
+
rubygems_version: 2.6.11
|
126
154
|
signing_key:
|
127
155
|
specification_version: 4
|
128
156
|
summary: Creates polish invoices and proforms as HTML or PDF files
|