polish_invoicer 0.0.1
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/.gitignore +16 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +145 -0
- data/Rakefile +9 -0
- data/doc/invoice.html +1 -0
- data/doc/invoice.pdf +0 -0
- data/doc/invoice.rb +21 -0
- data/doc/proforma.html +1 -0
- data/doc/proforma.pdf +0 -0
- data/doc/proforma.rb +23 -0
- data/lib/polish_invoicer.rb +14 -0
- data/lib/polish_invoicer/invoice.rb +93 -0
- data/lib/polish_invoicer/presenter.rb +63 -0
- data/lib/polish_invoicer/validator.rb +125 -0
- data/lib/polish_invoicer/vat.rb +36 -0
- data/lib/polish_invoicer/version.rb +3 -0
- data/lib/polish_invoicer/writer.rb +34 -0
- data/polish_invoicer.gemspec +26 -0
- data/test/invoice_test.rb +115 -0
- data/test/presenter_test.rb +56 -0
- data/test/test_helper.rb +19 -0
- data/test/validator_test.rb +176 -0
- data/test/vat_test.rb +25 -0
- data/test/writer_test.rb +35 -0
- data/tpl/invoice.slim +136 -0
- metadata +149 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Piotr Macuk
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
# PolishInvoicer [](https://codeclimate.com/github/macuk/polish_invoicer) [](https://travis-ci.org/macuk/polish_invoicer)
|
2
|
+
|
3
|
+
PolishInvoicer gem creates polish invoices and proforms as HTML or PDF files.
|
4
|
+
Gem description will be in polish language because of specific case of this gem.
|
5
|
+
|
6
|
+
Gem jest zgodny z nową [ustawą o podatku VAT](http://www.przepisy.gofin.pl/przepisy,3,32,32,670,55454,20140101,faktury.html), która weszła w życie z dniem 1 stycznia 2014.
|
7
|
+
|
8
|
+
[Krótkie podsumowanie zmian w wystawianiu faktur](http://www.jzk.pl/zmiany-2014).
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
gem 'polish_invoicer'
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install polish_invoicer
|
23
|
+
|
24
|
+
## Przykład użycia
|
25
|
+
|
26
|
+
### Generowanie proformy
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
require 'polish_invoicer'
|
30
|
+
|
31
|
+
invoice = PolishInvoicer::Invoice.new({
|
32
|
+
number: '1/2014', # numer faktury
|
33
|
+
create_date: Date.today, # data wystawienia
|
34
|
+
trade_date: Date.today, # data wykonania usługi
|
35
|
+
seller: ['Systemy Internetowe S.A.', # dane sprzedawcy
|
36
|
+
'ul. Jasna 10',
|
37
|
+
'12-345 Kraków'],
|
38
|
+
seller_nip: '123-456-78-90', # NIP sprzedawcy
|
39
|
+
buyer: ['Mała Firma sp. z o.o.', # dane nabywcy
|
40
|
+
'ul. Czerwona 20/4',
|
41
|
+
'10-043 Olsztyn'],
|
42
|
+
buyer_nip: '987-654-32-10', # NIP nabywcy
|
43
|
+
item_name: 'Usługi programistyczne', # nazwa usługi
|
44
|
+
price: 3500, # cena (domyślnie brutto)
|
45
|
+
payment_date: Date.today + 14, # data płatności
|
46
|
+
proforma: true, # znacznik proformy
|
47
|
+
paid: false, # znacznik opłacenia usługi
|
48
|
+
})
|
49
|
+
if invoice.valid?
|
50
|
+
invoice.save_to_html('/path/to/proforma.html')
|
51
|
+
invoice.save_to_pdf('/path/to/proforma.pdf')
|
52
|
+
else
|
53
|
+
puts invoice.errors.inspect
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
[Wygenerowana proforma](https://github.com/macuk/polish_invoicer/blob/master/doc/proforma.pdf?raw=true)
|
58
|
+
|
59
|
+
### Generowanie faktury
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
invoice.proforma = false
|
63
|
+
invoice.paid = true
|
64
|
+
invoice.save_to_html('/path/to/invoice.html')
|
65
|
+
invoice.save_to_pdf('/path/to/invoice.pdf')
|
66
|
+
```
|
67
|
+
|
68
|
+
[Wygenerowana faktura](https://github.com/macuk/polish_invoicer/blob/master/doc/invoice.pdf?raw=true)
|
69
|
+
|
70
|
+
## Opis wszystkich dostępnych parametrów
|
71
|
+
|
72
|
+
### Parametry wymagane
|
73
|
+
|
74
|
+
:number, # numer faktury (string)
|
75
|
+
:create_date, # data wystawienia faktury (date)
|
76
|
+
:trade_date, # data sprzedaży (date)
|
77
|
+
:seller, # adres sprzedawcy (tablica stringów)
|
78
|
+
:seller_nip, # NIP sprzedawcy (string)
|
79
|
+
:buyer, # adres nabywcy (tablica stringów)
|
80
|
+
:buyer_nip, # NIP nabywcy (string)
|
81
|
+
:item_name, # nazwa usługi (string)
|
82
|
+
:price, # cena w złotych (float)
|
83
|
+
:payment_date, # termin płatności (date)
|
84
|
+
|
85
|
+
### Parametry wymagane z ustawionymi wartościami domyślnymi
|
86
|
+
|
87
|
+
:gross_price, # znacznik rodzaju ceny (netto/brutto) (boolean)
|
88
|
+
# wartość domyślna: true, czyli brutto
|
89
|
+
:vat, # stawka vat (integer ze zbioru [23, 8, 5, 0, -1]
|
90
|
+
# -1 oznacza zwolniony z VAT
|
91
|
+
# wartość domyślna: 23
|
92
|
+
:paid, # znacznik opłacenia usługi (boolean)
|
93
|
+
# wartość domyślna: true, czyli opłacona
|
94
|
+
:proforma, # znacznik faktury pro-forma (boolean)
|
95
|
+
# wartość domyślna: false
|
96
|
+
:payment_type, # rodzaj płatności (string)
|
97
|
+
# wartość domyślna: 'Przelew'
|
98
|
+
|
99
|
+
### Parametry dodatkowe
|
100
|
+
|
101
|
+
:comments, # uwagi (string lub tablica stringów)
|
102
|
+
:pkwiu, # numer PKWiU (string)
|
103
|
+
:no_vat_reason, # podstawa prawna zwolnienia z VAT (string)
|
104
|
+
:footer, # treść umieszczana w stopce faktury (string)
|
105
|
+
|
106
|
+
### Parametry systemowe
|
107
|
+
|
108
|
+
:template_path, # ścieżka do własnego szablonu faktury
|
109
|
+
:logger, # możliwość ustawienia loggera
|
110
|
+
# podczas użycia w aplikacji Rails
|
111
|
+
# logger ustawia się automatycznie
|
112
|
+
:wkhtmltopdf_command # komenda wywołania polecenia wkhtmltopdf
|
113
|
+
# bez podawania plików html i pdf
|
114
|
+
|
115
|
+
## Walidacja parametrów i obsługa błędów
|
116
|
+
|
117
|
+
Zmienna `invoice` z poprzedniego przykładu.
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
invoice.create_date = Date.today
|
121
|
+
invoice.trade_date = Date.today - 60
|
122
|
+
invoice.vat = 1
|
123
|
+
invoice.valid?
|
124
|
+
puts invoice.errors.inspect
|
125
|
+
```
|
126
|
+
|
127
|
+
{
|
128
|
+
:vat=>"Stawka VAT spoza listy dopuszczalnych wartości",
|
129
|
+
:create_date=>"Data wystawienia nie może być późniejsza niż 15 dzień następnego miesiąca po wykonaniu usługi"
|
130
|
+
}
|
131
|
+
|
132
|
+
## Dodatkowe metody
|
133
|
+
|
134
|
+
net_value # obliczona wartość netto
|
135
|
+
vat_value # obliczona kwota VAT
|
136
|
+
gross_value # obliczona wartość brutto
|
137
|
+
to_hash # hash przekazywany do szablonu faktury
|
138
|
+
|
139
|
+
## Contributing
|
140
|
+
|
141
|
+
1. Fork it
|
142
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
143
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
144
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
145
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/doc/invoice.html
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8" /><link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet" /><title>Faktura nr 1/2014</title><style type="text/css">body, h1, h2, h3, h4, h5, h6 { font-family: verdana, helvetica, arial, sans-serif; }</style></head><body><div class="container"><br /><br /><h2>Faktura</h2><h3>Nr 1/2014</h3><br /><br /><div class="row"><div class="col-xs-6"><h4>Sprzedawca</h4>Systemy Internetowe S.A.<br />ul. Jasna 10<br />12-345 Kraków<br />NIP: 123-456-78-90</div><div class="col-xs-6"><h4>Nabywca</h4>Mała Firma sp. z o.o.<br />ul. Czerwona 20/4<br />10-043 Olsztyn<br />NIP: 987-654-32-10</div></div><hr /><div class="row"><div class="col-xs-3">Data wystawienia:<br />Wykonanie usługi:</div><div class="col-xs-3">21.01.2014<br />21.01.2014</div><div class="col-xs-3">Termin płatności:<br />Sposób zapłaty:</div><div class="col-xs-3">04.02.2014<br />Przelew</div></div><br /><br /><table class="table table-condensed"><tr><th width="40%">Usługa</th><th class="text-center" width="7%">Ilość</th><th class="text-center" width="7%">Cena netto</th><th class="text-center" width="7%">Wart. netto</th><th class="text-center" width="1%">VAT</th><th class="text-center" width="7%">Kwota VAT</th><th class="text-center" width="7%">Wart. brutto</th></tr><tr><td>Usługi programistyczne</td><td class="text-center">1 usł.</td><td class="text-center">2845,53</td><td class="text-center">2845,53</td><td class="text-center">23%</td><td class="text-center">654,47</td><td class="text-center">3500,00</td></tr><tr><td colspan="2"> </td><th class="text-center">Razem</th><td class="text-center">2845,53</td><td class="text-center">23%</td><td class="text-center">654,47</td><th class="text-center">3500,00</th></tr></table><br /><div class="row"><div class="col-xs-3"><b>Razem do zapłaty:</b><br />Zapłacono:<br />Zostało do zapłaty:</div><div class="col-xs-3"><b>3500,00 zł</b><br />3500,00 zł<br />0,00 zł</div></div></div></body></html>
|
data/doc/invoice.pdf
ADDED
Binary file
|
data/doc/invoice.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'polish_invoicer'
|
3
|
+
|
4
|
+
invoice = PolishInvoicer::Invoice.new({
|
5
|
+
number: '1/2014', # numer faktury
|
6
|
+
create_date: Date.today, # data wystawienia
|
7
|
+
trade_date: Date.today, # data wykonania usługi
|
8
|
+
seller: ['Systemy Internetowe S.A.', # dane sprzedawcy
|
9
|
+
'ul. Jasna 10',
|
10
|
+
'12-345 Kraków'],
|
11
|
+
seller_nip: '123-456-78-90', # NIP sprzedawcy
|
12
|
+
buyer: ['Mała Firma sp. z o.o.', # dane nabywcy
|
13
|
+
'ul. Czerwona 20/4',
|
14
|
+
'10-043 Olsztyn'],
|
15
|
+
buyer_nip: '987-654-32-10', # NIP nabywcy
|
16
|
+
item_name: 'Usługi programistyczne', # nazwa usługi
|
17
|
+
price: 3500, # cena (domyślnie brutto)
|
18
|
+
payment_date: Date.today + 14, # data płatności
|
19
|
+
})
|
20
|
+
invoice.save_to_html('/tmp/invoice.html')
|
21
|
+
invoice.save_to_pdf('/tmp/invoice.pdf')
|
data/doc/proforma.html
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8" /><link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet" /><title>Proforma nr 1/2014/PROFORMA</title><style type="text/css">body, h1, h2, h3, h4, h5, h6 { font-family: verdana, helvetica, arial, sans-serif; }</style></head><body><div class="container"><h5 class="text-center">Proforma nie jest dowodem księgowym i nie należy jej księgować.</h5><br /><br /><h2>Proforma</h2><h3>Nr 1/2014/PROFORMA</h3><br /><br /><div class="row"><div class="col-xs-6"><h4>Sprzedawca</h4>Systemy Internetowe S.A.<br />ul. Jasna 10<br />12-345 Kraków<br />NIP: 123-456-78-90</div><div class="col-xs-6"><h4>Nabywca</h4>Mała Firma sp. z o.o.<br />ul. Czerwona 20/4<br />10-043 Olsztyn<br />NIP: 987-654-32-10</div></div><hr /><div class="row"><div class="col-xs-3">Data wystawienia:</div><div class="col-xs-3">21.01.2014</div><div class="col-xs-3">Termin płatności:<br />Sposób zapłaty:</div><div class="col-xs-3">04.02.2014<br />Przelew</div></div><br /><br /><table class="table table-condensed"><tr><th width="40%">Usługa</th><th class="text-center" width="7%">Ilość</th><th class="text-center" width="7%">Cena netto</th><th class="text-center" width="7%">Wart. netto</th><th class="text-center" width="7%">Wart. brutto</th></tr><tr><td>Usługi programistyczne</td><td class="text-center">1 usł.</td><td class="text-center">2845,53</td><td class="text-center">2845,53</td><td class="text-center">3500,00</td></tr><tr><td colspan="2"> </td><th class="text-center">Razem</th><td class="text-center">2845,53</td><th class="text-center">3500,00</th></tr></table><br /><div class="row"><div class="col-xs-3"><b>Razem do zapłaty:</b><br />Zapłacono:<br />Zostało do zapłaty:</div><div class="col-xs-3"><b>3500,00 zł</b><br />0,00 zł<br />3500,00 zł</div></div></div></body></html>
|
data/doc/proforma.pdf
ADDED
Binary file
|
data/doc/proforma.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'polish_invoicer'
|
3
|
+
|
4
|
+
invoice = PolishInvoicer::Invoice.new({
|
5
|
+
number: '1/2014/PROFORMA', # numer faktury
|
6
|
+
create_date: Date.today, # data wystawienia
|
7
|
+
trade_date: Date.today, # data wykonania usługi
|
8
|
+
seller: ['Systemy Internetowe S.A.', # dane sprzedawcy
|
9
|
+
'ul. Jasna 10',
|
10
|
+
'12-345 Kraków'],
|
11
|
+
seller_nip: '123-456-78-90', # NIP sprzedawcy
|
12
|
+
buyer: ['Mała Firma sp. z o.o.', # dane nabywcy
|
13
|
+
'ul. Czerwona 20/4',
|
14
|
+
'10-043 Olsztyn'],
|
15
|
+
buyer_nip: '987-654-32-10', # NIP nabywcy
|
16
|
+
item_name: 'Usługi programistyczne', # nazwa usługi
|
17
|
+
price: 3500, # cena (domyślnie brutto)
|
18
|
+
payment_date: Date.today + 14, # data płatności
|
19
|
+
proforma: true,
|
20
|
+
paid: false
|
21
|
+
})
|
22
|
+
invoice.save_to_html('/tmp/proforma.html')
|
23
|
+
invoice.save_to_pdf('/tmp/proforma.pdf')
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "date"
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
require "polish_invoicer/version"
|
5
|
+
require "polish_invoicer/vat"
|
6
|
+
require "polish_invoicer/validator"
|
7
|
+
require 'slim2pdf'
|
8
|
+
require "polish_invoicer/writer"
|
9
|
+
require "polish_invoicer/presenter"
|
10
|
+
require "polish_invoicer/invoice"
|
11
|
+
|
12
|
+
module PolishInvoicer
|
13
|
+
# Your code goes here...
|
14
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module PolishInvoicer
|
3
|
+
class Invoice
|
4
|
+
AVAILABLE_PARAMS = [
|
5
|
+
:number, # numer faktury (string)
|
6
|
+
:create_date, # data wystawienia faktury (date)
|
7
|
+
:trade_date, # data sprzedaży (date)
|
8
|
+
:seller, # adres sprzedawcy (tablica stringów)
|
9
|
+
:seller_nip, # NIP sprzedawcy (string)
|
10
|
+
:buyer, # adres nabywcy (tablica stringów)
|
11
|
+
:buyer_nip, # NIP nabywcy (string)
|
12
|
+
:item_name, # nazwa usługi (string)
|
13
|
+
:price, # cena w złotych (float)
|
14
|
+
:gross_price, # znacznik rodzaju ceny (netto/brutto), domyślnie: true (boolean)
|
15
|
+
:vat, # stawka vat, domyślnie: 23 (integer)
|
16
|
+
:pkwiu, # numer PKWiU (string)
|
17
|
+
:payment_type, # rodzaj płatności, domyślnie: 'Przelew' (string)
|
18
|
+
:payment_date, # termin płatności (date)
|
19
|
+
:comments, # uwagi (string lub tablica stringów)
|
20
|
+
:paid, # znacznik opłacenia faktury, domyślnie: true (boolean)
|
21
|
+
:footer, # treść umieszczana w stopce faktury (string)
|
22
|
+
:proforma, # znacznik faktury pro-forma, domyślnie: false (boolean)
|
23
|
+
:no_vat_reason, # podstawa prawna zwolnienia z VAT (string)
|
24
|
+
]
|
25
|
+
|
26
|
+
attr_accessor *AVAILABLE_PARAMS
|
27
|
+
attr_accessor :template_path, :logger, :wkhtmltopdf_command
|
28
|
+
|
29
|
+
def initialize(params={})
|
30
|
+
set_defaults
|
31
|
+
params.each do |k, v|
|
32
|
+
raise "Nierozpoznany parametr #{k}" unless AVAILABLE_PARAMS.include?(k)
|
33
|
+
send("#{k}=", v)
|
34
|
+
end
|
35
|
+
@validator = Validator.new(self)
|
36
|
+
end
|
37
|
+
|
38
|
+
def errors
|
39
|
+
@validator.errors
|
40
|
+
end
|
41
|
+
|
42
|
+
def valid?
|
43
|
+
@validator.valid?
|
44
|
+
end
|
45
|
+
|
46
|
+
# cena/wartość netto
|
47
|
+
def net_value
|
48
|
+
return price unless gross_price
|
49
|
+
price / (1 + Vat.to_i(vat)/100.0)
|
50
|
+
end
|
51
|
+
|
52
|
+
# kwota VAT
|
53
|
+
def vat_value
|
54
|
+
(gross_value * Vat.to_i(vat)) / (100.0 + Vat.to_i(vat))
|
55
|
+
end
|
56
|
+
|
57
|
+
# cena/wartość brutto
|
58
|
+
def gross_value
|
59
|
+
return price if gross_price
|
60
|
+
price + price * Vat.to_i(vat)/100.0
|
61
|
+
end
|
62
|
+
|
63
|
+
def save_to_html(path)
|
64
|
+
validate!
|
65
|
+
Writer.new(self).save_to_html(path)
|
66
|
+
end
|
67
|
+
|
68
|
+
def save_to_pdf(path)
|
69
|
+
validate!
|
70
|
+
Writer.new(self).save_to_pdf(path)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Wszystkie dane w postaci hash-a
|
74
|
+
def to_hash
|
75
|
+
Presenter.new(self).data
|
76
|
+
end
|
77
|
+
|
78
|
+
protected
|
79
|
+
def set_defaults
|
80
|
+
@gross_price = true
|
81
|
+
@vat = 23
|
82
|
+
@payment_type = 'Przelew'
|
83
|
+
@paid = true
|
84
|
+
@proforma = false
|
85
|
+
end
|
86
|
+
|
87
|
+
def validate!
|
88
|
+
return if valid?
|
89
|
+
error_messages = errors.map { |k, v| "#{k}: #{v}" }.join(', ')
|
90
|
+
raise "Parametry do wystawienia faktury są nieprawidłowe: #{error_messages}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module PolishInvoicer
|
3
|
+
class Presenter
|
4
|
+
attr_accessor :invoice
|
5
|
+
|
6
|
+
def initialize(invoice)
|
7
|
+
@invoice = invoice
|
8
|
+
@out = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def data
|
12
|
+
copy_available_params
|
13
|
+
remove_redundand_params
|
14
|
+
copy_additional_params
|
15
|
+
format_dates
|
16
|
+
format_prices
|
17
|
+
format_comments
|
18
|
+
format_vat
|
19
|
+
@out
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
def copy_available_params
|
24
|
+
Invoice::AVAILABLE_PARAMS.each do |field|
|
25
|
+
@out[field] = @invoice.send(field)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove_redundand_params
|
30
|
+
@out.delete(:price)
|
31
|
+
end
|
32
|
+
|
33
|
+
def copy_additional_params
|
34
|
+
%w(net_value vat_value gross_value).each do |field|
|
35
|
+
@out[field.to_sym] = @invoice.send(field)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
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"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
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).gsub('.', ',')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
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
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module PolishInvoicer
|
3
|
+
class Validator
|
4
|
+
attr_reader :errors
|
5
|
+
|
6
|
+
def initialize(invoice)
|
7
|
+
@invoice = invoice
|
8
|
+
@errors = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def valid?
|
12
|
+
@errors = {}
|
13
|
+
check_presence
|
14
|
+
check_not_nil
|
15
|
+
check_dates
|
16
|
+
check_arrays
|
17
|
+
check_booleans
|
18
|
+
check_price
|
19
|
+
check_vat
|
20
|
+
check_proforma
|
21
|
+
check_create_and_trade_date_correlation
|
22
|
+
@errors.empty?
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
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
|
+
check_blank(:buyer_nip, 'NIP nabywcy nie może być pusty')
|
39
|
+
end
|
40
|
+
|
41
|
+
def check_not_nil
|
42
|
+
@errors[:gross_price] = 'Konieczne jest ustawienie znacznika rodzaju ceny (netto/brutto)' if @invoice.gross_price.nil?
|
43
|
+
@errors[:paid] = 'Konieczne jest ustawienie znacznika opłacenia faktury' if @invoice.paid.nil?
|
44
|
+
end
|
45
|
+
|
46
|
+
def check_arrays
|
47
|
+
@errors[:seller] = 'Sprzedawca musi być podany jako tablica stringów' unless @invoice.seller.is_a?(Array)
|
48
|
+
@errors[:buyer] = 'Nabywca musi być podany jako tablica stringów' unless @invoice.buyer.is_a?(Array)
|
49
|
+
end
|
50
|
+
|
51
|
+
def check_booleans
|
52
|
+
unless [true, false].include?(@invoice.gross_price)
|
53
|
+
@errors[:gross_price] = 'Znacznik rodzaju ceny musi być podany jako boolean'
|
54
|
+
end
|
55
|
+
unless [true, false].include?(@invoice.paid)
|
56
|
+
@errors[:paid] = 'Znacznik opłacenia faktury musi być podany jako boolean'
|
57
|
+
end
|
58
|
+
unless [true, false].include?(@invoice.proforma)
|
59
|
+
@errors[:proforma] = 'Znacznik faktury pro-forma musi być podany jako boolean'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def check_dates
|
64
|
+
@errors[:create_date] = 'Data wystawienia musi być typu Date' unless @invoice.create_date.is_a?(Date)
|
65
|
+
@errors[:trade_date] = 'Data sprzedaży musi być typu Date' unless @invoice.trade_date.is_a?(Date)
|
66
|
+
@errors[:payment_date] = 'Termin płatności musi być typu Date' unless @invoice.payment_date.is_a?(Date)
|
67
|
+
end
|
68
|
+
|
69
|
+
def check_price
|
70
|
+
unless @invoice.price.is_a?(Numeric)
|
71
|
+
@errors[:price] = 'Cena musi być liczbą'
|
72
|
+
else
|
73
|
+
@errors[:price] = 'Cena musi być liczbą dodatnią' unless @invoice.price > 0
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def check_vat
|
78
|
+
unless Vat.valid?(@invoice.vat)
|
79
|
+
@errors[:vat] = 'Stawka VAT spoza listy dopuszczalnych wartości'
|
80
|
+
else
|
81
|
+
if Vat.zw?(@invoice.vat) and blank?(@invoice.no_vat_reason)
|
82
|
+
@errors[:no_vat_reason] = 'Konieczne jest podanie podstawy prawnej zwolnienia z podatku VAT'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def check_proforma
|
88
|
+
return unless @invoice.proforma
|
89
|
+
return unless @invoice.paid
|
90
|
+
@errors[:paid] = 'Proforma nie może być opłacona'
|
91
|
+
end
|
92
|
+
|
93
|
+
def blank?(value)
|
94
|
+
value.to_s.strip == ''
|
95
|
+
end
|
96
|
+
|
97
|
+
def check_blank(key, msg)
|
98
|
+
value = @invoice.send(key)
|
99
|
+
@errors[key] = msg if blank?(value)
|
100
|
+
end
|
101
|
+
|
102
|
+
def check_create_and_trade_date_correlation
|
103
|
+
return unless @invoice.create_date
|
104
|
+
return unless @invoice.trade_date
|
105
|
+
cd = @invoice.create_date
|
106
|
+
td = @invoice.trade_date
|
107
|
+
# data wystawienia max 30 dni przed wykonaniem usługi
|
108
|
+
if cd < td and (td - cd > 30)
|
109
|
+
msg = 'Data wystawienia nie może być wcześniejsza niż ' +
|
110
|
+
'30 dni przed wykonaniem usługi'
|
111
|
+
@errors[:create_date] = msg
|
112
|
+
end
|
113
|
+
# data wystawienie max 15 dnia następnego miesiąca po wykonaniu usługi
|
114
|
+
if cd > td
|
115
|
+
td_nm = td.next_month
|
116
|
+
cd_dl = Date.new(td_nm.year, td_nm.month, 15)
|
117
|
+
if cd > cd_dl
|
118
|
+
msg = 'Data wystawienia nie może być późniejsza niż ' +
|
119
|
+
'15 dzień następnego miesiąca po wykonaniu usługi'
|
120
|
+
@errors[:create_date] = msg
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|