sunat_books 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DiaryEntries
4
+ def initial_entry(tickets, counts, total_sums)
5
+ initial = tickets.where(operation_type: "inicial")
6
+ if !initial.empty?
7
+ initial_data = get_row_sums(initial, counts, total_sums)
8
+ else
9
+ initial_data = []
10
+ total_sums.map do |sum|
11
+ initial_data << { content: formated_number(sum.total), align: :right }
12
+ end
13
+ end
14
+ initial_data
15
+ end
16
+
17
+ def buys_entry(tickets, counts, total_sums, data, period_date)
18
+ buys = tickets.where(operation_type: "compras")
19
+ title = "COMPRAS DEL PERIODO"
20
+ return unless buys.count.positive?
21
+ # buys entry
22
+ buys_sum = get_row_sums(buys, counts, total_sums)
23
+ data << [period_date, title, buys_sum].flatten
24
+ end
25
+
26
+ def sales_entry(tickets, counts, total_sums, data, period_date)
27
+ sales = tickets.where(operation_type: "ventas")
28
+ title = "VENTAS DEL PERIODO"
29
+ return unless sales.count.positive?
30
+ sales_sum = get_row_sums(sales, counts, total_sums)
31
+ data << [period_date, title, sales_sum].flatten
32
+ end
33
+
34
+ def other_entry(tickets, counts, total_sums, data)
35
+ # other entries
36
+ others = tickets.where(operation_type: "otros")
37
+ # others_row = get_row_sums(others, counts, total_sums)
38
+ others&.each do |ticket|
39
+ ticket_data = []
40
+ counts.each_with_index do |count, i|
41
+ value = mother_count?(count, ticket) ? get_value(ticket, count) : 0
42
+ increase_value(ticket_data, total_sums, i, value)
43
+ end
44
+ ref = ticket.reference
45
+ data << [parse_day(ticket.operation_date), ref, ticket_data].flatten
46
+ end
47
+ end
48
+
49
+ def close_entry(tickets, counts, total_sums, data)
50
+ close = tickets.where(operation_type: "cierre")
51
+ close.each do |ticket|
52
+ ticket_data = []
53
+ counts.each_with_index do |count, i|
54
+ value = mother_count?(count, ticket) ? get_value(ticket, count) : 0
55
+ increase_value(ticket_data, total_sums, i, value)
56
+ end
57
+ ref = ticket.reference
58
+ data << [parse_day(ticket.operation_date), ref, ticket_data].flatten
59
+ end
60
+ end
61
+
62
+ def total_entry(total_sums, data)
63
+ # totals
64
+ total_data = []
65
+ total_sums.map do |sum|
66
+ total_data << { content: formated_number(sum.total), align: :right }
67
+ end
68
+ data << [{ content: "TOTALES", colspan: 2 }, total_data].flatten
69
+ end
70
+
71
+ def mother_count?(count, ticket)
72
+ ticket.uniq_mother_counts.include?(count)
73
+ end
74
+
75
+ def calculate_totals(tickets, count_sums)
76
+ # get totals
77
+ tickets.each do |ticket|
78
+ count_sums.each do |count_sum|
79
+ count_sum.add get_value(ticket, count_sum.count)
80
+ end
81
+ end
82
+ end
83
+
84
+ def current_sum_count(count_sums, count)
85
+ sum_count = nil
86
+ count_sums.each do |count_sum|
87
+ sum_count = count_sum if count_sum.count == count
88
+ end
89
+ sum_count
90
+ end
91
+
92
+ def get_row_sums(tickets, counts, total_sums)
93
+ # given an array of counts and tickets get sums by each count
94
+ row_counts = get_mother_counts tickets
95
+ count_sums = row_counts.map { |count| Books::CountSum.new(count) }
96
+
97
+ calculate_totals(tickets, count_sums)
98
+ # get ordered row
99
+ row_data = []
100
+ counts.each_with_index do |count, i|
101
+ sum_count = current_sum_count(count_sums, count)
102
+ value = sum_count ? sum_count.total : 0
103
+ increase_value(row_data, total_sums, i, value)
104
+ end
105
+ row_data
106
+ end
107
+
108
+ def increase_value(row_data, total_sums, i, value)
109
+ total_sums[i].add value
110
+ row_data << { content: formated_number(value), align: :right }
111
+ end
112
+ end
@@ -11,7 +11,7 @@ headers:
11
11
  - client_document_number
12
12
  - client_name
13
13
  - export_value
14
- - taxable_bi #- bi_taxable_operation
14
+ - taxable_bi
15
15
  - sale_non_taxable:
16
16
  - exo
17
17
  - inaf
@@ -21,7 +21,7 @@ headers:
21
21
  - total_operation_sales
22
22
  - exchange_rate
