Files
TMS eb299c9131 Initial commit: Kimai TMS
Kimai time management system (PHP 5.6 / MySQL) with custom extensions:
- Budget tracking (ki_budget)
- Change request form (ki_changerequest)
- Invoice generation (ki_invoice)
- Expense tracking (ki_expenses)
- Flexi time (ki_flexitime)
- Export, admin panel, timesheets, tasks, summary

Database: ~900K time entries, 2,000+ users, 439 projects.
Config: includes/autoconf.php — localhost/kimai/kimai
2026-06-18 21:20:26 +00:00

570 lines
21 KiB
PHP

<?php
ini_set('max_execution_time', 5000);
session_start();
$hostname = "localhost";
$username = "kimai";
$password = "kimai";
$dbname = "kimai";
$dbport = "3306";
$conn = mysqli_connect($hostname, $username, $password, $dbname, $dbport) or die("<html><script language='JavaScript'>alert('Unable to connect to database! Please try again later.'),history.go(-1)</script></html>");
$date_string = '';
$fromdate = gmdate("Y-m-d", $in);
$todate = gmdate("Y-m-d", $out);
$date = $todate;
$date1 = str_replace('-', '/', $date);
$todate = date('Y-m-d', strtotime($date1 . "+1 days"));
$date = $fromdate;
$date1 = str_replace('-', '/', $date);
$fromdate = date('Y-m-d', strtotime($date1 . "+1 days"));
$usrname = $usr['usr_name'];
$sql = "select u.reported_div from kimai15_usr u where u.usr_name = '$usrname'";
$result = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_assoc($result)) {
$selected_division = $row['reported_div'];
}
$summaryfromdate = $fromdate;
$summarytodate = gmdate("Y-m-d", $out);
mysqli_query($conn, "SET SESSION sql_mode = 'TRADITIONAL'");
?>
<form method="post">
<legend>Division Selection</legend>
<label for="divisionselect">Division:</label>
<select id='selected_division' name='selected_division' tabindex='12' required style="width:400px">
<?php
echo "<option value='$selected_division'>$selected_division</option>";
?>
<option value="ALL">ALL</option>
<option value="ADM">ADM</option>
<option value="APS">APS</option>
<option value="ADS">ADS</option>
<option value="BD">BD</option>
<option value="CAB">CAB</option>
<option value="COT">COT</option>
<option value="DCC">DCC</option>
<option value="DCS">DCS</option>
<option value="DCS">DNT</option>
<option value="DOL">DOL</option>
<option value="DSD">DSD</option>
<option value="ECM">ECM</option>
<option value="EXE">EXE</option>
<option value="EKU">EKU</option>
<option value="HR">HR</option>
<option value="ITS">ITS</option>
<option value="LEG">LEG</option>
<option value="MSA">MSA</option>
<option value="MSC">MSC</option>
<option value="MSD">MSD</option>
<option value="MSS">MSS</option>
<option value="OCJ">OCJ</option>
<option value="OPS">OPS</option>
<option value="PMO">PMO</option>
<option value="RAF">RAF</option>
<option value="SEC">SEC</option>
<option value="SMG">SMG</option>
<option value="TPT">TPT</option>
<option value="ULT">ULT</option>
<option value="WIC">WCG</option>
<option value="WIC">WIC</option>
<option value="XI">XI</option>
<option value="ZN1">ZN1</option>
<option value="ZN2">ZN2</option>
</select>
<input type="submit" value="REFRESH">
</form>
<br/>
<form method="post" action="exportsummary.php">
<input type="submit" name="download_report" value="Download">
<input id="printBtn" type="button" value="Print" />
<input type="hidden" name="usrname" value="<?php echo $usrname; ?>">
<input type="hidden" name="in" value="<?php echo $in; ?>">
<input type="hidden" name="out" value="<?php echo $out; ?>">
</form>
<br/>
<div id="content">
<h1>Time Analysis for <?php echo $selected_division ?> division(s) </h1>
<h2><?php echo $fromdate . " - " . gmdate("Y-m-d", $out); ?></h2>
<legend>Project Chart</legend>
<?php
try {
if ($selected_division == "ALL") {
$wheresub = "";
$where = "";
} else {
$wheresub = " and usr.usr_div = '$selected_division' ";
$where = " and u.usr_div = '$selected_division' ";
}
$con = new PDO("mysql:host=$hostname;port=$dbport;dbname=$dbname", "$username", "$password");
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$query = "SELECT un.name,un.division,
b.Billable,
nb.Non_Billable as 'Non-billable',
up.Unproductive,
(case when th.Total_Hours is null then 0.00 else th.Total_Hours end) as 'Total Hours',
(5 * (DATEDIFF('$todate', '$fromdate') DIV 7) + MID('0123455501234445012333450122234501101234000123450', 7 * WEEKDAY('$fromdate') + WEEKDAY('$todate') + 1, 1)) * 8.5 as 'Core Working Hours',
round((((case when th.Total_Hours is null then 0.00 else th.Total_Hours end))-((5 * (DATEDIFF('$todate', '$fromdate') DIV 7) + MID('0123455501234445012333450122234501101234000123450', 7 * WEEKDAY('$fromdate') + WEEKDAY('$todate') + 1, 1)) * 8.5)),2) as 'Difference'
FROM
(select u.usr_alias as 'Name', u.usr_div as 'Division'
from kimai15_zef e
inner join kimai15_usr u on e.zef_usrID=u.usr_ID
inner join kimai15_pct p on e.zef_pctID=p.pct_ID
where
u.usr_active = 1
$where
group by u.usr_name) un
LEFT JOIN
(SELECT usr.usr_alias, (case when (round(sum(zef.zef_time) / 3600,2)) is null then 0 else (round(sum(zef.zef_time) / 3600,2)) end) as Total_Hours
FROM kimai15_zef zef
INNER JOIN kimai15_usr usr on zef.zef_usrID = usr.usr_ID
inner join kimai15_pct pct on zef.zef_pctID=pct.pct_ID
WHERE zef.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d'))
and zef.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d')) group by usr.usr_name) th
ON (un.name=th.usr_alias)
LEFT JOIN
(SELECT usr.usr_alias, round(sum(zef.zef_time) / 3600,2) as Billable FROM kimai15_zef zef
INNER JOIN kimai15_usr usr on zef.zef_usrID = usr.usr_ID
INNER JOIN kimai15_pct pct on zef.zef_pctID=pct.pct_ID
WHERE pct.pct_billable = 0
and zef.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d'))
and zef.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d')) group by usr.usr_name) b
ON (un.name=b.usr_alias)
LEFT JOIN
(SELECT usr.usr_alias, round(sum(zef.zef_time) / 3600,2) AS Non_Billable FROM kimai15_zef zef
INNER JOIN kimai15_usr usr on zef.zef_usrID = usr.usr_ID
INNER JOIN kimai15_pct pct on zef.zef_pctID=pct.pct_ID
WHERE pct.pct_billable = 1
and zef.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d'))
and zef.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d')) group by usr.usr_name) nb
ON (un.name=nb.usr_alias)
LEFT JOIN
(SELECT usr.usr_alias, round(sum(zef.zef_time) / 3600,2) AS Unproductive FROM kimai15_zef zef
INNER JOIN kimai15_usr usr on zef.zef_usrID = usr.usr_ID
INNER JOIN kimai15_pct pct on zef.zef_pctID=pct.pct_ID
WHERE pct.pct_billable = 2
and zef.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d'))
and zef.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d')) group by usr.usr_name) up
ON (un.name=up.usr_alias)";
//echo $query;
echo '<table id="myTable" border="1" cellpadding="3" cellspacing="0">';
$result = $con->query($query);
//return only the first row (we only need field names)
$row = $result->fetch(PDO::FETCH_ASSOC);
echo " <tr> \n";
foreach ($row as $field => $value) {
echo " <th>$field</th> \n";
} // end foreach
echo " </tr> \n";
//second query gets the data
$data = $con->query($query);
$data->setFetchMode(PDO::FETCH_ASSOC);
foreach ($data as $row) {
echo " <tr> \n";
foreach ($row as $name => $value) {
echo " <td>$value</td> \n";
} // end field loop
echo " </tr> \n";
} // end record loop
echo "</table> \n";
} catch (PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
} // end try
?>
<br/>
<br/>
<legend>Total Hours by Billable Projects</legend>
<table class="mytable" border="1px" style="margin: 10px; width: 99%; font-size: 9px">
<thead class="myth">
<tr class="myth">
<th class="myth">Company Name</th>
<th class="myth">Project Name</th>
<?php
$sqlyu = "select u.usr_name as 'name', u.usr_alias as 'alias' from kimai15_zef e
inner join kimai15_usr u on e.zef_usrID=u.usr_ID
inner join kimai15_pct p on e.zef_pctID=p.pct_ID
where
e.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d')) and
e.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d'))
and p.pct_billable = 0
$where
group by u.usr_name
";
$resultyu = mysqli_query($conn, $sqlyu);
while ($rowyu = mysqli_fetch_array($resultyu)) {
$nameyu = $rowyu['name'];
$aliasyu = $rowyu['alias'];
echo "<th class='myth'>$aliasyu</th>";
$namesyu[] = $nameyu;
}
?>
<th class="myth">TOTAL</th>
</tr>
</thead>
<?php
$sqlyu = "select k.knd_name as companyname, p.pct_name as project, ROUND(SUM(e.zef_time) / 3600, 2) as project_total from kimai15_zef e
join kimai15_usr u on e.zef_usrID=u.usr_ID
inner join kimai15_pct p on e.zef_pctID=p.pct_ID
inner join kimai15_knd k on p.pct_kndID=k.knd_ID
where
e.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d')) and
e.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d'))
and p.pct_billable = 0
$where
group by p.pct_name
";
$resultyu = mysqli_query($conn, $sqlyu);
$totalforreportyu = 0;
while ($rowyu = mysqli_fetch_array($resultyu)) {
$projecttotalyu = $rowyu['project_total'];
$projectyu = $rowyu['project'];
$companynameyu = $rowyu['companyname'];
echo "<tr><td class='mytd'>$companynameyu</td><td class='mytd'>$projectyu</td>";
foreach ($namesyu as $nameyu) {
$sqlayu = "select ROUND(SUM(e.zef_time) / 3600, 2) as 'totaltime'
from kimai15_zef e
inner join kimai15_usr u on e.zef_usrID=u.usr_ID
inner join kimai15_pct p on e.zef_pctID=p.pct_ID
where
e.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d')) and
e.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d'))
and p.pct_name = '$projectyu'
and u.usr_name = '$nameyu'
and p.pct_billable = 0
$where
group by p.pct_name;";
$result1yu = mysqli_query($conn, $sqlayu);
$totalyu = 0;
if (mysqli_num_rows($result1yu) != 0) {
while ($rowyu = mysqli_fetch_array($result1yu)) {
$timeyu = $rowyu['totaltime'];
echo "<td>$timeyu</td>";
}
} else {
echo "<td></td>";
}
}
echo "<td>$projecttotalyu</td>";
echo "</tr>";
$totalforreportyu = $totalforreportyu + $projecttotalyu;
}
?>
<tr>
<td>TOTAL</td><td></td>
<?php
foreach ($namesyu as $nameyu) {
$sqlyu = "select u.usr_alias as name, ROUND(SUM(e.zef_time) / 3600, 2) as 'totaltime'
from kimai15_zef e
inner join kimai15_usr u on e.zef_usrID=u.usr_ID
inner join kimai15_pct p on e.zef_pctID=p.pct_ID
where
e.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d')) and
e.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d'))
and u.usr_name = '$nameyu'
and p.pct_billable = 0
$where
group by u.usr_name;";
$resultyu = mysqli_query($conn, $sqlyu);
while ($rowyu = mysqli_fetch_array($resultyu)) {
$timeyu = $rowyu['totaltime'];
echo "<td>$timeyu</td>";
}
}
echo "<td>$totalforreportyu</td>";
?>
</tr>
</table>
<br/>
<legend>Total Hours by Non-billable Projects</legend>
<table class="mytable" border="1px" style="margin: 10px; width: 99%; font-size: 9px">
<thead class="myth">
<tr class="myth">
<th class="myth">Company Name</th>
<th class="myth">Project Name</th>
<?php
$sql = "select u.usr_name as 'name', u.usr_alias as 'alias' from kimai15_zef e
inner join kimai15_usr u on e.zef_usrID=u.usr_ID
inner join kimai15_pct p on e.zef_pctID=p.pct_ID
where
e.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d')) and
e.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d'))
and p.pct_billable = 1
$where
group by u.usr_name
";
$result = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_array($result)) {
$name = $row['name'];
$alias = $row['alias'];
echo "<th class='myth'>$alias</th>";
$names[] = $name;
}
?>
<th class="myth">TOTAL</th>
</tr>
</thead>
<?php
$sql = "select k.knd_name as companyname, p.pct_name as project, ROUND(SUM(e.zef_time) / 3600, 2) as project_total from kimai15_zef e
inner join kimai15_usr u on e.zef_usrID=u.usr_ID
inner join kimai15_pct p on e.zef_pctID=p.pct_ID
inner join kimai15_knd k on p.pct_kndID=k.knd_ID
where
e.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d')) and
e.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d'))
and p.pct_billable = 1
$where
group by p.pct_name
";
$result = mysqli_query($conn, $sql);
$totalforreport = 0;
while ($row = mysqli_fetch_array($result)) {
$projecttotal = $row['project_total'];
$project = $row['project'];
$companyname = $row['companyname'];
echo "<tr><td class='mytd'>$companyname</td><td class='mytd'>$project</td>";
foreach ($names as $name) {
$sqla = "select ROUND(SUM(e.zef_time) / 3600, 2) as 'totaltime'
from kimai15_zef e
inner join kimai15_usr u on e.zef_usrID=u.usr_ID
inner join kimai15_pct p on e.zef_pctID=p.pct_ID
where
e.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d')) and
e.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d'))
and p.pct_name = '$project'
and u.usr_name = '$name'
and p.pct_billable = 1
$where
group by p.pct_name;";
$result1 = mysqli_query($conn, $sqla);
$total = 0;
if (mysqli_num_rows($result1) != 0) {
while ($row = mysqli_fetch_array($result1)) {
$time = $row['totaltime'];
echo "<td>$time</td>";
}
} else {
echo "<td></td>";
}
}
echo "<td>$projecttotal</td>";
echo "</tr>";
$totalforreport = $totalforreport + $projecttotal;
}
?>
<tr>
<td>TOTAL</td><td></td>
<?php
foreach ($names as $name) {
$sql = "select u.usr_alias as name, ROUND(SUM(e.zef_time) / 3600, 2) as 'totaltime'
from kimai15_zef e
inner join kimai15_usr u on e.zef_usrID=u.usr_ID
inner join kimai15_pct p on e.zef_pctID=p.pct_ID
where
e.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d')) and
e.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d'))
and u.usr_name = '$name'
and p.pct_billable = 1
$where
group by u.usr_name;";
$result = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_array($result)) {
$time = $row['totaltime'];
echo "<td>$time</td>";
}
}
echo "<td>$totalforreport</td>";
?>
</tr>
</table>
<br/>
<legend>Total Hours by Unproductive Projects</legend>
<table class="mytable" border="1px" style="margin: 10px; width: 99%; font-size: 9px">
<thead class="myth">
<tr class="myth">
<th class="myth">Company Name</th>
<th class="myth">Project Name</th>
<?php
$sqlui = "select u.usr_name as 'name', u.usr_alias as 'alias' from kimai15_zef e
inner join kimai15_usr u on e.zef_usrID=u.usr_ID
inner join kimai15_pct p on e.zef_pctID=p.pct_ID
where
e.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d')) and
e.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d'))
and p.pct_billable = 2
$where
group by u.usr_name
";
$resultui = mysqli_query($conn, $sqlui);
while ($rowui = mysqli_fetch_array($resultui)) {
$nameui = $rowui['name'];
$aliasui = $rowui['alias'];
echo "<th class='myth'>$aliasui</th>";
$namesui[] = $nameui;
}
?>
<th class="myth">TOTAL</th>
</tr>
</thead>
<?php
$sqlui = "select k.knd_name as companyname ,p.pct_name as project, ROUND(SUM(e.zef_time) / 3600, 2) as project_total from kimai15_zef e
inner join kimai15_usr u on e.zef_usrID=u.usr_ID
inner join kimai15_pct p on e.zef_pctID=p.pct_ID
inner join kimai15_knd k on p.pct_kndID=k.knd_ID
where
e.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d')) and
e.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d'))
and p.pct_billable = 2
$where
group by p.pct_name
";
$resultui = mysqli_query($conn, $sqlui);
$totalforreportui = 0;
while ($rowui = mysqli_fetch_array($resultui)) {
$projecttotalui = $rowui['project_total'];
$projectui = $rowui['project'];
$companynameui = $rowui['companyname'];
echo "<tr><td class='mytd'>$companynameui</td><td class='mytd'>$projectui</td>";
foreach ($namesui as $nameui) {
$sqlaui = "select ROUND(SUM(e.zef_time) / 3600, 2) as 'totaltime'
from kimai15_zef e
inner join kimai15_usr u on e.zef_usrID=u.usr_ID
inner join kimai15_pct p on e.zef_pctID=p.pct_ID
where
e.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d')) and
e.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d'))
and p.pct_name = '$projectui'
and u.usr_name = '$nameui'
and p.pct_billable = 2
$where
group by p.pct_name;";
$result1ui = mysqli_query($conn, $sqlaui);
$totalui = 0;
if (mysqli_num_rows($result1ui) != 0) {
while ($rowui = mysqli_fetch_array($result1ui)) {
$timeui = $rowui['totaltime'];
echo "<td>$timeui</td>";
}
} else {
echo "<td></td>";
}
}
echo "<td>$projecttotalui</td>";
echo "</tr>";
$totalforreportui = $totalforreportui + $projecttotalui;
}
?>
<tr>
<td>TOTAL</td><td></td>
<?php
foreach ($namesui as $nameui) {
$sqlui = "select u.usr_alias as name, ROUND(SUM(e.zef_time) / 3600, 2) as 'totaltime'
from kimai15_zef e
inner join kimai15_usr u on e.zef_usrID=u.usr_ID
inner join kimai15_pct p on e.zef_pctID=p.pct_ID
where
e.zef_in > UNIX_TIMESTAMP(DATE_FORMAT('$fromdate','%Y-%m-%d')) and
e.zef_in < UNIX_TIMESTAMP(DATE_FORMAT('$todate','%Y-%m-%d'))
and u.usr_name = '$nameui'
and p.pct_billable = 2
$where
group by u.usr_name;";
$resultui = mysqli_query($conn, $sqlui);
while ($rowui = mysqli_fetch_array($resultui)) {
$timeui = $rowui['totaltime'];
echo "<td>$timeui</td>";
}
}
echo "<td>$totalforreportui</td>";
?>
</tr>
</table>
</div>
<script>
$("#printBtn").click(function(){
printcontent($("#content").html());
});
function printcontent(content)
{
var mywindow = window.open('', '', '');
mywindow.document.write('<html><title></title><body>');
mywindow.document.write(content);
mywindow.document.write('</body></html>');
mywindow.document.close();
mywindow.print();
return true;
}
</script>