polish_invoicer 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|