23
23
  - credit_origina_document:
24
- - credit_original_document_date #
24
+ - credit_original_document_date
25
25
  - credit_original_document_type
26
26
  - credit_original_document_serial
27
27
  - credit_original_document_number
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "i18n"
4
+
5
+ I18n.load_path << "#{File.dirname(__FILE__)}/locales/es.yml"
6
+ I18n.default_locale = :es
@@ -0,0 +1,65 @@
1
+ es:
2
+ books:
3
+ buys:
4
+ correlative: "Nro"
5
+ operation_date: "Fecha de Emisión"
6
+ pay_date: "Fecha de Venc"
7
+ document: "Documento"
8
+ doc_type: "T"
9
+ document_serial: "Serie"
10
+ year_emition: "AÑO DUA DSI"
11
+ document_number: "N° documen"
12
+ supplier: "Proveedor"
13
+ supplier_document_type: "t"
14
+ supplier_document_number: "N° documen"
15
+ supplier_name: "Nombre o razón social"
16
+ taxable_to_taxable_export: "adquisiciones grav. dest. a oper. gravadas y/o de exportac."
17
+ taxable_to_taxable_export_bi: "bi"
18
+ taxable_to_taxable_export_igv: "igv"
19
+ taxable_to_taxable_export_non_taxable: "adquisiciones gravadas dest. a oper. grav. y/o exportac. y a oper. no gravadas"
20
+ taxable_to_taxable_export_non_taxable_bi: "bi"
21
+ taxable_to_taxable_export_non_taxable_igv: "igv"
22
+ taxable_to_non_taxable: "adquisiciones gravadas destinadas a operaciones no gravadas"
23
+ taxable_to_non_taxable_bi: "bi"
24
+ taxable_to_non_taxable_igv: "igv"
25
+ non_taxable: "adquisiciones no gravadas"
26
+ isc: "isc"
27
+ other_taxs: "otros tributos y cargos"
28
+ total_operation_buys: "importe total"
29
+ foreign_pay_document_number: "n° comprobante pago emitido por no domiciliado"
30
+ detraction: "detracción"
31
+ detraction_number: "número"
32
+ detraction_date: "fech emis"
33
+ exchange_rate: "tipo de cambio"
34
+ debit_original_document: "referencia del comprobante de pago que se modifica"
35
+ debit_original_document_date: "Fecha"
36
+ debit_original_document_type: "t"
37
+ debit_original_document_serial: "serie"
38
+ debit_original_document_number: "n° doc"
39
+ sales:
40
+ correlative: "nro"
41
+ operation_date: "Fecha de Emisión"
42
+ pay_date: "Fecha de Venc"
43
+ document: "Documento"
44
+ doc_type: "T"
45
+ document_serial: "Serie"
46
+ document_number: "N° documen"
47
+ client: "Cliente"
48
+ client_document_type: "t"
49
+ client_document_number: "N° documen"
50
+ client_name: "Nombre o razón social"
51
+ export_value: "Valor exportac"
52
+ taxable_bi: "BI operac gravadas"
53
+ sale_non_taxable: "operacion. exoneradas o inafectas"
54
+ exo: "Exo"
55
+ inaf: "Inaf"
56
+ isc: "ISC"
57
+ igv: "IGV"
58
+ other_taxs: "Otros tributos"
59
+ total_operation_sales: "importe total"
60
+ exchange_rate: "tipo de cambio"
61
+ credit_origina_document: "referencia de documento original que se modifica"
62
+ credit_original_document_date: "Fec"
63
+ credit_original_document_type: "t"
64
+ credit_original_document_serial: "serie"
65
+ credit_original_document_number: "n° doc"
data/lib/books/page.rb ADDED
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Books
6
+ class Page < Base
7
+ attr_accessor :length, :bi_sum, :igv_sum, :total_sum, :non_taxable, :data
8
+
9
+ def initialize(page_number, length)
10
+ @page_number = page_number
11
+ @length = length
12
+ @bi_sum = BigDecimal(0)
13
+ @igv_sum = BigDecimal(0)
14
+ @total_sum = BigDecimal(0)
15
+ @non_taxable = BigDecimal(0)
16
+ @data = []
17
+ end
18
+
19
+ def update_data_buys(ticket)
20
+ @bi_sum += ticket.taxable_to_taxable_export_bi.round(2)
21
+ @igv_sum += ticket.taxable_to_taxable_export_igv.round(2)
22
+ @total_sum += ticket.total_operation_buys.round(2)
23
+ @non_taxable += ticket.non_taxable unless ticket.non_taxable.nil?
24
+ end
25
+
26
+ def update_data_sales(ticket)
27
+ @bi_sum += ticket.taxable_bi.round(2)
28
+ @igv_sum += ticket.igv.round(2)
29
+ @total_sum += ticket.total_operation_sales.round(2)
30
+ end
31
+
32
+ def update_fields(fields = nil, source = nil)
33
+ # update fields from a given source
34
+ return if source.nil?
35
+ fields&.each do |field|
36
+ begin
37
+ send("#{field}=", source.send(field))
38
+ rescue
39
+ return nil
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "page"
4
+
5
+ module PagesUtils
6
+ def page_not_full(last_page, pages, page_max, &block)
7
+ if last_page.length < page_max
8
+ last_page.length += 1
9
+ last_page
10
+ else
11
+ yield if block
12
+ new_page = setup_new_page(pages, last_page, 2)
13
+ new_page
14
+ end
15
+ end
16
+
17
+ def setup_pages(pages, length, page_max, index = 1)
18
+ pages_num = (length / page_max.to_f).ceil
19
+ last_index = index.zero? ? pages_num - 1 : pages_num
20
+ (index..last_index).each do |i|
21
+ pages[i] = Books::Page.new(i, 0)
22
+ end
23
+ end
24
+
25
+ def setup_new_page(pages, last_page, length)
26
+ return if last_page.page_number == pages.count
27
+ new_page = pages[last_page.page_number + 1]
28
+ fields = %w[bi_sum igv_sum total_sum non_taxable]
29
+ new_page.update_fields(fields, last_page)
30
+ new_page.length += length
31
+ new_page
32
+ end
33
+
34
+ def page_index(i, page_max)
35
+ i.zero? ? 1 : (i / page_max.to_f).ceil
36
+ end
37
+
38
+ def not_moviment_page(data)
39
+ data << [content: "SIN MOVIMIENTO EN EL PERIODO", colspan: 5]
40
+ end
41
+
42
+ def setup_final_row_data(page, ticket, data)
43
+ if page.length == @page_max && @tickets.last != ticket
44
+ data << final_row("VAN", page)
45
+ elsif @tickets.last == ticket
46
+ data << final_row("TOTAL", page)
47
+ end
48
+ end
49
+
50
+ def row_data(data, widths, aligns, fields, operation)
51
+ @tickets.each_with_index do |ticket, i|
52
+ last_page = @pages[page_index(i, @page_max)]
53
+ page = page_not_full(last_page, @pages, @page_max) do
54
+ data << final_row("VIENEN", last_page)
55
+ end
56
+ data << table_body(fields, ticket, widths, aligns)
57
+ page.send("update_data_#{operation}", ticket)
58
+ setup_final_row_data(page, ticket, data)
59
+ end
60
+ end
61
+
62
+ # for diary
63
+ def split_data(data, max_column)
64
+ # split rows data in pages according max_column
65
+ pages = []
66
+ setup_pages(pages, data.first.count, max_column, 0)
67
+ data&.each_with_index do |row, i|
68
+ if i == data.length - 1
69
+ setup_row_pages(pages, row, max_column - 1, 1)
70
+ else
71
+ setup_row_pages(pages, row, max_column)
72
+ end
73
+ end
74
+ pages
75
+ end
76
+
77
+ def setup_row_pages(pages, row, max_column, first_rows = 2)
78
+ initial_rows = row.first(first_rows)
79
+ batches_length = max_column - first_rows
80
+ left_data = row[first_rows..row.length].in_groups_of(batches_length, false)
81
+ pages.each_with_index do |page, i|
82
+ page.data << (initial_rows + left_data[i])
83
+ end
84
+ end
85
+ end
data/lib/books/sales.rb CHANGED
@@ -1,114 +1,73 @@
1
- require 'books/base'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+ require_relative "pages_utils"
2
5
 
