polish_invoicer 0.0.25 → 0.0.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +37 -0
- data/.rubocop.yml +7 -5
- data/.rubocop_todo.yml +66 -0
- data/.ruby-version +1 -0
- data/Gemfile +2 -0
- data/README.md +1 -1
- data/Rakefile +2 -0
- data/doc/invoice.rb +2 -0
- data/doc/proforma.rb +2 -0
- data/lib/polish_invoicer/invoice.rb +21 -5
- data/lib/polish_invoicer/presenter.rb +5 -1
- data/lib/polish_invoicer/validator.rb +27 -9
- data/lib/polish_invoicer/vat.rb +4 -0
- data/lib/polish_invoicer/version.rb +3 -1
- data/lib/polish_invoicer/writer.rb +4 -7
- data/lib/polish_invoicer.rb +2 -0
- data/polish_invoicer.gemspec +10 -5
- data/test/invoice_test.rb +92 -10
- data/test/presenter_test.rb +11 -1
- data/test/test_generator.rb +2 -0
- data/test/test_helper.rb +5 -2
- data/test/validator_test.rb +34 -1
- data/test/vat_test.rb +3 -1
- data/test/writer_test.rb +7 -2
- data/tpl/invoice-en.slim +31 -113
- data/tpl/invoice-es.slim +117 -0
- data/tpl/{invoice.slim → invoice-pl.slim} +1 -1
- data/tpl/invoice-pl_en.slim +199 -0
- data/tpl/proforma-en.slim +27 -83
- data/tpl/proforma-es.slim +104 -0
- data/tpl/proforma-pl_en.slim +160 -0
- metadata +46 -18
- data/.travis.yml +0 -5
- /data/tpl/{proforma.slim → proforma-pl.slim} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80d547e5b447b0bdd6116f666ebc332a8e586cdc0513da03d75f69d83219253c
|
4
|
+
data.tar.gz: 988303b13fe261a44aa22cf1141ee18c834b5f8ba813f117b14596f552c97700
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44849946ede47b60e85c1fc53c91ba6cc58c04e218a03ca15e6a41fb33b94cda982af279fa68aaa537512a660b502ca05e31e37df89b79d5b2b84882368b7755
|
7
|
+
data.tar.gz: c52f5c7de68dc7369976056b08357198405e6fcea846cb87abeea94fe5b51040ee6ff067b4b725c9a296c14f46a8014bc52649d63fc96c6edc32ad674aec14da
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: Ruby
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ "master" ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ "master" ]
|
15
|
+
|
16
|
+
permissions:
|
17
|
+
contents: read
|
18
|
+
|
19
|
+
jobs:
|
20
|
+
test:
|
21
|
+
|
22
|
+
runs-on: ubuntu-22.04
|
23
|
+
strategy:
|
24
|
+
matrix:
|
25
|
+
ruby-version: ['3.0', '3.1', '3.2']
|
26
|
+
|
27
|
+
steps:
|
28
|
+
- uses: actions/checkout@v4
|
29
|
+
- name: Set up Ruby
|
30
|
+
uses: ruby/setup-ruby@v1
|
31
|
+
with:
|
32
|
+
ruby-version: ${{ matrix.ruby-version }}
|
33
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
34
|
+
- name: Run tests
|
35
|
+
run: bundle exec rake
|
36
|
+
- name: Run linter
|
37
|
+
run: bundle exec rubocop
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2023-10-24 20:10:00 UTC using RuboCop version 1.57.1.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 7
|
10
|
+
# Configuration parameters: EnforcedStyle, AllowedGems, Include.
|
11
|
+
# SupportedStyles: Gemfile, gems.rb, gemspec
|
12
|
+
# Include: **/*.gemspec, **/Gemfile, **/gems.rb
|
13
|
+
Gemspec/DevelopmentDependencies:
|
14
|
+
Exclude:
|
15
|
+
- 'polish_invoicer.gemspec'
|
16
|
+
|
17
|
+
# Offense count: 1
|
18
|
+
# Configuration parameters: Severity, Include.
|
19
|
+
# Include: **/*.gemspec
|
20
|
+
Gemspec/RequiredRubyVersion:
|
21
|
+
Exclude:
|
22
|
+
- 'polish_invoicer.gemspec'
|
23
|
+
|
24
|
+
# Offense count: 1
|
25
|
+
# This cop supports safe autocorrection (--autocorrect).
|
26
|
+
# Configuration parameters: AllowForAlignment.
|
27
|
+
Layout/CommentIndentation:
|
28
|
+
Exclude:
|
29
|
+
- 'lib/polish_invoicer/invoice.rb'
|
30
|
+
|
31
|
+
# Offense count: 12
|
32
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
33
|
+
Metrics/AbcSize:
|
34
|
+
Max: 32
|
35
|
+
|
36
|
+
# Offense count: 4
|
37
|
+
# Configuration parameters: CountComments, CountAsOne.
|
38
|
+
Metrics/ClassLength:
|
39
|
+
Max: 196
|
40
|
+
|
41
|
+
# Offense count: 14
|
42
|
+
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
43
|
+
Metrics/MethodLength:
|
44
|
+
Max: 20
|
45
|
+
|
46
|
+
# Offense count: 11
|
47
|
+
Minitest/MultipleAssertions:
|
48
|
+
Max: 12
|
49
|
+
|
50
|
+
# Offense count: 5
|
51
|
+
# Configuration parameters: AllowedConstants.
|
52
|
+
Style/Documentation:
|
53
|
+
Exclude:
|
54
|
+
- 'spec/**/*'
|
55
|
+
- 'test/**/*'
|
56
|
+
- 'lib/polish_invoicer/invoice.rb'
|
57
|
+
- 'lib/polish_invoicer/presenter.rb'
|
58
|
+
- 'lib/polish_invoicer/validator.rb'
|
59
|
+
- 'lib/polish_invoicer/vat.rb'
|
60
|
+
- 'lib/polish_invoicer/writer.rb'
|
61
|
+
|
62
|
+
# Offense count: 2
|
63
|
+
Style/OpenStructUse:
|
64
|
+
Exclude:
|
65
|
+
- 'test/presenter_test.rb'
|
66
|
+
- 'test/validator_test.rb'
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.2.2
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# PolishInvoicer [![Code Climate](https://codeclimate.com/github/macuk/polish_invoicer.png)](https://codeclimate.com/github/macuk/polish_invoicer)
|
1
|
+
# PolishInvoicer [![Code Climate](https://codeclimate.com/github/macuk/polish_invoicer.png)](https://codeclimate.com/github/macuk/polish_invoicer)
|
2
2
|
|
3
3
|
PolishInvoicer gem creates Polish invoices and proforms in HTML and PDF formats.
|
4
4
|
|
data/Rakefile
CHANGED
data/doc/invoice.rb
CHANGED
data/doc/proforma.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module PolishInvoicer
|
2
4
|
class Invoice
|
3
5
|
AVAILABLE_PARAMS = [
|
@@ -23,19 +25,22 @@ module PolishInvoicer
|
|
23
25
|
:proforma, # znacznik faktury pro-forma, domyślnie: false (boolean)
|
24
26
|
:no_vat_reason, # podstawa prawna zwolnienia z VAT (string)
|
25
27
|
:foreign_buyer, # nabywcą jest firma spoza Polski, domyślnie: false (boolean)
|
28
|
+
:lang, # język na fakturze, domyślnie: zależny od ustawienia foreign_buyer
|
29
|
+
# foreign_buyer = false => lang = 'pl'
|
30
|
+
# foreign_buyer = true => lang = 'pl_en'
|
31
|
+
# możliwe wartości: pl | pl_en | en | es
|
26
32
|
:reverse_charge, # faktura z odwrotnym obciążeniem VAT
|
27
33
|
:currency, # waluta rozliczeniowa, domyślnie: PLN (string)
|
28
34
|
:exchange_rate # kurs waluty rozliczeniowej, domyślnie: 1.0000 (float)
|
29
35
|
].freeze
|
30
36
|
|
31
|
-
attr_accessor(*AVAILABLE_PARAMS)
|
32
|
-
attr_accessor :template_path
|
33
|
-
attr_accessor :logger, :wkhtmltopdf_path, :wkhtmltopdf_command
|
37
|
+
attr_accessor(*AVAILABLE_PARAMS, :template_path, :logger, :wkhtmltopdf_path, :wkhtmltopdf_command)
|
34
38
|
|
35
39
|
def initialize(params = {})
|
36
40
|
set_defaults
|
37
41
|
params.each do |k, v|
|
38
42
|
raise "Nierozpoznany parametr #{k}" unless AVAILABLE_PARAMS.include?(k)
|
43
|
+
|
39
44
|
send("#{k}=", v)
|
40
45
|
end
|
41
46
|
@validator = PolishInvoicer::Validator.new(self)
|
@@ -52,7 +57,8 @@ module PolishInvoicer
|
|
52
57
|
# cena/wartość netto
|
53
58
|
def net_value
|
54
59
|
return price unless gross_price
|
55
|
-
|
60
|
+
|
61
|
+
price / (1 + (Vat.to_i(vat) / 100.0))
|
56
62
|
end
|
57
63
|
|
58
64
|
# kwota VAT
|
@@ -63,7 +69,8 @@ module PolishInvoicer
|
|
63
69
|
# cena/wartość brutto
|
64
70
|
def gross_value
|
65
71
|
return price if gross_price
|
66
|
-
|
72
|
+
|
73
|
+
price + (price * Vat.to_i(vat) / 100.0)
|
67
74
|
end
|
68
75
|
|
69
76
|
def save_to_html(path)
|
@@ -97,6 +104,14 @@ module PolishInvoicer
|
|
97
104
|
paid ? 0 : (total_to_pay_value - price_paid.to_f)
|
98
105
|
end
|
99
106
|
|
107
|
+
def template_lang
|
108
|
+
lang || (foreign_buyer ? 'pl_en' : 'pl')
|
109
|
+
end
|
110
|
+
|
111
|
+
def template_file
|
112
|
+
proforma ? "proforma-#{template_lang}.slim" : "invoice-#{template_lang}.slim"
|
113
|
+
end
|
114
|
+
|
100
115
|
private
|
101
116
|
|
102
117
|
def set_defaults
|
@@ -114,6 +129,7 @@ module PolishInvoicer
|
|
114
129
|
|
115
130
|
def validate!
|
116
131
|
return if valid?
|
132
|
+
|
117
133
|
error_messages = errors.map { |k, v| "#{k}: #{v}" }.join(', ')
|
118
134
|
raise "Parametry do wystawienia faktury są nieprawidłowe: #{error_messages}"
|
119
135
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module PolishInvoicer
|
2
4
|
class Presenter
|
3
5
|
attr_accessor :invoice
|
@@ -40,6 +42,7 @@ module PolishInvoicer
|
|
40
42
|
%w[trade_date create_date payment_date].each do |field|
|
41
43
|
v = @invoice.send(field)
|
42
44
|
next unless v
|
45
|
+
|
43
46
|
@out[field.to_sym] = v.strftime '%d.%m.%Y'
|
44
47
|
end
|
45
48
|
end
|
@@ -48,7 +51,8 @@ module PolishInvoicer
|
|
48
51
|
%w[net_value vat_value gross_value exchanged_tax total_to_pay_value paid_value to_pay_value].each do |field|
|
49
52
|
v = @invoice.send(field)
|
50
53
|
next unless v
|
51
|
-
|
54
|
+
|
55
|
+
@out[field.to_sym] = format('%02.2f', v).tr('.', ',')
|
52
56
|
end
|
53
57
|
end
|
54
58
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module PolishInvoicer
|
2
4
|
class Validator
|
3
5
|
attr_reader :errors
|
@@ -20,6 +22,7 @@ module PolishInvoicer
|
|
20
22
|
check_proforma
|
21
23
|
check_create_and_payment_date
|
22
24
|
check_currency
|
25
|
+
check_lang
|
23
26
|
@errors.empty?
|
24
27
|
end
|
25
28
|
|
@@ -40,7 +43,10 @@ module PolishInvoicer
|
|
40
43
|
end
|
41
44
|
|
42
45
|
def check_not_nil
|
43
|
-
|
46
|
+
if @invoice.gross_price.nil?
|
47
|
+
@errors[:gross_price] =
|
48
|
+
'Konieczne jest ustawienie znacznika rodzaju ceny (netto/brutto)'
|
49
|
+
end
|
44
50
|
@errors[:paid] = 'Konieczne jest ustawienie znacznika opłacenia faktury' if @invoice.paid.nil?
|
45
51
|
@errors[:currency] = 'Konieczne jest ustawienie waluty rozliczeniowej' if @invoice.currency.nil?
|
46
52
|
@errors[:exchange_rate] = 'Konieczne jest podanie kursu waluty rozliczeniowej' if @invoice.exchange_rate.nil?
|
@@ -55,18 +61,17 @@ module PolishInvoicer
|
|
55
61
|
unless [true, false].include?(@invoice.gross_price)
|
56
62
|
@errors[:gross_price] = 'Znacznik rodzaju ceny musi być podany jako boolean'
|
57
63
|
end
|
58
|
-
unless [true,
|
59
|
-
|
60
|
-
end
|
64
|
+
@errors[:paid] = 'Znacznik opłacenia faktury musi być podany jako boolean' unless [true,
|
65
|
+
false].include?(@invoice.paid)
|
61
66
|
unless [true, false].include?(@invoice.proforma)
|
62
67
|
@errors[:proforma] = 'Znacznik faktury pro-forma musi być podany jako boolean'
|
63
68
|
end
|
64
69
|
unless [true, false].include?(@invoice.foreign_buyer)
|
65
70
|
@errors[:foreign_buyer] = 'Znacznik zagranicznego nabywcy musi być podany jako boolean'
|
66
71
|
end
|
67
|
-
|
68
|
-
|
69
|
-
|
72
|
+
return if [true, false].include?(@invoice.reverse_charge)
|
73
|
+
|
74
|
+
@errors[:reverse_charge] = 'Znacznik odwrotnego obciążenia VAT musi być podany jako boolean'
|
70
75
|
end
|
71
76
|
|
72
77
|
def check_dates
|
@@ -77,7 +82,7 @@ module PolishInvoicer
|
|
77
82
|
|
78
83
|
def check_price
|
79
84
|
if @invoice.price.is_a?(Numeric)
|
80
|
-
@errors[:price] = 'Cena musi być liczbą dodatnią' unless @invoice.price
|
85
|
+
@errors[:price] = 'Cena musi być liczbą dodatnią' unless @invoice.price.positive?
|
81
86
|
else
|
82
87
|
@errors[:price] = 'Cena musi być liczbą'
|
83
88
|
end
|
@@ -89,7 +94,10 @@ module PolishInvoicer
|
|
89
94
|
|
90
95
|
if @invoice.price_paid.is_a?(Numeric)
|
91
96
|
@errors[:price_paid] = 'Kwota zapłacona musi być liczbą dodatnią' unless @invoice.price_paid >= 0
|
92
|
-
|
97
|
+
unless @invoice.price_paid <= @invoice.price
|
98
|
+
@errors[:price_paid] =
|
99
|
+
'Kwota zapłacona musi być mniejsza lub równa cenie'
|
100
|
+
end
|
93
101
|
else
|
94
102
|
@errors[:price_paid] = 'Kwota zapłacona musi być liczbą'
|
95
103
|
end
|
@@ -108,6 +116,7 @@ module PolishInvoicer
|
|
108
116
|
def check_proforma
|
109
117
|
return unless @invoice.proforma
|
110
118
|
return unless @invoice.paid
|
119
|
+
|
111
120
|
@errors[:paid] = 'Proforma nie może być opłacona'
|
112
121
|
end
|
113
122
|
|
@@ -115,15 +124,24 @@ module PolishInvoicer
|
|
115
124
|
return if @errors[:create_date]
|
116
125
|
return if @errors[:payment_date]
|
117
126
|
return if @invoice.create_date <= @invoice.payment_date
|
127
|
+
|
118
128
|
@errors[:payment_date] = 'Termin płatności nie może być wcześniejszy niż data wystawienia'
|
119
129
|
end
|
120
130
|
|
121
131
|
def check_currency
|
122
132
|
return if @errors[:currency]
|
123
133
|
return if %w[PLN EUR USD GBP].include?(@invoice.currency)
|
134
|
+
|
124
135
|
@errors[:currency] = 'Nieznana waluta'
|
125
136
|
end
|
126
137
|
|
138
|
+
def check_lang
|
139
|
+
return if blank?(@invoice.lang)
|
140
|
+
return if %w[pl pl_en en es].include?(@invoice.lang)
|
141
|
+
|
142
|
+
@errors[:lang] = 'Nieznany język'
|
143
|
+
end
|
144
|
+
|
127
145
|
def blank?(value)
|
128
146
|
value.to_s.strip == ''
|
129
147
|
end
|
data/lib/polish_invoicer/vat.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module PolishInvoicer
|
2
4
|
class Vat
|
3
5
|
def self.rates
|
@@ -6,6 +8,7 @@ module PolishInvoicer
|
|
6
8
|
|
7
9
|
def self.valid?(rate)
|
8
10
|
return true if zw?(rate)
|
11
|
+
|
9
12
|
rates.include?(rate)
|
10
13
|
end
|
11
14
|
|
@@ -16,6 +19,7 @@ module PolishInvoicer
|
|
16
19
|
|
17
20
|
def self.to_s(rate)
|
18
21
|
return 'zw.' if zw?(rate)
|
22
|
+
|
19
23
|
"#{rate}%"
|
20
24
|
end
|
21
25
|
|
@@ -1,7 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module PolishInvoicer
|
2
4
|
class Writer
|
3
|
-
attr_accessor :invoice
|
4
|
-
attr_accessor :logger, :wkhtmltopdf_path, :wkhtmltopdf_command
|
5
|
+
attr_accessor :invoice, :logger, :wkhtmltopdf_path, :wkhtmltopdf_command
|
5
6
|
|
6
7
|
def initialize(invoice)
|
7
8
|
@invoice = invoice
|
@@ -21,11 +22,7 @@ module PolishInvoicer
|
|
21
22
|
end
|
22
23
|
|
23
24
|
def template_path
|
24
|
-
tpl =
|
25
|
-
invoice.foreign_buyer ? 'proforma-en.slim' : 'proforma.slim'
|
26
|
-
else
|
27
|
-
invoice.foreign_buyer ? 'invoice-en.slim' : 'invoice.slim'
|
28
|
-
end
|
25
|
+
tpl = invoice.template_file
|
29
26
|
invoice.template_path || File.expand_path("../../../tpl/#{tpl}", __FILE__)
|
30
27
|
end
|
31
28
|
|
data/lib/polish_invoicer.rb
CHANGED
data/polish_invoicer.gemspec
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'English'
|
4
|
+
lib = File.expand_path('lib', __dir__)
|
2
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
6
|
require 'polish_invoicer/version'
|
4
7
|
|
@@ -12,16 +15,18 @@ Gem::Specification.new do |spec|
|
|
12
15
|
spec.homepage = ''
|
13
16
|
spec.license = 'MIT'
|
14
17
|
|
15
|
-
spec.files = `git ls-files`.split(
|
18
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
16
19
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
20
|
spec.require_paths = ['lib']
|
21
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
19
22
|
|
20
23
|
spec.add_development_dependency 'bundler'
|
21
|
-
spec.add_development_dependency 'rake'
|
22
24
|
spec.add_development_dependency 'minitest'
|
23
|
-
spec.add_development_dependency '
|
25
|
+
spec.add_development_dependency 'rake'
|
24
26
|
spec.add_development_dependency 'rubocop'
|
27
|
+
spec.add_development_dependency 'rubocop-minitest'
|
28
|
+
spec.add_development_dependency 'rubocop-rake'
|
29
|
+
spec.add_development_dependency 'simplecov'
|
25
30
|
|
26
31
|
spec.add_dependency 'slim2pdf'
|
27
32
|
end
|