Enable per-diem form to send emails, and generally align with rc form
This commit is contained in:
parent
ae7548eadc
commit
8b289bd153
@ -1,35 +1,109 @@
|
||||
<?php
|
||||
/***********************************************************************
|
||||
* Copyright (C) 2016 Max Mehl <max.mehl [at] fsfe [dot] org> for FSFE e.V.
|
||||
************************************************************************
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
************************************************************************
|
||||
*
|
||||
* This file receives input from /internal/pd.en.(x)html and calculates per
|
||||
* diem charges for reimbursement claims. The amounts can be defined in
|
||||
* the XHTML file. For the output of the data, it uses
|
||||
* /internal/pd-result.en.(x)html as a template.
|
||||
*
|
||||
***********************************************************************/
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Free Software Foundation Europe <https://fsfe.org>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*
|
||||
************************************************************************
|
||||
*
|
||||
* This file receives input from /internal/pd.en.(x)html and calculates per
|
||||
* diem charges for reimbursement claims. The amounts can be defined in
|
||||
* the XHTML file. For the output of the data, it uses
|
||||
* /internal/pd-result.en.(x)html as a template.
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
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 number", "Remarks")); // create array for CSV
|
||||
$csvfile = tmpfile();
|
||||
$csvfile_path = stream_get_meta_data($csvfile)['uri'];
|
||||
$r_total = 0; // total reimbursement for early calculation
|
||||
|
||||
$who = isset($_POST["who"]) ? $_POST["who"] : false;
|
||||
$er = isset($_POST["er"]) ? $_POST["er"] : false;
|
||||
$catch = isset($_POST["catch"]) ? $_POST["catch"] : false;
|
||||
$extra = isset($_POST["extra"]) ? $_POST["extra"] : false;
|
||||
$mailopt = isset($_POST["mailopt"]) ? $_POST["mailopt"] : false;
|
||||
$home = isset($_POST["home"]) ? $_POST["home"] : false;
|
||||
$home_other = isset($_POST["home_other"]) ? $_POST["home_other"] : false;
|
||||
$dest = isset($_POST["dest"]) ? $_POST["dest"] : false;
|
||||
$dest_other = isset($_POST["dest_other"]) ? $_POST["dest_other"] : false;
|
||||
$use = isset($_POST["use"]) ? $_POST["use"] : false;
|
||||
$date = isset($_POST["date"]) ? $_POST["date"] : false;
|
||||
$break = isset($_POST["break"]) ? $_POST["break"] : false;
|
||||
$lunch = isset($_POST["lunch"]) ? $_POST["lunch"] : false;
|
||||
$dinner = isset($_POST["dinner"]) ? $_POST["dinner"] : false;
|
||||
|
||||
// Separate employee name parameters
|
||||
$who_verbose = explode('|', $who)[0];
|
||||
$who = explode('|', $who)[1];
|
||||
|
||||
// FUNCTIONS
|
||||
function errexit($msg) {
|
||||
exit("Error: " . $msg . "<br/><br/>To avoid losing your data, press the back button in your browser");
|
||||
}
|
||||
function replace_page($temp, $content){
|
||||
$vars = array(':RESULT:'=>$content);
|
||||
return str_replace(array_keys($vars), $vars, $temp);
|
||||
}
|
||||
/* Snippet Begin:
|
||||
* SPDX-SnippetLicenseConcluded: CC-BY-SA-4.0
|
||||
* SPDX-SnippetCopyrightText: mgutt <https://stackoverflow.com/users/318765/mgutt>
|
||||
*/
|
||||
function filter_filename($filename, $beautify=true) {
|
||||
// sanitize filename
|
||||
$filename = preg_replace(
|
||||
'~
|
||||
[<>:"/\\|?*]| # file system reserved https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
|
||||
[\x00-\x1F]| # control characters http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
|
||||
[\x7F\xA0\xAD]| # non-printing characters DEL, NO-BREAK SPACE, SOFT HYPHEN
|
||||
[#\[\]@!$&\'()+,;=]| # URI reserved https://tools.ietf.org/html/rfc3986#section-2.2
|
||||
[{}^\~`] # URL unsafe characters https://www.ietf.org/rfc/rfc1738.txt
|
||||
~x',
|
||||
'-', $filename);
|
||||
// avoids ".", ".." or ".hiddenFiles"
|
||||
$filename = ltrim($filename, '.-');
|
||||
// optional beautification
|
||||
if ($beautify) $filename = beautify_filename($filename);
|
||||
// maximize filename length to 255 bytes http://serverfault.com/a/9548/44086
|
||||
$ext = pathinfo($filename, PATHINFO_EXTENSION);
|
||||
$filename = mb_strcut(pathinfo($filename, PATHINFO_FILENAME), 0, 255 - ($ext ? strlen($ext) + 1 : 0), mb_detect_encoding($filename)) . ($ext ? '.' . $ext : '');
|
||||
return $filename;
|
||||
}
|
||||
function beautify_filename($filename) {
|
||||
// reduce consecutive characters
|
||||
$filename = preg_replace(array(
|
||||
// "file name.zip" becomes "file-name.zip"
|
||||
'/ +/',
|
||||
// "file___name.zip" becomes "file-name.zip"
|
||||
'/_+/',
|
||||
// "file---name.zip" becomes "file-name.zip"
|
||||
'/-+/'
|
||||
), '-', $filename);
|
||||
$filename = preg_replace(array(
|
||||
// "file--.--.-.--name.zip" becomes "file.name.zip"
|
||||
'/-*\.-*/',
|
||||
// "file...name..zip" becomes "file.name.zip"
|
||||
'/\.{2,}/'
|
||||
), '.', $filename);
|
||||
// lowercase for windows/unix interoperability http://support.microsoft.com/kb/100625
|
||||
$filename = mb_strtolower($filename, mb_detect_encoding($filename));
|
||||
// ".file-name.-" becomes "file-name"
|
||||
$filename = trim($filename, '.-');
|
||||
return $filename;
|
||||
}
|
||||
/* Snippet End */
|
||||
|
||||
$output = ''; // create empty variable
|
||||
|
||||
// detect home country and set accodingly: currency, rates
|
||||
$home = $_POST['home'];
|
||||
if ($home === 'de') {
|
||||
$cur = " €"; // currency
|
||||
$c_b = 0.2; // breakfast rate
|
||||
@ -43,7 +117,7 @@ if ($home === 'de') {
|
||||
$c_d = 0.35;
|
||||
$c_flat = 0.15;
|
||||
} elseif ($home === 'other') {
|
||||
$home_other = explode("/", $_POST['home_other']);
|
||||
$home_other = explode("/", $home_other);
|
||||
$cur = " " . $home_other[0];
|
||||
$c_b = $home_other[1];
|
||||
$c_l = $home_other[2];
|
||||
@ -51,48 +125,60 @@ if ($home === 'de') {
|
||||
$c_flat = $home_other[4];
|
||||
}
|
||||
|
||||
|
||||
// amount per day
|
||||
$epd = $_POST['dest'];
|
||||
if ($epd === 'other') {
|
||||
$epd = $_POST['dest_other']; // if other destination, just take this value
|
||||
// eligible amount per day
|
||||
if ($dest === 'other') {
|
||||
$dest = $dest_other; // if other destination, just take this value
|
||||
} else {
|
||||
$pattern = "/" . $home . "=([0-9.]+)?\/([0-9.]+)?/"; // define pattern something like "/de=12/24/"
|
||||
$epd = preg_match($pattern, $epd, $match, PREG_OFFSET_CAPTURE); // actually search for it
|
||||
$epd = $match[0][0]; // matches are on 2nd level inn an array
|
||||
$epd = explode('=', $epd); // now separate at the "="
|
||||
$epd = $epd[1]; // take the second half of it "12/24"
|
||||
$dest = preg_match($pattern, $dest, $match, PREG_OFFSET_CAPTURE); // actually search for it
|
||||
$dest = $match[0][0]; // matches are on 2nd level inn an array
|
||||
$dest = explode('=', $dest); // now separate at the "="
|
||||
$dest = $dest[1]; // take the second half of it "12/24"
|
||||
}
|
||||
|
||||
$epd = explode('/', $epd); // separate at "/"
|
||||
// dest -> epd (half/full amount)
|
||||
$epd = explode('/', $dest); // separate at "/"
|
||||
$epd_trav = $epd[0]; // first half
|
||||
$epd_full = $epd[1]; // second hald
|
||||
$epd_full = $epd[1]; // second half
|
||||
|
||||
$output .= "<h2>Detailled overview of per diems</h2>";
|
||||
$output .= "<p>Travel day(s): " . $epd_trav . $cur . " per day <br />";
|
||||
$output .= "Full day(s): " . $epd_full . $cur . " per day <br />";
|
||||
$output .= "Own country: " . $home . " <br />";
|
||||
$output .= "Percentage rate for breakfast/lunch/dinner: " . $c_b . "/" . $c_l . "/" . $c_d . " <br />";
|
||||
$output .= "Flat rate (percentage which employee gets even if all meals are paid): " . $c_flat . " <br /></p>";
|
||||
|
||||
$output .= '<table class="table table-striped">
|
||||
// Prepare output table
|
||||
if ($mailopt === "onlyme") {
|
||||
$html .= "<p><strong>ATTENTION: The email has only been sent to you, not to the financial team!</strong></p>";
|
||||
} else if ($mailopt === "none") {
|
||||
$html .= "<p><strong>ATTENTION: You have configured to not send any email!</strong></p>";
|
||||
}
|
||||
$html .= "<p>This per diem statement is made by <strong>$who_verbose</strong>.</p>
|
||||
<table class='table table-striped'>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Breakfast</th>
|
||||
<th>Lunch</th>
|
||||
<th>Dinner</th>
|
||||
<th>Flat reimbursement</th>
|
||||
<th>Your total reimbursement</th>
|
||||
</tr>';
|
||||
<th>Amount</th>
|
||||
<th>Recipient</th>
|
||||
<th>ER number</th>
|
||||
<th>Catchphrase</th>
|
||||
<th>Receipt Name</th>
|
||||
<th>Remarks</th>
|
||||
</tr>";
|
||||
|
||||
$use = $_POST['use'];
|
||||
$date = $_POST['date'];
|
||||
$break = $_POST['break'];
|
||||
$lunch = $_POST['lunch'];
|
||||
$dinner = $_POST['dinner'];
|
||||
// Prepare email
|
||||
$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_verbose);
|
||||
$email->Subject = "per diem statement by $who_verbose for $catch";
|
||||
if ($mailopt === "normal") {
|
||||
$email->addAddress("finance@lists.fsfe.org");
|
||||
}
|
||||
$email->addAddress($who . "@fsfe.org");
|
||||
|
||||
// set variables
|
||||
$r_total = 0; // total reimbursement
|
||||
|
||||
foreach ($use as $d => $day) { // calculate for each day
|
||||
// set "no" as value for day's variable if empty
|
||||
@ -101,166 +187,131 @@ foreach ($use as $d => $day) { // calculate for each day
|
||||
$break[$d] = $break[$d] ?? 'no';
|
||||
$lunch[$d] = $lunch[$d] ?? 'no';
|
||||
$dinner[$d] = $dinner[$d] ?? 'no';
|
||||
|
||||
|
||||
// increase $d by 1 if numeric, for $csv array number
|
||||
if (is_numeric($d)) {
|
||||
$key = $d + 1;
|
||||
} else {
|
||||
$key = $d;
|
||||
}
|
||||
|
||||
// set variables
|
||||
$r_day[$d] = 0; // reimbursement for this day
|
||||
|
||||
|
||||
|
||||
if ($use[$d] === 'yes') { // only calculate if checkbox has been activated (day in use)
|
||||
if ($d === 'out' || $d === 'return') { // set amount of € for travel or full day
|
||||
$eur = $epd_trav; // total reimburseable amount for this day
|
||||
$desc = " (travel)";
|
||||
$eur = $epd_trav; // total reimburseable amount for this half day
|
||||
} else {
|
||||
$eur = $epd_full; // total reimburseable amount for this day
|
||||
$desc = " (full)";
|
||||
$eur = $epd_full; // total reimburseable amount for this full day
|
||||
}
|
||||
// open row
|
||||
$output .= "<tr>";
|
||||
|
||||
|
||||
// date
|
||||
if ($date[$d] === '' ) {
|
||||
$date[$d] = "Day " . $d;
|
||||
} else {
|
||||
$date[$d] = date("d.m.Y", strtotime($date[$d]));
|
||||
}
|
||||
$output .= "<td>" . $date[$d] . $desc . "</td>";
|
||||
|
||||
// breakfast ($r_b)
|
||||
if ($break[$d] === "yes") {
|
||||
$r_b = $eur * $c_b;
|
||||
$r_day[$d] = $r_day[$d] + $r_b;
|
||||
$output .= "<td>yes (" . $r_b . $cur . ")</td>";
|
||||
} else {
|
||||
$output .= "<td>no</td>";
|
||||
}
|
||||
|
||||
// lunch ($r_l)
|
||||
if ($lunch[$d] === "yes") {
|
||||
$r_l = $eur * $c_l;
|
||||
$r_day[$d] = $r_day[$d] + $r_l;
|
||||
$output .= "<td>yes (" . $r_l . $cur . ")</td>";
|
||||
} else {
|
||||
$output .= "<td>no</td>";
|
||||
}
|
||||
|
||||
// breakfast ($r_d)
|
||||
if ($dinner[$d] === "yes") {
|
||||
$r_d = $eur * $c_d;
|
||||
$r_day[$d] = $r_day[$d] + $r_d;
|
||||
$output .= "<td>yes (" . $r_d . $cur . ")</td>";
|
||||
} else {
|
||||
$output .= "<td>no</td>";
|
||||
}
|
||||
|
||||
// flat rate
|
||||
$r_flat = $eur * $c_flat;
|
||||
$r_day[$d] = $r_day[$d] + $r_flat;
|
||||
$output .= "<td>" . $r_flat . $cur . "</td>";
|
||||
|
||||
// reimbursement for the single day
|
||||
$output .= "<td>" . $r_day[$d] . $cur . "</td>";
|
||||
|
||||
// total reimbursement for the single day
|
||||
$r_total = $r_total + $r_day[$d];
|
||||
|
||||
// close row (day)
|
||||
$output .= "</tr>";
|
||||
|
||||
|
||||
// Remarks, explanation what has been self-paid
|
||||
$remarks[$d] = "";
|
||||
if ($break[$d] === "yes") {
|
||||
$remarks[$d] .= "breakfast+";
|
||||
}
|
||||
if ($lunch[$d] === "yes") {
|
||||
$remarks[$d] .= "lunch+";
|
||||
}
|
||||
if ($dinner[$d] === "yes") {
|
||||
$remarks[$d] .= "dinner";
|
||||
}
|
||||
if ($break[$d] != "yes" && $lunch[$d] != "yes" && $dinner[$d] != "yes") {
|
||||
$remarks[$d] = "nothing";
|
||||
}
|
||||
if ($break[$d] === "yes" && $lunch[$d] === "yes" && $dinner[$d] === "yes") {
|
||||
$remarks[$d] = "everything";
|
||||
}
|
||||
$remarks[$d] = preg_replace("/\+$/", "", $remarks[$d]);
|
||||
$remarks[$d] .= " self-paid";
|
||||
|
||||
// HTML output for this day
|
||||
$html .= "
|
||||
<tr>
|
||||
<td>$date[$d]</td>
|
||||
<td>$r_day[$d]</td>
|
||||
<td></td>
|
||||
<td>$er</td>
|
||||
<td>$catch</td>
|
||||
<td>per diem</td>
|
||||
<td>$remarks[$d]</td>
|
||||
</tr>";
|
||||
|
||||
// CSV for this receipt
|
||||
$csv[$key] = array($who_verbose, $date[$d], $r_day[$d], "", $er, $catch, "per diem", $remarks[$d]);
|
||||
|
||||
} // if day is used
|
||||
} // foreach
|
||||
|
||||
$output .= "<tr><td></td><td></td><td></td><td></td><td></td>";
|
||||
$output .= "<td><strong>Total per diem: " . $r_total . $cur . "</strong></td></tr></table>";
|
||||
// Write and attach temporary CSV file
|
||||
foreach ($csv as $fields) {
|
||||
fputcsv($csvfile, $fields, ',', '"', '"');
|
||||
}
|
||||
$email->addAttachment($csvfile_path, filter_filename("perdiem" ."-". $who ."-". $er ."-". $catch . ".csv"));
|
||||
|
||||
/* ------------------------------------
|
||||
* --- PRINT FOR COPY IN SPREADSHEET ---
|
||||
* -----------------------------------*/
|
||||
$output .= "<hr />";
|
||||
$output .= "<h2>Spreadsheet copy&paste</h2>";
|
||||
$output .= "<p>The following section can be copied to your Reimbursement Claim spreadsheet. Please mark and copy the content of the table (except the headings), and paste it in your spreadsheet application.<br /><em>Hint: In LibreOffice, press Ctrl+Shift+V in order to paste it as unformatted text instead of HTML code. This avoids conflicting formatting.</em></p>";
|
||||
// Prepare email body
|
||||
$email_body = "Hi,
|
||||
|
||||
This is a per diem statement by $who_verbose for
|
||||
$catch (ER: $er),
|
||||
sent via <https://fsfe.org/internal/pd>.
|
||||
|
||||
$output .= '<table class="table">';
|
||||
$output .= '<tr><th>Employee name</th><th>Date</th><th>Amount (EUR)</th><th>Recipient Name</th><th>ER number</th><th>Catchphrase</th><th>Receipt / per diem</th><th>Remarks</th></tr>';
|
||||
foreach ($use as $d => $day) { // calculate for each day
|
||||
// set "no" as value for day's variable if empty
|
||||
$use[$d] = $use[$d] ?? 'no';
|
||||
$date[$d] = $date[$d] ?? 'no';
|
||||
$break[$d] = $break[$d] ?? 'no';
|
||||
$lunch[$d] = $lunch[$d] ?? 'no';
|
||||
$dinner[$d] = $dinner[$d] ?? 'no';
|
||||
$remark[$d] = $remark[$d] ?? '';
|
||||
Please find the expenses attached.";
|
||||
|
||||
if ($use[$d] === 'yes') {
|
||||
$rc_name = $_POST['rc_name'];
|
||||
$rc_er = $_POST['rc_er'];
|
||||
$rc_catch = $_POST['rc_catch'];
|
||||
|
||||
if ($rc_name === '') { $rc_name = "YOUR-NAME"; }
|
||||
if ($rc_er === '') { $rc_er = "ER-NUMBER"; }
|
||||
if ($rc_catch === '') { $rc_catch = "CATCHPHRASE"; }
|
||||
|
||||
$output .= "<tr>";
|
||||
|
||||
// 1. Name
|
||||
$output .= "<td>" . $rc_name . "</td>";
|
||||
|
||||
// 2. Date
|
||||
$output .= "<td>" . $date[$d] . "</td>";
|
||||
|
||||
// 3. Amount
|
||||
$r_day[$d] = preg_replace("/\./", ",", $r_day[$d]); // replace . by , in amount to make it compatible with the used spreadsheet template
|
||||
$output .= "<td>" . $r_day[$d] . "</td>";
|
||||
|
||||
// 4. Recipient Name (empty)
|
||||
$output .= "<td></td>";
|
||||
|
||||
// 5. ER number
|
||||
$output .= "<td>" . $rc_er . "</td>";
|
||||
|
||||
// 6. Catchphrase
|
||||
$output .= "<td>" . $rc_catch . "</td>";
|
||||
|
||||
// 7. Receipt/per diem
|
||||
$output .= "<td>per diem</td>";
|
||||
|
||||
// 8. Remarks
|
||||
if ($break[$d] === "yes") {
|
||||
$remark[$d] = "breakfast+";
|
||||
}
|
||||
if ($lunch[$d] === "yes") {
|
||||
$remark[$d] .= "lunch+";
|
||||
}
|
||||
if ($dinner[$d] === "yes") {
|
||||
$remark[$d] .= "dinner";
|
||||
}
|
||||
if ($break[$d] != "yes" && $lunch[$d] != "yes" && $dinner[$d] != "yes") {
|
||||
$remark[$d] = "nothing";
|
||||
}
|
||||
if ($break[$d] === "yes" && $lunch[$d] === "yes" && $dinner[$d] === "yes") {
|
||||
$remark[$d] = "everything";
|
||||
}
|
||||
$remark[$d] = preg_replace("/\+$/", "", $remark[$d]);
|
||||
$remark[$d] .= " self-paid";
|
||||
|
||||
$output .= "<td>" . $remark[$d] . "</td>";
|
||||
|
||||
$output .= "</tr>";
|
||||
|
||||
}
|
||||
// Finalise output table
|
||||
$html .= "<tr><td><strong>Total:</strong></td><td><strong>$r_total $cur</strong></td>";
|
||||
$html .= "<td colspan='5'></td></tr>";
|
||||
$html .= "</table>";
|
||||
if ($extra) {
|
||||
$html .= "<p>Extra remarks: <br />$extra</p>";
|
||||
|
||||
$email_body .= "
|
||||
|
||||
The sender added the following comment:
|
||||
|
||||
$extra";
|
||||
}
|
||||
|
||||
$output .= '</table>';
|
||||
|
||||
// Send email, and delete attachments
|
||||
$email->Body = $email_body;
|
||||
if ($mailopt === "normal" || $mailopt === "onlyme") {
|
||||
$email->send();
|
||||
$html .= $email->ErrorInfo;
|
||||
}
|
||||
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/pd-result.en.html', true);
|
||||
|
||||
echo replace_page($template, $output);
|
||||
echo replace_page($template, $html);
|
||||
|
||||
?>
|
||||
|
@ -3,53 +3,120 @@
|
||||
<version>1</version>
|
||||
|
||||
<head>
|
||||
<title>FSFE - Internal Tools - per diem calculator</title>
|
||||
<title>Per Diem / VKP statement</title>
|
||||
<style type="text/css">
|
||||
th {
|
||||
text-align: center;
|
||||
}
|
||||
tr.descr {
|
||||
font-style: italic;
|
||||
font-size: small;
|
||||
}
|
||||
#content input[type="radio"] {
|
||||
margin: 0 5px 0 15px;
|
||||
}
|
||||
label {
|
||||
font-weight: normal;
|
||||
margin-left: 5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Originally coded by Max Mehl <max.mehl [at] fsfe [dot] org> for FSFE e.V. -->
|
||||
<h1>Calculate per diem charges (VKP)</h1>
|
||||
<h1>Per Diem / VKP statement</h1>
|
||||
|
||||
<p>
|
||||
In this form, you can enter travel days – e.g. for conferences –
|
||||
and the meals you paid yourself during this time. The correct
|
||||
amount will be calculated and sent to the financial team.
|
||||
<strong>For each individual travel/conference, you have to fill
|
||||
the form separately! Do this as soon as possible after a
|
||||
conference to not forget details, and to make sure that the
|
||||
amount will be checked in time by the financial team.</strong>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
With the checkboxes of the left column you can add a day in your
|
||||
calculation; the unchecked days will be ignored. For your
|
||||
travelled days you can mark which meal you paid with your own
|
||||
money.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
By default the calculator assumes you paid all meals yourself, so
|
||||
you will have to uncheck those meals which FSFE paid for, e.g. by
|
||||
paying the hotel room incl. breakfast.
|
||||
</p>
|
||||
|
||||
<p>Using this form you can calculate the amount of money you can claim as
|
||||
reimbursement when travelling as FSFE staff. With the checkboxes of the
|
||||
left column you can add a day in you calculation; the unchecked days will
|
||||
be ignored. For your travelled days you can mark which meal you paid with
|
||||
your own money; per default the calculator assumes you paid all meals
|
||||
yourself, so you will have to uncheck those meals which FSFE paid for, e.g.
|
||||
by paying the hotel room incl. breakfast.</p>
|
||||
|
||||
<p>The outward and return travel day are calculated with a reduced per diem
|
||||
amount, according to the legislation of your residence (currently Sweden
|
||||
and Germany are pre-defined). Please make sure that you know whether a
|
||||
certain day counts as half/travel or full day.</p>
|
||||
<p>
|
||||
The outward and return travel day are calculated with a reduced
|
||||
per diem amount, according to the legislation of your residence
|
||||
(currently Germany is pre-defined). Please make sure that you
|
||||
know whether a certain day counts as half/travel or full day.
|
||||
</p>
|
||||
|
||||
<form action="/cgi-bin/perdiem.php" method="post">
|
||||
<h2>1. Select your own country</h2>
|
||||
|
||||
|
||||
<h2>1. Set general options</h2>
|
||||
|
||||
<div class="row 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="Alexander Sander|alex.sander">Alexander Sander</option>
|
||||
<option value="Bonnie Mehring|bonnie">Bonnie Mehring</option>
|
||||
<option value="Erik Albers|eal">Erik Albers</option>
|
||||
<option value="Francesca Indorato|fi">Francesca Indorato</option>
|
||||
<option value="Gabriel Ku Wei Bin|gabriel.ku">Gabriel Ku Wei Bin</option>
|
||||
<option value="Lucas Lasota|lucas.lasota">Lucas Lasota</option>
|
||||
<option value="Max Mehl|max.mehl">Max Mehl</option>
|
||||
<option value="Matthias Kirschner|mk">Matthias Kirschner</option>
|
||||
<option value="Reinhard Müller|reinhard">Reinhard Müller</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-3">ER number for this trip:</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="text" name="er" class="form-control" pattern="(^\?$|^er\.[\d]{4}-[\d]{2}-[\d]{2}\.[\d.-]+)" placeholder="er.2020-..." required="required" />
|
||||
</div>
|
||||
<div class="col-sm-5 small">
|
||||
(Enter <strong>?</strong> if you do not have it)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-3">Catchphrase of ER:</label>
|
||||
<div class="col-sm-4">
|
||||
<input type="text" name="catch" class="form-control" required="required" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>2. Select your own country</h2>
|
||||
|
||||
<!-- if you add new countries, the respective settings have to be set in PHP file -->
|
||||
<input type="radio" id="home-de" name="home" value="de" checked="checked" /><label for="home-de"> Germany</label>
|
||||
<input type="radio" id="home-other" name="home" value="other" />Other <input type="text" name="home_other" placeholder="€/0.2/0.4/0.4/0" /><label>(Other: currency and percentage rates: currency/breakfast/lunch/dinner/flat (e.g. "€/0.2/0.4/0.4/0" for Germany). If <em>Other</em> is selected, you'll have to set the values in step 2 manually)</label>
|
||||
<div class="form-group">
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="home" value="de" checked="checked" /> Germany
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="home" value="other" /> Other
|
||||
</label>
|
||||
<input type="text" name="home_other" placeholder="€/0.2/0.4/0.4/0" />
|
||||
<p>(Other: currency and percentage rates: currency/breakfast/lunch/dinner/flat (e.g. "€/0.2/0.4/0.4/0" for Germany). If <em>Other</em> is selected, you'll have to set the values for the destination country in the next step manually)</p>
|
||||
</div>
|
||||
|
||||
<h2>2. Select the destination country</h2>
|
||||
<h2>3. Select the destination country</h2>
|
||||
|
||||
<!-- you can add new countries. For the individual amounts, set value="CC=$travel/$full,[...]" -->
|
||||
<input type="radio" id="dest-de" name="dest" value="de=14/28,se=314.5/629" checked="checked" /><label for="dest-de"> Germany</label>
|
||||
<input type="radio" id="dest-be" name="dest" value="de=28/42,se=344/688" /><label for="dest-be"> Belgium</label><br />
|
||||
<input type="radio" id="dest-other" name="dest" value="other" />Other <input type="text" name="dest_other" placeholder="14/28" /><label>(Other: per diem travel/full (e.g. "14/28" for Germany -> Germany). <a href="https://www.reisekostenabrechnung.com/verpflegungsmehraufwand-2020/">(See the different rates per country.)</a></label>
|
||||
<div class="form-group">
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="dest" value="de=14/28,se=314.5/629" checked="checked" /> Germany
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="dest" value="de=28/42,se=344/688" /> Belgium
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="dest" value="other" /> Other
|
||||
</label>
|
||||
<input type="text" name="dest_other" placeholder="14/28" />
|
||||
<p>(Other: per diem travel/full (e.g. "14/28" for Germany -> Germany). <a href="https://www.reisekostenabrechnung.com/verpflegungsmehraufwand-2020/">(See the different rates per country.)</a></p>
|
||||
</div>
|
||||
|
||||
<h2>3. Which meal did you pay yourself?</h2>
|
||||
<h2>4. Which meal did you pay yourself?</h2>
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<th>Use</th>
|
||||
@ -154,14 +221,34 @@
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>4. Provide additional information for spreadsheet</h2>
|
||||
<p>If you want to copy&paste the output directly to your Reimbursement Claim spreadsheet, please provide additional data of your trip.</p>
|
||||
<h2>5. Extra remarks / notes</h2>
|
||||
|
||||
<input type="text" name="rc_name" placeholder="Your Name" /><label>(Your name, as used in the spreadsheet)</label><br />
|
||||
<input type="text" name="rc_er" placeholder="er.xxxx-xx-xx.yyy.zzzz" /><label>(The ER number used for your trip)</label><br />
|
||||
<input type="text" name="rc_catch" placeholder="Catchy Phrase" /><label>(Catchphrase which will be used for your trip)</label><br />
|
||||
<p>If necessary, you can add additional remarks and notes to the statement you send.</p>
|
||||
|
||||
<button type="submit" name="action" value="calc">Calculate per diem</button>
|
||||
<div class="form-group">
|
||||
<textarea name="extra" class="form-control" rows="3"></textarea>
|
||||
</div>
|
||||
|
||||
<h2>6. Submit per diem report</h2>
|
||||
|
||||
<p>If you would like to preview the results, either via email or
|
||||
only in the web interface, choose differing options below. To not
|
||||
lose your data, press the "back" button in your browser to come
|
||||
back to this page afterwards.</p>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="mailopt" value="normal" required="required" checked="checked" /> Send emails to finance team and me
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="mailopt" value="onlyme" required="required" /> Send email only to me
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="mailopt" value="none" required="required" /> Do not send any email at all
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Submit per diem report</button>
|
||||
|
||||
</form>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user