3
6
  module Books
4
7
  class Sales < Base
8
+ include PagesUtils
9
+
5
10
  def initialize(company, tickets, view, month, year)
11
+ # company => an object that respond to ruc and name methods
12
+ # tickets => an array of objects that respond to a layout's methods
13
+ # view => a view context
14
+ # month => a number that represent a month
15
+ # year => a number that represent a year
6
16
  super(page_layout: :landscape, margin: [5], page_size: "A4")
7
17
  @view = view
8
18
  @company = company
9
19
  @period = get_period(month, year)
10
- @pages = {}
11
20
  @tickets = tickets
12
21
  @book_name = self.class.name.downcase.sub("books::", "")
13
22
  dir = File.dirname(__FILE__)
14
23
  @blayout = YAML.load_file("#{dir}/layouts/#{@book_name}.yml")
15
24
  @page_max = 29
16
25
 
17
- repeat(:all) do
18
- canvas do
19
- bounding_box([bounds.left + 10, bounds.top - 10], width: 800) do
20
- # book_title "REGISTRO DE VENTAS"
21
- book_header @period, @company.ruc, @company.name, "REGISTRO DE VENTAS"
22
- end
23
- end
24
- end
26
+ prawn_book
27
+ end
25
28
 
26
- bounding_box([bounds.left + 3, bounds.top - 45], width: 800, height: 530) do
27
- book_body
28
- end
29
+ def prawn_book
30
+ prawn_header "REGISTRO DE VENTAS", @period, @company
31
+ @pages = []
29
32
 
