add form for reimbursement claims and credit card statements

This commit is contained in:
Max Mehl 2020-05-28 16:53:16 +02:00
parent 69a7ffecd5
commit 384070731d
Signed by: max.mehl
GPG Key ID: 2704E4AB371E2E92
7 changed files with 6630 additions and 0 deletions

View File

@ -0,0 +1,39 @@
<?php
/**
* PHPMailer Exception class.
* PHP Version 5.5.
*
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2017 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*/
namespace PHPMailer\PHPMailer;
/**
* PHPMailer exception handler.
*
* @author Marcus Bointon <phpmailer@synchromedia.co.uk>
*/
class Exception extends \Exception
{
/**
* Prettify error message output.
*
* @return string
*/
public function errorMessage()
{
return '<strong>' . htmlspecialchars($this->getMessage()) . "</strong><br />\n";
}
}

File diff suppressed because it is too large Load Diff

1371
cgi-bin/PHPMailer/SMTP.php Normal file

File diff suppressed because it is too large Load Diff

184
cgi-bin/reimbursement.php Executable file
View File

@ -0,0 +1,184 @@
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\SMTP;
require 'PHPMailer/Exception.php';
require 'PHPMailer/PHPMailer.php';
require 'PHPMailer/SMTP.php';
$html = ''; // create empty variable
$csv = array(array("Employee name", "Date", "Amount (EUR)", "Recipient name", "ER number", "Catchphrase", "Receipt name", "Remarks")); // create array for CSV
$csvfile = tmpfile();
$csvfile_path = stream_get_meta_data($csvfile)['uri'];
$who = isset($_POST["who"]) ? $_POST["who"] : false;
$type = isset($_POST["type"]) ? $_POST["type"] : false;
$rc_month = isset($_POST["rc_month"]) ? $_POST["rc_month"] : false;
$rc_year = isset($_POST["rc_year"]) ? $_POST["rc_year"] : false;
$cc_month = isset($_POST["cc_month"]) ? $_POST["cc_month"] : false;
$cc_year = isset($_POST["cc_year"]) ? $_POST["cc_year"] : false;
$entry = isset($_POST["entry"]) ? $_POST["entry"] : false; // will become $date in loop
$amount = isset($_POST["amount"]) ? $_POST["amount"] : false;
$recipient = isset($_POST["recipient"]) ? $_POST["recipient"] : false;
$er = isset($_POST["er"]) ? $_POST["er"] : false;
$catch = isset($_POST["catch"]) ? $_POST["catch"] : false;
$receipt = isset($_POST["receipt"]) ? $_POST["receipt"] : false;
$remarks = isset($_POST["remarks"]) ? $_POST["remarks"] : false;
$extra = isset($_POST["extra"]) ? $_POST["extra"] : false;
// create empty arrays for uploaded file
$receipt_dest = [];
// FUNCTIONS
function td($input) {
return "<td>$input</td>";
}
// Sanity checks
if ($type == "rc") {
if ( ! $rc_month || ! $rc_year ) {
exit("You must provide month and year of the RC");
}
$type_verbose = "Reimbursement Claim";
$type_date = "$rc_year-$rc_month";
} else if ($type == "cc") {
if ( ! $cc_month || ! $cc_year ) {
exit("You must provide quarter and year of the CC statement");
}
$type_verbose = "Credit Card Statement";
$type_date = "$cc_year-$cc_month";
} else {
exit("You must provide a reimbursement type");
}
// Prepare output table
$html .= "<p>This <strong>$type_verbose</strong> is made by <strong>$who</strong>.</p>
<table class='table table-striped'>
<tr>
<th>Date</th>
<th>Amount</th>
<th>Recipient</th>
<th>ER number</th>
<th>Catchphrase</th>
<th>Receipt Name</th>
<th>Remarks</th>
</tr>";
$email = new PHPMailer();
$email->isSMTP();
$email->Host = "mail.fsfe.org";
// Settings on server
$email->SMTPAuth = false;
$email->Port = 25;
// Settings for local debug
//$email->SMTPAuth = true;
//$email->Port = 587;
//$email->Username = 'fsfe_user';
//$email->Password = 'fsfe_pass';
//$email->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$email->SetFrom($who . "@fsfe.org", "$who");
$email->Subject = "$type_verbose for $type_date by $who";
$email->addAddress($who . "@fsfe.org");
foreach ($entry as $key => $date) { // calculate for each entry
$receipt_tmp = $_FILES["receipt"]["tmp_name"][$key];
$receipt_error = $_FILES["receipt"]["error"][$key];
$receipt_name = basename($_FILES["receipt"]["name"][$key]);
$receipt_size = $_FILES["receipt"]["size"][$key];
$receipt_no = $key + 1;
if (! $receipt_tmp) {
exit("Something with $receipt_name went wrong, it has not been uploaded.");
}
if ($receipt_size > 2097152) {
exit("File size of $receipt_name must not be larger than 2MB");
}
$receipt_mime = mime_content_type($receipt_tmp);
if(! in_array($receipt_mime, array('image/jpeg', 'image/png', 'application/pdf'))) {
exit("Only PDF, JPG and PNG allowed. $receipt_name has $receipt_mime");
}
$receipt_ext = pathinfo($receipt_name)['extension'];
$receipt_rename = $type ."-". $type_date ."-". $who ."-receipt". $receipt_no ."-". $er[$key] .".". "$receipt_ext";
$receipt_dest[$key] = "/tmp/" . $receipt_rename;
if ($receipt_error == UPLOAD_ERR_OK) {
if ( ! move_uploaded_file($receipt_tmp, $receipt_dest[$key]) ) {
exit("Could not move uploaded file '".$receipt_tmp."' to '".$receipt_dest."'<br/>\n");
}
} else {
exit("Upload error. [".$receipt_error."] on file '".$receipt_name."'<br/>\n");
}
// HTML output
$html .= "
<tr>
<td>$date</td>
<td>$amount[$key]</td>
<td>$recipient[$key]</td>
<td>$er[$key]</td>
<td>$catch[$key]</td>
<td>$receipt_rename</td>
<td>$remarks[$key]</td>
</tr>";
// CSV
$csv[$receipt_no] = array($who, $date, $amount[$key], $recipient[$key], $er[$key], $catch[$key], $receipt_rename, $remarks[$key]);
// Email
$email->addAttachment($receipt_dest[$key], basename($receipt_dest[$key]));
} // foreach
// Write and attach temporary CSV file
foreach ($csv as $fields) {
fputcsv($csvfile, $fields, ',', '"', '"');
}
$email->addAttachment($csvfile_path, $type ."-". $type_date ."-". $who . ".csv");
// Prepare email body
$email_body = "Hi,
This is a $type_verbose for $type_date by $who,
sent via <https://fsfe.org/internal/rc>.
Please find the expenses and their receipts attached.";
// Finalise output table
$html .= "</table>";
if ($extra) {
$html .= "<p>Extra remarks: <br />$extra</p>";
$email_body .= "
The sender added the following comment:
$extra";
}
// Send email, and delete attachments
$email->Body = $email_body;
$email->send();
$html .= $email->ErrorInfo;
foreach ($receipt_dest as $receipt) {
unlink($receipt);
}
fclose($csvfile);
// --- PRINT OUTPUT IN TEMPLATE FILE ---
function replace_page($temp, $content){
$vars = array(':RESULT:'=>$content);
return str_replace(array_keys($vars), $vars, $temp);
}
$template = file_get_contents($_SERVER['REQUEST_SCHEME'] ."://". $_SERVER['HTTP_HOST'] . '/internal/rc-result.en.html', true);
echo replace_page($template, $html);
?>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8" ?>
<html>
<version>1</version>
<head>
<title>Reimbursement Claim / Credit Card statement</title>
</head>
<body>
<h1>Review you input</h1>
<p>You have just sent the following information, and will receive a
confirmation mail soon. If there is a problem, please redo your
statement (Back-button in your browser) or contact your financial
contact person.</p>
<div>:RESULT:</div>
</body>
</html>
<!--
Local Variables: ***
mode: xml ***
End: ***
-->

