sunat_books 0.0.2 → 0.0.3
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/.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
|