30
- repeat(:all, dynamic: true) do
31
- canvas do
32
- bounding_box([235, 50], width: 700) do
33
- # book_footer
34
- end
35
- end
33
+ bounding_box([bounds.left + 3, bounds.top - 45], width: 800,
34
+ height: 530) do
35
+ setup_pages(@pages, @tickets.length, @page_max)
36
+ book_body
36
37
  end
37
38
  end
38
39
 
39
40
  def book_body
40
- length = @tickets.length
41
- page_num = (length / 29.0).ceil
42
- page_num.times do |i|
43
- @pages[i + 1] = {
44
- page_number: i + 1,
45
- length: 0,
46
- bi_sum: BigDecimal(0)
47
- }
48
- end
49
-
50
41
  move_down 5
51
- fields = @blayout["headers"]
52
- widths = @blayout["widths"]
53
- aligns = @blayout["align"]
54
42
  data = []
43
+ fields = @blayout["headers"]
55
44
  data << table_head(fields, @book_name, @blayout)
56
45
 
57
- n = 1
58
- bi_sum = BigDecimal(0)
59
- igv_sum = BigDecimal(0)
60
- total_sum = BigDecimal(0)
61
- non_taxable = BigDecimal(0)
62
-
63
- if length > 0
64
- @tickets.each do |ticket|
65
-
66
- if @pages[n][:length] < @page_max
67
- page = @pages[n]
68
- page[:length] += 1
69
- else
70
- data << final_row('VIENEN', @pages[n])
71
- page = @pages[n + 1]
72
- n += 1
73
- page[:length] += 2
74
- end
75
-
76
- data << table_body(fields, ticket, widths, aligns)
77
-
78
- bi_sum += ticket.taxable_bi
79
- igv_sum += ticket.igv
80
- total_sum += ticket.total_operation_sales
81
- page[:bi_sum] = bi_sum.round(2)
82
- page[:igv_sum] = igv_sum.round(2)
83
- page[:total_sum] = total_sum.round(2)
84
- if page[:length] == @page_max && @tickets.last != ticket
85
- data << final_row('VAN', page)
86
- elsif @tickets.last == ticket
87
- data << final_row('TOTAL', page)
88
- end
89
- end
46
+ if @tickets.length.positive?
47
+ row_data(data, @blayout["widths"], @blayout["align"], fields, "sales")
90
48
  else
91
- data << [content: 'SIN MOVIMIENTO EN EL PERIODO', colspan: 5]
92
- @pages[n] = {}
93
- page = @pages[n]
94
- page[:bi_sum] = zero
95
- page[:igv_sum] = zero
96
- page[:total_sum] = zero
49
+ not_moviment_page(data)
97
50
  end
98
51
 
99
- table(data, header: true, cell_style: { borders: [], size: 5,
100
- align: :right },
101
- column_widths: {0 => 22, 1 => 35, 2 => 30, 5 => 27, 6 => 37,
102
- 8 => 20, 9 => 33, 10 => 27, 11 => 35, 12 => 29}) do
103
- row(0).borders = [:bottom, :top]
52
+ render_prawn_table(data)
53
+ end
54
+
55
+ def render_prawn_table(data)
56
+ widths_columns = { 0 => 22, 1 => 35, 2 => 30, 5 => 27, 6 => 37, 8 => 20,
57
+ 9 => 33, 10 => 27, 11 => 35, 12 => 29 }
58
+
59
+ table(data, header: true,
60
+ cell_style: { borders: [], size: 5, align: :right },
61
+ column_widths: widths_columns) do
62
+ row(0).borders = %i[bottom top]
104
63
  end
105
64
  end
106
65
 
107
- def final_row foot_line_text, page
108
- [ {content: foot_line_text, colspan: 5}, zero,
109
- formated_number(page[:bi_sum]), make_sub_table([zero, zero], 22), zero,
110
- formated_number(page[:igv_sum]), zero,
111
- formated_number(page[:total_sum])]
66
+ def final_row(foot_line_text, page)
67
+ [{ content: foot_line_text, colspan: 5 }, zero,
68
+ formated_number(page.bi_sum), make_sub_table([zero, zero], 22), zero,
69
+ formated_number(page.igv_sum), zero,
70
+ formated_number(page.total_sum)]
112
71
  end
113
72
  end
114
73
  end