152
internal/rc.en.xhtml Normal file
View File

@ -0,0 +1,152 @@
<?xml version="1.0" encoding="utf-8" ?>
<html>
<version>1</version>
<head>
<title>Reimbursement Claim / Credit Card statement</title>
<style type="text/css">
table input.form-control,
table textarea.form-control {
font-size: 12px;
}
table td {
padding: 1px !important;
}
.form-control {
padding: 3px 6px !important;
}
input[type="file"] {
width: 180px;
}
</style>
<script src="/scripts/addrow.js"></script>
</head>
<body>
<h1>Reimbursement Claim / Credit Card statement</h1>
<p>
In this form, you can enter your reimbursable expenses (monthly)
as well as your credit card expenses (twi-monthly), upload
receipts, and eventually submit it to our financial team.
</p>
<p>
Please fill out all fields as requested, and take care of
selecting the correct type (Reimbursement Claim or Credit Card).
</p>
<form action="/cgi-bin/reimbursement.php" method="post" enctype="multipart/form-data">
<h2>1. Set general options</h2>
<div class="form-group form-inline">
<label class="col-sm-3">Employee:</label>
<select class="form-control col-sm-9" name="who" size="1" required="required">
<option />
<option value="alex.sander">Alexander Sander</option>
<option value="bonnie">Bonnie Mehring</option>
<option value="eal">Erik Albers</option>
<option value="fi">Francesca Indorato</option>
<option value="gabriel.ku">Gabriel Ku Wei Bin</option>
<option value="lucas.lasota">Lucas Lasota</option>
<option value="max.mehl">Max Mehl</option>
<option value="mk">Matthias Kirschner</option>
</select>
</div>
<div class="clearfix"></div>
<div class="form-group">
<label class="col-sm-3">Type:</label>
<div class="radio form-inline col-sm-9">
<label>
<input type="radio" name="type" value="rc" required="required" />
Reimbursement Claim for month
<select class="form-control" name="rc_month">
<option />
<option value="01">January</option>
<option value="02">February</option>
<option value="03">March</option>
<option value="04">April</option>
<option value="05">May</option>
<option value="06">June</option>
<option value="07">July</option>
<option value="08">August</option>
<option value="09">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>
<select class="form-control" name="rc_year">
<option value="2020">2020</option>
<option value="2021">2021</option>
<option value="2022">2022</option>
</select>
</label>
</div>
<div class="clearfix"></div>
<div class="radio form-inline col-sm-offset-3 col-sm-9">
<label>
<input type="radio" name="type" value="cc" required="required" />
Credit Card for quarter
<select class="form-control" name="cc_month">
<option />
<option value="Q1">Q1</option>
<option value="Q2">Q2</option>
<option value="Q3">Q3</option>
<option value="Q4">Q4</option>
</select>
<select class="form-control" name="cc_year">
<option value="2020">2020</option>
<option value="2021">2021</option>
<option value="2022">2022</option>
</select>
</label>
</div>
</div>
<h2>2. Enter your expenses</h2>
<table class="table table-striped">
<tr>
<th>Date</th>
<th>Amount in EUR</th>
<th>Recipient</th>
<th>ER number</th>
<th>Catchphrase</th>
<th>Receipt Scan</th>
<th>Remarks</th>
<th>Add/Del Rows</th>
</tr>
<tr>
<td><input type="date" name="entry[]" class="form-control" required="required" /></td>
<td><input type="number" name="amount[]" step=".01" class="form-control" placeholder="12.34" required="required" /></td>
<td><input type="text" name="recipient[]" class="form-control" required="required" /></td>
<td><input type="text" name="er[]" class="form-control" placeholder="er.2020-..." required="required" /></td>
<td><input type="text" name="catch[]" class="form-control" required="required" /></td>
<td><input type="file" name="receipt[]" class="form-control" required="required" /></td>
<td><textarea name="remarks[]" class="form-control" rows="1" required="required"></textarea></td>
<td><input type="button" class="AddNewRow btn btn-primary" value="+ 1 row" /></td>
</tr>
</table>
<h2>3. Extra remarks / notes</h2>
<p>If necessary, you can add additional remarks and notes to the statement you send.</p>
<div class="form-group">
<textarea name="extra" class="form-control" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-primary">Send RC/CC report</button>
</form>
</body>
</html>

22
scripts/addrow.js Normal file
View File

@ -0,0 +1,22 @@
/*
* SPDX-License-Identifier: CC-BY-SA-4.0
* SPDX-FileCopyrightText: 2012 Cheery <https://stackoverflow.com/users/1164491/cheery>
* SPDX-FileCopyrightText: 2020 Free Software Foundation Europe <https://fsfe.org>
*
* This script allows the dynamic clone of a table row using a button.
* Reference implementation on /internal/rc.en.xhtml
*/
$(document).ready(function() {
$('.AddNewRow').click(function(){
var row = $(this).closest('tr').clone();
row.find('input').val('');
row.find('textarea').val('');
$(this).closest('tr').parent().children('tr').last().after(row);
$('input[type="button"]', row).removeClass('AddNewRow btn-primary').addClass('RemoveRow btn-danger').val('Delete');
});
$('table').on('click', '.RemoveRow', function(){
$(this).closest('tr').remove();
});
});