sunat_books 0.0.2 → 0.0.3
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/.rvmrc +1 -0
- data/.travis.yml +2 -5
- data/README.mkd +9 -3
- data/lib/sunat_books.rb +6 -6
- data/lib/sunat_books/common_utils.rb +9 -0
- data/lib/sunat_books/csv/base.rb +63 -0
- data/lib/sunat_books/csv/option_error.rb +8 -0
- data/lib/sunat_books/pdf/base.rb +134 -0
- data/lib/sunat_books/pdf/buys.rb +36 -0
- data/lib/sunat_books/pdf/count_sum.rb +24 -0
- data/lib/{books → sunat_books/pdf}/diary_entries.rb +1 -3
- data/lib/{books → sunat_books/pdf}/layouts/buys.yml +0 -0
- data/lib/{books → sunat_books/pdf}/layouts/sales.yml +0 -0
- data/lib/{books → sunat_books/pdf}/locale.rb +0 -0
- data/lib/{books → sunat_books/pdf}/locales/es.yml +0 -0
- data/lib/sunat_books/pdf/page.rb +48 -0
- data/lib/{books → sunat_books/pdf}/pages_utils.rb +1 -1
- data/lib/sunat_books/pdf/sales.rb +35 -0
- data/lib/sunat_books/pdf/simplified_diary.rb +94 -0
- data/lib/sunat_books/pdf/trading_book.rb +50 -0
- data/lib/{books → sunat_books/pdf}/utils.rb +4 -6
- data/lib/sunat_books/ple/base.rb +76 -0
- data/lib/sunat_books/ple/buys.rb +38 -0
- data/lib/{ple_books → sunat_books/ple}/layouts/buys.yml +0 -0
- data/lib/{ple_books → sunat_books/ple}/layouts/sales.yml +0 -0
- data/lib/sunat_books/ple/sales.rb +22 -0
- data/sunat_books.gemspec +2 -2
- data/test/{csv_books → csv}/base_test.rb +8 -5
- data/test/{books → pdf}/base_test.rb +0 -0
- data/test/pdf/buys_test.rb +27 -0
- data/test/{books → pdf}/page_test.rb +4 -4
- data/test/{books → pdf}/pages_utils_test.rb +32 -2
- data/test/pdf/sales_test.rb +15 -0
- data/test/{books → pdf}/utils_test.rb +7 -1
- data/test/{ple_books_test.rb → ple/base_test.rb} +2 -2
- data/test/{ple_books → ple}/buys_test.rb +8 -8
- metadata +38 -35
- data/Gemfile.lock +0 -83
- data/lib/books/base.rb +0 -132
- data/lib/books/buys.rb +0 -72
- data/lib/books/count_sum.rb +0 -22
- data/lib/books/page.rb +0 -44
- data/lib/books/sales.rb +0 -73
- data/lib/books/simplified_diary.rb +0 -97
- data/lib/csv_books/base.rb +0 -67
- data/lib/csv_books/option_error.rb +0 -6
- data/lib/ple_books/base.rb +0 -75
- data/lib/ple_books/buys.rb +0 -36
- data/lib/ple_books/sales.rb +0 -20
- data/test/books/buys_test.rb +0 -57
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 709258f206c12128dc3767eab4a1dad442905cd0
|
4
|
+
data.tar.gz: 90aec2c66bad2f061d0a782d56dfbd787b50ad76
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddb4b6af254003a306535f3df550a052737ba443c38a8f25e594bb4d83969f6d49f5f473f52c182303409f507569d14e557e812df258df2f0e87c552b158bd0c
|
7
|
+
data.tar.gz: 565b98f45c56f0fa74ef8b37e3316b969806ce869e0e17ff46f226fd19e4f6fd09dce33f5cb44705069422200f1d58bd64478648caf6387420c5242ae4c953c3
|
data/.gitignore
CHANGED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create use 2.4.1@sunat_books
|
data/.travis.yml
CHANGED
data/README.mkd
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# Sunat Books
|
2
2
|
[![Gem Version][rubygems-image]][rubygems-url]
|
3
3
|
[![Build Status][travis-image]][travis-url]
|
4
|
+
[![Code Climate][code-climate-image]][code-climate-url]
|
5
|
+
[![Dependency Status][gemnasium-image]][gemnasium-url]
|
4
6
|
|
5
|
-
> A ruby gem
|
7
|
+
> A ruby gem to get accounting books for [SUNAT](https://www.sunat.gob.pe)
|
6
8
|
|
7
9
|
## Install
|
8
10
|
You can install via
|
@@ -23,17 +25,21 @@ require 'sunat_books'
|
|
23
25
|
to get a pdf format
|
24
26
|
|
25
27
|
```ruby
|
26
|
-
pdf =
|
28
|
+
pdf = SunatBooks::Pdf::Buys.new(company, tickets, month, year)
|
27
29
|
pdf.render
|
28
30
|
```
|
29
31
|
|
30
32
|
to get the txt file for electronic books
|
31
33
|
|
32
34
|
```ruby
|
33
|
-
ple =
|
35
|
+
ple = SunatBooks::Ple::Buys.new(ruc, tickets, month, year)
|
34
36
|
```
|
35
37
|
|
36
38
|
[rubygems-image]: https://badge.fury.io/rb/sunat_books.svg
|
37
39
|
[rubygems-url]: https://badge.fury.io/rb/sunat_books
|
38
40
|
[travis-image]: https://travis-ci.org/ccarruitero/sunat_books.svg?branch=master
|
39
41
|
[travis-url]: https://travis-ci.org/ccarruitero/sunat_books
|
42
|
+
[code-climate-image]: https://codeclimate.com/github/ccarruitero/sunat_books/badges/gpa.svg
|
43
|
+
[code-climate-url]: https://codeclimate.com/github/ccarruitero/sunat_books
|
44
|
+
[gemnasium-image]: https://gemnasium.com/ccarruitero/sunat_books.png
|
45
|
+
[gemnasium-url]: https://gemnasium.com/ccarruitero/sunat_books
|
data/lib/sunat_books.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: false
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
require "sunat_books/pdf/buys"
|
4
|
+
require "sunat_books/pdf/sales"
|
5
|
+
require "sunat_books/pdf/simplified_diary"
|
6
|
+
require "sunat_books/ple/buys"
|
7
|
+
require "sunat_books/ple/sales"
|
8
|
+
require "sunat_books/csv/base"
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "csv"
|
4
|
+
require_relative "option_error"
|
5
|
+
require_relative "../common_utils"
|
6
|
+
|
7
|
+
module SunatBooks
|
8
|
+
module Csv
|
9
|
+
class Base
|
10
|
+
include SunatBooks::CommonUtils
|
11
|
+
|
12
|
+
attr_accessor :file
|
13
|
+
|
14
|
+
def initialize(tickets, options = {})
|
15
|
+
# options
|
16
|
+
# - layout => Array of strings used to get data for csv
|
17
|
+
# - filename
|
18
|
+
if options[:layout].nil?
|
19
|
+
raise SunatBooks::Csv::OptionError, "Layout option is required"
|
20
|
+
end
|
21
|
+
filename = options[:filename] || "#{tmp_path}book.csv"
|
22
|
+
fields = options[:layout]
|
23
|
+
get_file(filename, fields, tickets)
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_file(filename, fields, tickets)
|
27
|
+
send("file=", filename)
|
28
|
+
File.exist?(filename) ? File.delete(filename) : nil
|
29
|
+
FileUtils.touch(filename)
|
30
|
+
append_headers(filename, fields)
|
31
|
+
append_data(tickets, filename, fields)
|
32
|
+
end
|
33
|
+
|
34
|
+
def tmp_path
|
35
|
+
dir = File.dirname(__FILE__)
|
36
|
+
tmp_path = "#{dir}/tmp/"
|
37
|
+
Dir.mkdir(tmp_path) unless Dir.exist?(tmp_path)
|
38
|
+
tmp_path
|
39
|
+
end
|
40
|
+
|
41
|
+
def append_headers(filename, fields)
|
42
|
+
append_to_csv(filename, fields, "w+")
|
43
|
+
end
|
44
|
+
|
45
|
+
def append_data(tickets, filename, fields)
|
46
|
+
tickets&.each do |ticket|
|
47
|
+
data = []
|
48
|
+
fields&.each do |field|
|
49
|
+
data << available_value?(ticket, field)
|
50
|
+
end
|
51
|
+
append_to_csv(filename, data, "a+")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def append_to_csv(filename, data, mode)
|
56
|
+
return if data.nil?
|
57
|
+
CSV.open(filename, mode) do |csv|
|
58
|
+
csv << data
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "prawn"
|
4
|
+
require "prawn/table"
|
5
|
+
require "yaml"
|
6
|
+
require_relative "utils"
|
7
|
+
require_relative "locale"
|
8
|
+
|
9
|
+
module SunatBooks
|
10
|
+
module Pdf
|
11
|
+
class Base < Prawn::Document
|
12
|
+
include Utils
|
13
|
+
include Prawn::Table::Interface
|
14
|
+
|
15
|
+
def sub_head(hash, book_name, blayout)
|
16
|
+
arr, current_key = nil
|
17
|
+
hash.each do |key, value|
|
18
|
+
k = I18n.t("books.#{book_name}.#{key}").mb_chars.upcase.to_s
|
19
|
+
v = value.collect do |s|
|
20
|
+
I18n.t("books.#{book_name}.#{s}").mb_chars.upcase.to_s
|
21
|
+
end
|
22
|
+
arr = [[{ content: k, colspan: value.length }], v]
|
23
|
+
current_key = key
|
24
|
+
end
|
25
|
+
|
26
|
+
sub_head_table(blayout["widths"], arr, current_key)
|
27
|
+
end
|
28
|
+
|
29
|
+
def sub_head_table(widths, arr, key)
|
30
|
+
column_widths = get_column_widths(widths, key)
|
31
|
+
options = sub_head_options(column_widths)
|
32
|
+
make_table(arr, options)
|
33
|
+
end
|
34
|
+
|
35
|
+
def sub_head_options(column_widths)
|
36
|
+
options = { cell_style: {
|
37
|
+
borders: [], size: 5, align: :center, padding: 1
|
38
|
+
} }
|
39
|
+
add_widths(column_widths, options, 22)
|
40
|
+
options
|
41
|
+
end
|
42
|
+
|
43
|
+
def book_title(title)
|
44
|
+
text title, align: :center, size: 8
|
45
|
+
end
|
46
|
+
|
47
|
+
def book_header(period, ruc, name, title = nil)
|
48
|
+
move_down 5
|
49
|
+
txt name.to_s.upcase
|
50
|
+
txt "RUC: #{ruc}"
|
51
|
+
book_title("#{title} - #{period}")
|
52
|
+
move_down 5
|
53
|
+
end
|
54
|
+
|
55
|
+
def prawn_header(title, period, company)
|
56
|
+
repeat(:all) do
|
57
|
+
canvas do
|
58
|
+
bounding_box([bounds.left + 10, bounds.top - 10], width: 800) do
|
59
|
+
book_header period, company.ruc, company.name, title
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def table_head(fields, book_name, layout)
|
66
|
+
thead = []
|
67
|
+
fields.each do |h|
|
68
|
+
if h.class == Hash
|
69
|
+
r = sub_head(h, book_name, layout)
|
70
|
+
thead << r
|
71
|
+
else
|
72
|
+
thead << I18n.t("books.#{book_name}.#{h}").mb_chars.upcase.to_s
|
73
|
+
end
|
74
|
+
end
|
75
|
+
thead
|
76
|
+
end
|
77
|
+
|
78
|
+
def table_body(fields, ticket, widths, aligns)
|
79
|
+
tbody = []
|
80
|
+
fields.each do |f|
|
81
|
+
if f.is_a? Hash
|
82
|
+
table_hash(f, ticket, tbody, widths, aligns)
|
83
|
+
else
|
84
|
+
tbody << field_value(ticket, f)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
tbody
|
88
|
+
end
|
89
|
+
|
90
|
+
def table_hash(f, ticket, tbody, widths, aligns)
|
91
|
+
options = { cell_style: { borders: [], size: 5 } }
|
92
|
+
|
93
|
+
f.each do |key, value|
|
94
|
+
v = value.collect do |s|
|
95
|
+
value = field_value(ticket, s)
|
96
|
+
end
|
97
|
+
|
98
|
+
column_widths = get_column_widths(widths, key)
|
99
|
+
add_widths(column_widths, options, 28)
|
100
|
+
add_align(aligns, options, key) unless aligns.nil?
|
101
|
+
tbody << make_table([v], options)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# diary
|
106
|
+
def get_counts(tickets)
|
107
|
+
tickets.map(&:uniq_counts).flatten.uniq.sort
|
108
|
+
end
|
109
|
+
|
110
|
+
def get_mother_counts(tickets)
|
111
|
+
tickets.map(&:uniq_mother_counts).flatten.uniq.sort
|
112
|
+
end
|
113
|
+
|
114
|
+
def get_value(ticket, count)
|
115
|
+
# active_amount = ticket.get_amount_by_position(count)
|
116
|
+
# pasive_amount = ticket.get_amount_by_position(count, false)
|
117
|
+
active_amount = ticket.get_amount_by_mother_count(count)
|
118
|
+
pasive_amount = ticket.get_amount_by_mother_count(count, false)
|
119
|
+
# if count === '401' && ticket.operation_type == 'compras'
|
120
|
+
# amount = amount * (-1)
|
121
|
+
# end
|
122
|
+
active_amount - pasive_amount
|
123
|
+
end
|
124
|
+
|
125
|
+
def make_sub_table(content, width = nil)
|
126
|
+
options = { cell_style: { width: width, size: 5, borders: [],
|
127
|
+
align: :right } }
|
128
|
+
content_row = []
|
129
|
+
content.each { |c| content_row << formated_number(c) }
|
130
|
+
make_table([content_row], options)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "trading_book"
|
4
|
+
require_relative "pages_utils"
|
5
|
+
|
6
|
+
module SunatBooks
|
7
|
+
module Pdf
|
8
|
+
class Buys < TradingBook
|
9
|
+
include PagesUtils
|
10
|
+
|
11
|
+
def initialize(company, tickets, month, year)
|
12
|
+
super
|
13
|
+
prawn_book("REGISTRO DE COMPRAS", 27)
|
14
|
+
end
|
15
|
+
|
16
|
+
def final_row(foot_line_text, page)
|
17
|
+
[{ content: foot_line_text, colspan: 5 },
|
18
|
+
make_sub_table([page.bi_sum, page.igv_sum], 32),
|
19
|
+
make_sub_table([zero, zero], 25),
|
20
|
+
make_sub_table([zero, zero], 25),
|
21
|
+
formated_number(page.non_taxable),
|
22
|
+
zero, zero,
|
23
|
+
formated_number(page.total_sum)]
|
24
|
+
end
|
25
|
+
|
26
|
+
def render_prawn_table(data)
|
27
|
+
table(data, header: true, cell_style: { borders: [], size: 5,
|
28
|
+
align: :right },
|
29
|
+
column_widths: { 0 => 22, 1 => 35, 2 => 30, 8 => 30,
|
30
|
+
10 => 30, 9 => 22, 11 => 33, 12 => 33 }) do
|
31
|
+
row(0).borders = %i[bottom top]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SunatBooks
|
4
|
+
module Pdf
|
5
|
+
class CountSum
|
6
|
+
def initialize(count_number, initial_value = BigDecimal(0))
|
7
|
+
@sum = initial_value
|
8
|
+
@count_number = count_number
|
9
|
+
end
|
10
|
+
|
11
|
+
def add(value)
|
12
|
+
@sum += value
|
13
|
+
end
|
14
|
+
|
15
|
+
def count
|
16
|
+
@count_number
|
17
|
+
end
|
18
|
+
|
19
|
+
def total
|
20
|
+
@sum
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -18,7 +18,6 @@ module DiaryEntries
|
|
18
18
|
buys = tickets.where(operation_type: "compras")
|
19
19
|
title = "COMPRAS DEL PERIODO"
|
20
20
|
return unless buys.count.positive?
|
21
|
-
# buys entry
|
22
21
|
buys_sum = get_row_sums(buys, counts, total_sums)
|
23
22
|
data << [period_date, title, buys_sum].flatten
|
24
23
|
end
|
@@ -32,7 +31,6 @@ module DiaryEntries
|
|
32
31
|
end
|
33
32
|
|
34
33
|
def other_entry(tickets, counts, total_sums, data)
|
35
|
-
# other entries
|
36
34
|
others = tickets.where(operation_type: "otros")
|
37
35
|
# others_row = get_row_sums(others, counts, total_sums)
|
38
36
|
others&.each do |ticket|
|
@@ -92,7 +90,7 @@ module DiaryEntries
|
|
92
90
|
def get_row_sums(tickets, counts, total_sums)
|
93
91
|
# given an array of counts and tickets get sums by each count
|
94
92
|
row_counts = get_mother_counts tickets
|
95
|
-
count_sums = row_counts.map { |count|
|
93
|
+
count_sums = row_counts.map { |count| SunatBooks::Pdf::CountSum.new(count) }
|
96
94
|
|
97
95
|
calculate_totals(tickets, count_sums)
|
98
96
|
# get ordered row
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
module SunatBooks
|
6
|
+
module Pdf
|
7
|
+
class Page < Base
|
8
|
+
attr_accessor :length, :bi_sum, :igv_sum, :total_sum, :non_taxable, :data
|
9
|
+
|
10
|
+
def initialize(page_number, length)
|
11
|
+
@page_number = page_number
|
12
|
+
@length = length
|
13
|
+
@bi_sum = BigDecimal(0)
|
14
|
+
@igv_sum = BigDecimal(0)
|
15
|
+
@total_sum = BigDecimal(0)
|
16
|
+
@non_taxable = BigDecimal(0)
|
17
|
+
@data = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def update_data_buys(ticket)
|
21
|
+
@bi_sum += ticket.taxable_to_taxable_export_bi.round(2)
|
22
|
+
@igv_sum += ticket.taxable_to_taxable_export_igv.round(2)
|
23
|
+
@total_sum += ticket.total_operation_buys.round(2)
|
24
|
+
@non_taxable += ticket.non_taxable unless ticket.non_taxable.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
def update_data_sales(ticket)
|
28
|
+
@bi_sum += ticket.taxable_bi.round(2)
|
29
|
+
@igv_sum += ticket.igv.round(2)
|
30
|
+
@total_sum += ticket.total_operation_sales.round(2)
|
31
|
+
end
|
32
|
+
|
33
|
+
def update_fields(fields = nil, source = nil)
|
34
|
+
# update fields from a given source
|
35
|
+
return if source.nil?
|
36
|
+
fields&.each do |field|
|
37
|
+
send("#{field}=", source.send(field)) if available?(field, source)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def available?(field, source)
|
44
|
+
respond_to?("#{field}=") && source.respond_to?(field)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|