Generate invocies from the members.csv

This commit updates the previous template to inline the two images as
data URIs and embed ERB template markers for the data. The ruby script
added in this commit interpolates the data from the members.csv file
into the template and generates PDFs using wkhtmltopdf.
This commit is contained in:
Chris Lowis 2022-05-03 11:44:36 +01:00
parent 08dd95f3a2
commit 455306a0a6
7 changed files with 174 additions and 169 deletions

View File

@ -4,24 +4,20 @@ Records and documentation for the CoTech fund
## Generating receipts
Install `pandoc` and `wkhtmltopdf` using, for example homebrew on OS X
Install `wkhtmltopdf` using, for example homebrew on OS X
```
brew install pandoc
brew install Caskroom/cask/wkhtmltopdf
```
Then in `receipts/` create a markdown file from an existing one, and run, for example
Then in the root of the project run
```
pandoc -t html5 agile_collective_2019-2020.md -o agile_collective_2019-2020.pdf --css style.css
ruby scripts/generate_invoices.rb
```
The invoices should be generated in `invoices/sent/2022/`.
The ruby script can be edited to change the start of the range of invoice numbers and to generate the output in a different directory.
---
---
Alternatively, to make PDF invoices/receipts with markdown files [markdown themes](https://support.typora.io/About-Themes/) can be used. `theme/cotech.css` can be used as a CSS stylesheet and `invoice_template_themed.md` as template. Images path has to point to `img/` directory at the root of the repository. Invoices in `invoices/sent/2020` were created that way.
The data used to generate the invoices is in `members.csv`.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

View File

@ -0,0 +1,66 @@
require 'csv'
require 'erb'
require 'date'
FIRST_INVOICE_NUMBER = 50
output_dir = File.join(File.dirname(__FILE__), "..", "invoices", "sent", "2022")
members_fn = File.read(File.join(File.dirname(__FILE__), "..", "members.csv"))
members = CSV.parse(members_fn, headers: true)
template_fn = File.read(File.join(File.dirname(__FILE__), "..", "template", "template.html"))
class Invoice
def initialize(data, number)
@coop_name = data['coop_name']
@contact_address = data['contact_address']
@members = data['members']
@number = number
end
def date
Date.today.strftime('%d %B %Y')
end
def number
"%04d" % @number
end
def members
@members.to_i
end
def total
members * 52
end
def name
@coop_name
end
def basename
name.downcase.gsub(' ', '_').gsub('.', '')
end
def address
@contact_address.gsub("//", "\n")
end
def get_binding
binding()
end
end
members.each_with_index do |member, index|
invoice = Invoice.new(member, FIRST_INVOICE_NUMBER + index)
renderer = ERB.new(template_fn)
result = renderer.result(invoice.get_binding)
output_html_fn = File.join(output_dir, invoice.basename + '.html')
output_pdf_fn = File.join(output_dir, invoice.basename + '.pdf')
File.write(output_html_fn, result)
system("wkhtmltopdf #{output_html_fn} #{output_pdf_fn}")
end

102
template/template.html Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,114 +0,0 @@
@charset "utf-8";
body {
font-size: 10.5pt;
font-family: "Avenir Next", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
hyphens: auto;
height: 270mm; /* 297 - 10 (top) - 20 (bottom) */
line-height: 140%;
margin: 0;
padding: 0;
}
code {
font-family: "Source Sans Code", Courier New, Courier, monospace;
margin-left: 1pt;
}
a {
color: black;
margin-left: 1pt;
}
table {
width: 100%;
}
table:nth-of-type(3) {
border: 1px solid black;
padding: 5pt;
}
table:nth-of-type(3) td:nth-of-type(2) {
text-align: center;
}
h1 {
font-size: 13pt;
margin-top: 6pt;
margin-bottom: 0;
}
h2 {
font-size: 10.5pt;
font-weight: normal;
margin-top: 0;
margin-bottom: 20pt;
}
p {
width: 100%;
}
p:first-of-type {
font-size: 9pt;
word-spacing: 1pt;
}
/*p:first-of-type::after {
content: "\2014";
position: absolute;
top: 89mm; / 99mm - 10mm top /
right: 0mm;
}*/
p:nth-of-type(2) {
margin-top: 20mm;
}
p:nth-of-type(3) {
text-align: left;
}
p:nth-last-of-type(3) {
margin-top: 10mm;
}
p:last-of-type {
text-align: justify;
font-size: 9pt;
position: absolute;
bottom: 2mm;
margin-bottom: 0;
padding-bottom: 0;
/* word-spacing: 1pt; */
color: #444;
}
hr {
border: 1px solid #eee;
}
hr:last-of-type {
position: absolute;
bottom: 14mm;
width: 100%;
}
figure {
margin: 0;
}
img {
width: 15%;
left: 0px;
float: left;
display: block;
}
.footer {
position: fixed;
bottom: 0px;
font-size: 8pt;
}

View File

@ -1,45 +0,0 @@
![](../img/Cotech-blue-text.png)
<pre>
Co-op's name
Address
</pre>
19th June 2020
# Invoice: CoTech Fund Contribution
## Invoice number: 00023
| Description | Members | Total |
| --------------------------------------------------- | ------- | ------ |
| Annual subscription to CoTech fund @ £1/member/week | 1 | £52.00 |
Please make a payment of £52.00 by bank transfer to:
- **Account Name**: Co-operative Technologists
- **Account Number**: 20409157
- **Sort Code**: 60-83-01
Kind regards,
![](../img/chris_lowis_signature.png)
(Chris Lowis, Treasurer)
<span class="footer"> Chris Lowis | treasurer@coops.tech</span>