rock_books 0.6.1 → 0.10.0
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/README.md +8 -10
- data/RELEASE_NOTES.md +57 -10
- data/assets/fonts/JetBrainsMono-Medium.ttf +0 -0
- data/lib/rock_books/cmd_line/command_line_interface.rb +15 -24
- data/lib/rock_books/cmd_line/main.rb +1 -9
- data/lib/rock_books/documents/book_set.rb +5 -2
- data/lib/rock_books/documents/chart_of_accounts.rb +29 -12
- data/lib/rock_books/documents/journal.rb +3 -8
- data/lib/rock_books/documents/journal_entry.rb +7 -2
- data/lib/rock_books/documents/journal_entry_builder.rb +4 -0
- data/lib/rock_books/helpers/book_set_loader.rb +3 -3
- data/lib/rock_books/reports/balance_sheet.rb +9 -43
- data/lib/rock_books/reports/book_set_reporter.rb +138 -106
- data/lib/rock_books/reports/data/bs_is_data.rb +61 -0
- data/lib/rock_books/reports/data/bs_is_section_data.rb +30 -0
- data/lib/rock_books/reports/data/journal_data.rb +38 -0
- data/lib/rock_books/reports/data/multidoc_txn_by_account_data.rb +40 -0
- data/lib/rock_books/reports/data/multidoc_txn_report_data.rb +39 -0
- data/lib/rock_books/reports/data/receipts_report_data.rb +47 -0
- data/lib/rock_books/reports/data/tx_one_account_data.rb +37 -0
- data/lib/rock_books/reports/helpers/erb_helper.rb +21 -0
- data/lib/rock_books/reports/helpers/receipts_hyperlink_converter.rb +59 -0
- data/lib/rock_books/reports/helpers/text_report_helper.rb +144 -0
- data/lib/rock_books/reports/income_statement.rb +9 -47
- data/lib/rock_books/reports/index_html_page.rb +27 -0
- data/lib/rock_books/reports/journal_report.rb +82 -0
- data/lib/rock_books/reports/multidoc_txn_by_account_report.rb +32 -0
- data/lib/rock_books/reports/multidoc_txn_report.rb +25 -0
- data/lib/rock_books/reports/receipts_report.rb +6 -55
- data/lib/rock_books/reports/templates/html/index.html.erb +158 -0
- data/lib/rock_books/reports/templates/html/report_page.html.erb +25 -0
- data/lib/rock_books/reports/templates/text/_receipt_section.txt.erb +17 -0
- data/lib/rock_books/reports/templates/text/_totals.txt.erb +8 -0
- data/lib/rock_books/reports/templates/text/balance_sheet.txt.erb +23 -0
- data/lib/rock_books/reports/templates/text/income_statement.txt.erb +23 -0
- data/lib/rock_books/reports/templates/text/journal.txt.erb +23 -0
- data/lib/rock_books/reports/templates/text/multidoc_txn_by_account_report.txt.erb +31 -0
- data/lib/rock_books/reports/templates/text/multidoc_txn_report.txt.erb +25 -0
- data/lib/rock_books/reports/templates/text/receipts_report.txt.erb +16 -0
- data/lib/rock_books/reports/templates/text/tx_one_account.txt.erb +21 -0
- data/lib/rock_books/reports/tx_one_account.rb +10 -45
- data/lib/rock_books/types/account.rb +13 -1
- data/lib/rock_books/types/account_type.rb +18 -7
- data/lib/rock_books/version.rb +2 -1
- data/manual.md +13 -16
- data/rock_books.gemspec +2 -0
- metadata +57 -10
- data/lib/rock_books/helpers/html_helper.rb +0 -29
- data/lib/rock_books/reports/index.html.erb +0 -156
- data/lib/rock_books/reports/multidoc_transaction_report.rb +0 -66
- data/lib/rock_books/reports/receipts.html.erb +0 -54
- data/lib/rock_books/reports/reporter.rb +0 -118
- data/lib/rock_books/reports/transaction_report.rb +0 -105
- data/lib/rock_books/reports/tx_by_account.rb +0 -82
@@ -1,63 +1,25 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
1
|
+
require_relative 'helpers/erb_helper'
|
2
|
+
require_relative 'helpers/text_report_helper'
|
3
3
|
|
4
4
|
module RockBooks
|
5
5
|
|
6
6
|
|
7
7
|
class IncomeStatement
|
8
8
|
|
9
|
-
include
|
9
|
+
include TextReportHelper
|
10
|
+
include ErbHelper
|
10
11
|
|
11
|
-
|
12
|
+
attr_reader :data, :context
|
12
13
|
|
13
14
|
|
14
|
-
def initialize(report_context)
|
15
|
+
def initialize(report_context, data)
|
15
16
|
@context = report_context
|
17
|
+
@data = data
|
16
18
|
end
|
17
19
|
|
18
20
|
|
19
|
-
def
|
20
|
-
|
21
|
+
def generate
|
22
|
+
ErbHelper.render_hashes('text/income_statement.txt.erb', data, template_presentation_context)
|
21
23
|
end
|
22
|
-
|
23
|
-
|
24
|
-
def end_date
|
25
|
-
context.chart_of_accounts.end_date
|
26
|
-
end
|
27
|
-
|
28
|
-
|
29
|
-
def generate_header
|
30
|
-
lines = [banner_line]
|
31
|
-
lines << center(context.entity || 'Unspecified Entity')
|
32
|
-
lines << "#{center("Income Statement -- #{start_date} to #{end_date}")}"
|
33
|
-
lines << banner_line
|
34
|
-
lines << ''
|
35
|
-
lines << ''
|
36
|
-
lines << ''
|
37
|
-
lines.join("\n")
|
38
|
-
end
|
39
|
-
|
40
|
-
|
41
|
-
def generate_report
|
42
|
-
filter = RockBooks::JournalEntryFilters.date_in_range(start_date, end_date)
|
43
|
-
acct_amounts = Journal.acct_amounts_in_documents(context.journals, filter)
|
44
|
-
totals = AcctAmount.aggregate_amounts_by_account(acct_amounts)
|
45
|
-
totals.each { |aa| aa[1] = -aa[1] } # income statement shows credits as positive, debits as negative
|
46
|
-
output = generate_header
|
47
|
-
|
48
|
-
income_output, income_total = generate_account_type_section('Income', totals, :income, true)
|
49
|
-
expense_output, expense_total = generate_account_type_section('Expenses', totals, :expense, false)
|
50
|
-
|
51
|
-
grand_total = income_total - expense_total
|
52
|
-
|
53
|
-
output << [income_output, expense_output].join("\n\n")
|
54
|
-
output << "\n#{"%12.2f Net Income" % grand_total}\n============\n"
|
55
|
-
output
|
56
|
-
end
|
57
|
-
|
58
|
-
alias_method :to_s, :generate_report
|
59
|
-
alias_method :call, :generate_report
|
60
|
-
|
61
|
-
|
62
24
|
end
|
63
25
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative 'report_context'
|
2
|
+
|
3
|
+
|
4
|
+
module RockBooks
|
5
|
+
class IndexHtmlPage
|
6
|
+
|
7
|
+
include TextReportHelper
|
8
|
+
|
9
|
+
attr_reader :context, :data
|
10
|
+
|
11
|
+
def initialize(report_context, metadata, run_options)
|
12
|
+
@context = report_context
|
13
|
+
@data = {
|
14
|
+
metadata: metadata,
|
15
|
+
journals: context.journals,
|
16
|
+
chart_of_accounts: context.chart_of_accounts,
|
17
|
+
run_options: run_options,
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate
|
22
|
+
webized_generate_message_lines = template_presentation_context[:generated].split("\n")
|
23
|
+
presentation_context = template_presentation_context.merge( { generated: webized_generate_message_lines})
|
24
|
+
ErbHelper.render_hashes('html/index.html.erb', data, presentation_context)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require_relative 'data/journal_data'
|
2
|
+
require_relative 'helpers/erb_helper'
|
3
|
+
require_relative 'helpers/text_report_helper'
|
4
|
+
|
5
|
+
module RockBooks
|
6
|
+
|
7
|
+
class JournalReport
|
8
|
+
|
9
|
+
include TextReportHelper
|
10
|
+
include ErbHelper
|
11
|
+
|
12
|
+
attr_accessor :context, :report_data
|
13
|
+
|
14
|
+
|
15
|
+
def initialize(report_data, report_context, filter = nil)
|
16
|
+
@report_data = report_data
|
17
|
+
@context = report_context
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def generate
|
22
|
+
presentation_context = template_presentation_context.merge(fn_format_entry: method(:format_entry))
|
23
|
+
ErbHelper.render_hashes('text/journal.txt.erb', report_data, presentation_context)
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
private def format_date_and_account_amount(date, acct_amount)
|
28
|
+
"#{date} #{format_acct_amount(acct_amount)}\n"
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
private def format_entry_first_acct_amount(entry)
|
33
|
+
format_date_and_account_amount(entry.date, entry.acct_amounts.first)
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
private def format_entry_last_acct_amount(entry)
|
38
|
+
format_date_and_account_amount(entry.date, entry.acct_amounts.last)
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# Formats an entry like this, with entry description added on additional line(s) if it exists:
|
43
|
+
# 2018-05-21 $120.00 701 Office Supplies
|
44
|
+
private def format_entry_no_split(entry)
|
45
|
+
output = format_entry_last_acct_amount(entry)
|
46
|
+
|
47
|
+
if entry.description && entry.description.length > 0
|
48
|
+
output += entry.description
|
49
|
+
end
|
50
|
+
output
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
# Formats an entry like this, with entry description added on additional line(s) if it exists::
|
55
|
+
# 2018-05-21 $120.00 95.00 701 Office Supplies
|
56
|
+
# 25.00 751 Gift to Customer
|
57
|
+
private def format_entry_with_split(entry)
|
58
|
+
output = StringIO.new
|
59
|
+
output << format_entry_first_acct_amount(entry)
|
60
|
+
indent = ' ' * 12
|
61
|
+
|
62
|
+
entry.acct_amounts[1..-1].each do |acct_amount|
|
63
|
+
output << indent << format_acct_amount(acct_amount) << "\n"
|
64
|
+
end
|
65
|
+
|
66
|
+
if entry.description && entry.description.length > 0
|
67
|
+
output << entry.description
|
68
|
+
end
|
69
|
+
|
70
|
+
output.string
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
private def format_entry(entry)
|
75
|
+
if entry.acct_amounts.size > 2
|
76
|
+
format_entry_with_split(entry)
|
77
|
+
else
|
78
|
+
format_entry_no_split(entry)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative '../documents/chart_of_accounts'
|
2
|
+
require_relative 'helpers/erb_helper'
|
3
|
+
require_relative 'helpers/text_report_helper'
|
4
|
+
require_relative 'report_context'
|
5
|
+
require_relative 'data/multidoc_txn_by_account_data'
|
6
|
+
|
7
|
+
module RockBooks
|
8
|
+
|
9
|
+
class MultidocTransactionByAccountReport
|
10
|
+
|
11
|
+
include TextReportHelper
|
12
|
+
include ErbHelper
|
13
|
+
|
14
|
+
attr_reader :context, :data
|
15
|
+
|
16
|
+
|
17
|
+
def initialize(data, report_context)
|
18
|
+
@data = data
|
19
|
+
@context = report_context
|
20
|
+
end
|
21
|
+
|
22
|
+
def account_total_line(account_code, account_total)
|
23
|
+
account_name = context.chart_of_accounts.name_for_code(account_code)
|
24
|
+
sprintf("%.2f Total for account: %s - %s", account_total, account_code, account_name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def generate
|
28
|
+
presentation_context = template_presentation_context.merge({ fn_account_total_line: method(:account_total_line) })
|
29
|
+
ErbHelper.render_hashes('text/multidoc_txn_by_account_report.txt.erb', data, presentation_context)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'data/multidoc_txn_report_data'
|
2
|
+
require_relative '../documents/journal'
|
3
|
+
require_relative 'helpers/erb_helper'
|
4
|
+
require_relative 'helpers/text_report_helper'
|
5
|
+
require_relative 'report_context'
|
6
|
+
|
7
|
+
module RockBooks
|
8
|
+
|
9
|
+
class MultidocTransactionReport
|
10
|
+
|
11
|
+
include TextReportHelper
|
12
|
+
include ErbHelper
|
13
|
+
|
14
|
+
attr_reader :context, :data
|
15
|
+
|
16
|
+
def initialize(report_data, report_context)
|
17
|
+
@data = report_data
|
18
|
+
@context = report_context
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate
|
22
|
+
ErbHelper.render_hashes('text/multidoc_txn_report.txt.erb', data, template_presentation_context)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -4,67 +4,18 @@ require_relative 'report_context'
|
|
4
4
|
module RockBooks
|
5
5
|
class ReceiptsReport
|
6
6
|
|
7
|
-
include
|
7
|
+
include TextReportHelper
|
8
8
|
|
9
|
-
attr_reader :context, :
|
9
|
+
attr_reader :context, :data
|
10
10
|
|
11
|
-
|
12
|
-
def initialize(report_context, missing, existing, unused)
|
11
|
+
def initialize(report_context, data)
|
13
12
|
@context = report_context
|
14
|
-
@
|
15
|
-
@existing = existing
|
16
|
-
@unused = unused
|
17
|
-
end
|
18
|
-
|
19
|
-
|
20
|
-
def generate_header
|
21
|
-
lines = [banner_line]
|
22
|
-
lines << center(context.entity || 'Unspecified Entity')
|
23
|
-
lines << "#{center("Receipts Report")}"
|
24
|
-
lines << banner_line
|
25
|
-
lines.join("\n")
|
26
|
-
end
|
27
|
-
|
28
|
-
|
29
|
-
def receipt_info_line(info)
|
30
|
-
"%-16.16s %s\n" % [info[:journal], info[:receipt]]
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
def column_headings
|
35
|
-
format_string = "%-16.16s %s\n"
|
36
|
-
(format_string % ['Journal', 'Receipt Filespec']) << (format_string % %w(------- ----------------)) << "\n"
|
37
|
-
end
|
38
|
-
|
39
|
-
|
40
|
-
def report_one_section(name, list)
|
41
|
-
output = ''
|
42
|
-
output << "\n\n\n#{name} Receipts:\n\n" << column_headings
|
43
|
-
if list.empty?
|
44
|
-
output << "[None]\n\n\n"
|
45
|
-
else
|
46
|
-
list.each { |receipt| output << receipt_info_line(receipt) }
|
47
|
-
end
|
48
|
-
output
|
13
|
+
@data = data
|
49
14
|
end
|
50
15
|
|
51
16
|
|
52
|
-
def
|
53
|
-
|
54
|
-
output << report_one_section('Missing', missing)
|
55
|
-
|
56
|
-
output << "\n\n\nUnused Receipts:\n\n"
|
57
|
-
if unused.empty?
|
58
|
-
output << "[None]\n\n\n"
|
59
|
-
else
|
60
|
-
unused.each { |filespec| output << filespec << "\n" }
|
61
|
-
end
|
62
|
-
|
63
|
-
output << report_one_section('Existing', existing)
|
64
|
-
output
|
17
|
+
def generate
|
18
|
+
ErbHelper.render_hashes('text/receipts_report.txt.erb', data, template_presentation_context)
|
65
19
|
end
|
66
|
-
|
67
|
-
alias_method :to_s, :generate_report
|
68
|
-
alias_method :call, :generate_report
|
69
20
|
end
|
70
21
|
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<!-- <%= metadata %> -->
|
4
|
+
<head>
|
5
|
+
|
6
|
+
<meta charset="utf-8">
|
7
|
+
|
8
|
+
<!--Bootstrap:-->
|
9
|
+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
|
10
|
+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
11
|
+
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
|
12
|
+
|
13
|
+
<style>
|
14
|
+
body {
|
15
|
+
padding: 36px;
|
16
|
+
background-color: #88c1f7;
|
17
|
+
color: #01182d;
|
18
|
+
max-width: 1024px;
|
19
|
+
float: none !important;
|
20
|
+
margin: 0 auto !important;
|
21
|
+
}
|
22
|
+
|
23
|
+
.top_heading {
|
24
|
+
text-align: center;
|
25
|
+
}
|
26
|
+
|
27
|
+
h2 {
|
28
|
+
margin-top: 32px;
|
29
|
+
margin-bottom: 12px;
|
30
|
+
}
|
31
|
+
|
32
|
+
.this_page_style {
|
33
|
+
background-color: #88c1f7;
|
34
|
+
color: #01182d;
|
35
|
+
border: 0px;
|
36
|
+
}
|
37
|
+
</style>
|
38
|
+
</head>
|
39
|
+
|
40
|
+
<body>
|
41
|
+
|
42
|
+
<h1 class="top_heading"><%= entity %></h1>
|
43
|
+
<h1 class="top_heading">Financial Statements, Reports, and Source Data</h1>
|
44
|
+
<h1 class="top_heading"><%= accounting_period %></h1>
|
45
|
+
<br />
|
46
|
+
<br />
|
47
|
+
<h4 class="top_heading"><%= generated[0] %></h4>
|
48
|
+
<h4 class="top_heading"><%= generated[1] %> (<a href="https://github.com/keithrbennett/rock_books">https://github.com/keithrbennett/rock_books</a>)</h4>
|
49
|
+
<h4 class="top_heading">Open Source Software Provided by <a href="https://www.bbs-software.com/">Bennett Business Solutions, Inc.</a></h4>
|
50
|
+
<br />
|
51
|
+
<br />
|
52
|
+
|
53
|
+
<h2>Financial Statements</h2>
|
54
|
+
<div id="financial-statements">
|
55
|
+
<a href='balance_sheet.html' class="btn btn-primary">Balance Sheet</a>
|
56
|
+
<a href='income_statement.html' class="btn btn-primary">Income Statement</a>
|
57
|
+
</div>
|
58
|
+
|
59
|
+
|
60
|
+
<h2>Supporting Documents</h2>
|
61
|
+
<div id="supporting-documents" style="display: inline ">
|
62
|
+
<%
|
63
|
+
subdir_link = ->(name, caption) do
|
64
|
+
link_dir_name = File.join('..', '..', name)
|
65
|
+
test_dir_name = name
|
66
|
+
if Dir.exist?(test_dir_name)
|
67
|
+
%Q{<a href=#{link_dir_name} class="btn btn-primary">#{caption}</a>}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
%>
|
71
|
+
<%= subdir_link.('invoices', 'Invoices') %>
|
72
|
+
<%= subdir_link.('receipts', 'Receipts') %>
|
73
|
+
<%= subdir_link.('statements', 'Statements') %>
|
74
|
+
<%= subdir_link.('worksheets', 'Worksheets') %>
|
75
|
+
</div>
|
76
|
+
|
77
|
+
|
78
|
+
<h2>All Transactions Reports</h2>
|
79
|
+
<div id="all-transactions">
|
80
|
+
<a href="all_txns_by_acct.html" class="btn btn-primary">By Account</a>
|
81
|
+
<a href="all_txns_by_amount.html" class="btn btn-primary">By Amount</a>
|
82
|
+
<a href="all_txns_by_date.html" class="btn btn-primary">By Date</a>
|
83
|
+
</div>
|
84
|
+
|
85
|
+
<% collapsible_heading = ->(caption, href) do %Q{
|
86
|
+
<br /><br />
|
87
|
+
<div class="collapsible-heading">
|
88
|
+
<div class="container-fluid">
|
89
|
+
<div class="row">
|
90
|
+
|
91
|
+
<div class="col-sm2" style="margin-right: 12px;">
|
92
|
+
<a class="btn btn-primary" data-toggle="collapse" href="#{href}" role="button" aria-expanded="false" aria-controls="collapseExample">
|
93
|
+
+/-
|
94
|
+
</a>
|
95
|
+
</div>
|
96
|
+
|
97
|
+
<div class="col-sm10">
|
98
|
+
<h2 style="margin: 0px;">#{caption}</h2>
|
99
|
+
</div>
|
100
|
+
</div>
|
101
|
+
</div>
|
102
|
+
</div>
|
103
|
+
} end %>
|
104
|
+
|
105
|
+
<%= collapsible_heading.('Journal Reports', '#journal-reports') %>
|
106
|
+
|
107
|
+
<div class="collapse" id="journal-reports">
|
108
|
+
<div class="card card-body this_page_style">
|
109
|
+
<ul>
|
110
|
+
<% journals.each do |journal|
|
111
|
+
filespec = journal.short_name + '.html' %>
|
112
|
+
<li><a href="<%= filespec %>" class="this_page_style"><%= journal.title %></a></li>
|
113
|
+
<% end %>
|
114
|
+
</ul>
|
115
|
+
</div>
|
116
|
+
</div>
|
117
|
+
|
118
|
+
<%= collapsible_heading.('Individual Accounts', '#individual-accounts') %>
|
119
|
+
|
120
|
+
<div class="collapse" id="individual-accounts">
|
121
|
+
<div class="card card-body this_page_style">
|
122
|
+
<ul>
|
123
|
+
<%
|
124
|
+
chart_of_accounts.accounts.each do |account|
|
125
|
+
filespec = File.join('single-account', "acct_#{account.code}.html")
|
126
|
+
caption = "#{account.name} (#{account.code})"
|
127
|
+
%>
|
128
|
+
<li><a href="<%= filespec %>" class="this_page_style"><%= caption %></a></li>
|
129
|
+
<% end %>
|
130
|
+
</ul>
|
131
|
+
</div>
|
132
|
+
</div>
|
133
|
+
|
134
|
+
<%= collapsible_heading.('Other', '#other') %>
|
135
|
+
|
136
|
+
<div class="collapse" id="other">
|
137
|
+
<div class="card card-body this_page_style">
|
138
|
+
<ul>
|
139
|
+
<% if run_options.do_receipts %>
|
140
|
+
<li><a href="receipts.html" class="this_page_style">Missing and Existing Receipts</a></li>
|
141
|
+
<% end %>
|
142
|
+
</ul>
|
143
|
+
</div>
|
144
|
+
</div>
|
145
|
+
|
146
|
+
<%= collapsible_heading.('Reports in PDF and Text Formats', '#other-formats') %>
|
147
|
+
|
148
|
+
<div class="collapse" id="other-formats">
|
149
|
+
<div class="card card-body this_page_style">
|
150
|
+
<ul>
|
151
|
+
<li><a href="../pdf" class="this_page_style">PDF Format</a></li>
|
152
|
+
<li><a href="../txt" class="this_page_style">Text Format</a></li>
|
153
|
+
</ul>
|
154
|
+
</div>
|
155
|
+
</div>
|
156
|
+
|
157
|
+
</body>
|
158
|
+
</html>
|