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
This commit is contained in:
TMS
2026-06-18 21:20:26 +00:00
commit eb299c9131
1099 changed files with 359817 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
<?php
/**
* This file is part of
* Kimai - Open Source Time Tracking // http://www.kimai.org
* (c) 2006-2009 Kimai-Development-Team
*
* Kimai is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; Version 3, 29 June 2007
*
* Kimai 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kimai; If not, see <http://www.gnu.org/licenses/>.
*/
// Always include the Kimai Standard Processor Initialization!
// insert KSPI
$isCoreProcessor = 0;
$dir_templates = "templates/";
require("../../includes/kspi.php");
switch ($axAction) {
case 'test':
echo $kga['usr']['timespace_in'];
break;
}
?>

View File

@@ -0,0 +1,40 @@
<?php /* Smarty version 2.6.20, created on 2015-02-02 15:35:09
compiled from index.tpl */ ?>
<?php echo '
<script type="text/javascript">
$(document).ready(function() {
summary_ext_onload();
});
</script>
<style>
.mytable {
border-collapse: collapse;
border-spacing: 0;
margin-bottom:30px;
}
.myth {
text-align: left;
font-weight: bold;
}
.myth {
border-right: 1px solid #999999;
padding: 5px;
}
.myth:first-child { border-left: 1px solid #999999; }
.mytd {
border-right: 1px solid #999999;
padding: 5px;
}
.mytd:first-child { border-left: 1px solid #999999; }
</style>
'; ?>
<div id="summary_ext_wrap" width="100%">
<div id ="summary_ext" width="100%">

View File

@@ -0,0 +1,2 @@
<?php /* Smarty version 2.6.20, created on 2015-02-02 07:37:03
compiled from index.php */ ?>

View File

@@ -0,0 +1,61 @@
;= =====================================================================================================
;= You can define vars as single values or as array, for array efinition separate string values with [,]
;= EXAMPLE_SINGLE_VALUE = "myvar"
;= EXAMPLE_ARRAY = "myvar1", "myvar2"
;= =====================================================================================================
;= =====================================================================================================
;= Basic Vars you must define
;= =====================================================================================================
EXTENSION_NAME = "Summary"
EXTENSION_KEY = "summary_ext"
EXTENSION_INIT_FILE = "ki_summary/init.php"
EXTENSION_DIR = "ki_summary"
ADMIN_ALLOWED = "1"
GROUP_LEADER_ALLOWED = "1"
USER_ALLOWED = "1"
CUSTOMER_ALLOWED = "0"
;= =====================================================================================================
;= Hooks
;= =====================================================================================================
; you may set this to an empty string if you don't want a function called up on tabchange
; multiple calls can be added using ";" as delimiter *inside* the quotes
; Hooklist:
; TAB_CHANGE_TRIGGER - gets called when any tab was clicked, regardless if the tab is already active or not
; TIMESPACE_CHANGE_TRIGGER - gets called everytime the datepicker picks a date (equally for start and end)
; BUZZER_RECORD_TRIGGER - fires when the buzzer was clicked for recording (also true for "record again" in ts_ext)
; BUZZER_STOP_TRIGGER - fires when the buzzer was hit in stop-state (true for stops in ts_ext)
; CHANGE_KND_TRIGGER - gets called when any change happend on a customer record
; CHANGE_PCT_TRIGGER - same for projects
; CHANGE_EVT_TRIGGER - same for events/tasks
; REG_TIMEOUTS - if you have timeouts running that do not need to run when the tab of your extension
; is not active, register them here. they will be terminated on tabchange and you have
; to restart them on triggerchange
; If you need a special hook for your extension please contact the core-team ;)
TAB_CHANGE_TRIGGER = "summary_ext_triggerchange();"
TIMESPACE_CHANGE_TRIGGER = "summary_ext_triggerTSS();"
;BUZZER_RECORD_TRIGGER = "summary_ext_triggerREC();"
;BUZZER_STOP_TRIGGER = "summary_ext_triggerSTP();"
;CHANGE_KND_TRIGGER =
;CHANGE_PCT_TRIGGER =
;CHANGE_EVT_TRIGGER =
;REG_TIMEOUTS =
;= =====================================================================================================
;= Optional Vars you could define
;= =====================================================================================================
CSS_INCLUDE_FILES = "../extensions/ki_summary/css/demo.css.php"
JS_INCLUDE_FILES[] = "../extensions/ki_summary/js/init.js"
JS_INCLUDE_FILES[] = "../extensions/ki_summary/js/func.js"

View File

@@ -0,0 +1,50 @@
<?php
header('Content-type: text/css');
$table_header = "../../../skins/standard/grfx/g3_table_header.png";
?>
#summary_ext_wrap {
border:1px solid #000;
border-top:none;
width: 98%;
left: 1%;
position:absolute;
overflow:hidden;
margin:0;
}
#summary_ext {
padding:10px;
background-color: #eee;
color:#000;
overflow:auto;
}
#summary_ext_header {
background-image: url('<?php echo $table_header; ?>');
border:1px solid #000;
color:#fff;
padding:5px 10px;
height:20px;
overflow:hidden;
position:absolute;
}
#summary_ext_advanced {
padding:10px;
}
#summary_timespan {
padding: 20px 0px;
}
#summary_screenshot
{
float:left;
margin-right:10px;
}

View File

@@ -0,0 +1,39 @@
<?php
/**
* This file is part of
* Kimai - Open Source Time Tracking // http://www.kimai.org
* (c) 2006-2009 Kimai-Development-Team
*
* Kimai is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; Version 3, 29 June 2007
*
* Kimai 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kimai; If not, see <http://www.gnu.org/licenses/>.
*/
// Include Basics
include('../../includes/basics.php');
$usr = checkUser();
// =========================================
// = Get the currently displayed timespace =
// =========================================
$timespace = get_timespace();
$in = $timespace[0];
$out = $timespace[1];
// Set smarty config.
require_once(WEBROOT.'libraries/smarty/Smarty.class.php');
$tpl = new Smarty();
$tpl->template_dir = 'templates/';
$tpl->compile_dir = 'compile/';
$tpl->display('index.tpl');
include_once './templates/index.php';
?>

View File

View File

@@ -0,0 +1,52 @@
/**
* This file is part of
* Kimai - Open Source Time Tracking // http://www.kimai.org
* (c) 2006-2009 Kimai-Development-Team
*
* Kimai is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; Version 3, 29 June 2007
*
* Kimai 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kimai; If not, see <http://www.gnu.org/licenses/>.
*/
function summary_ext_onload() {
$("#loader").hide();
}
function summary_ext_resize() {
// function must exist, so init can register it as callback
}
var background = new Array("#000000","#FFFF00","#76EE00","#CD3333","#B23AEE","#CDBE70");
var text = new Array("#FFFFFF","#000000","#000000","#FFFFFF","#FFFFFF","#000000");
function summary_ext_triggerchange() {
$("#testdiv").append(" This has been put here on tab change.");
array_target = Math.round(Math.random()*background.length);
$("#testdiv").css("color",text[array_target]);
$("#testdiv").css("background-color",background[array_target]);
}
function summary_ext_triggerTSS() {
$.post(summary_ext_path + "processor.php", { axAction: "test", axValue: 0, id: 0 },
function(data) {
$('#demo_timespace > span.timespace_target').html(data);
});
}
function summary_ext_triggerREC() {
logfile("trigger REC summary_ext");
}
function summary_ext_triggerSTP() {
logfile("trigger STP summary_ext");
}

View File

@@ -0,0 +1,53 @@
/**
* This file is part of
* Kimai - Open Source Time Tracking // http://www.kimai.org
* (c) 2006-2009 Kimai-Development-Team
*
* Kimai is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; Version 3, 29 June 2007
*
* Kimai 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kimai; If not, see <http://www.gnu.org/licenses/>.
*/
/****************************************************************************************************
*
* IMPORTANT NOTE:
*
* If you like a function to run when your extension is loaded into the extension-frame
* you CAN'T use the methods you'd normally use when the dom is ready build! So something like:
*
*
* $(document).ready(function(){
* [do something stupid...]
* });
*
*
* ... won't work here.
* This is because the dom is already finished loading BEFORE the extensions are hooked in!
* When You want JavaScript or jQuery to do something when your extension is loaded into its
* place in the *existing* DOM, you have to put a function-call *into* the content you load.
* You can also use the jQuery ready-funktion there!
*
****************************************************************************************************/
// set path of extension
var summary_ext_path = "../extensions/ki_summary/";
$(document).ready(function(){
var summary_ext_resizeTimer = null;
$(window).bind('resize', function() {
if (summary_ext_resizeTimer) clearTimeout(summary_ext_resizeTimer);
summary_ext_resizeTimer = setTimeout(summary_ext_resize, 500);
});
});

View File

@@ -0,0 +1,33 @@
<?php
/**
* This file is part of
* Kimai - Open Source Time Tracking // http://www.kimai.org
* (c) 2006-2009 Kimai-Development-Team
*
* Kimai is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; Version 3, 29 June 2007
*
* Kimai 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kimai; If not, see <http://www.gnu.org/licenses/>.
*/
// Always include the Kimai Standard Processor Initialization!
// insert KSPI
$isCoreProcessor = 0;
$dir_templates = "templates/";
require("../../includes/kspi.php");
switch ($axAction) {
case 'test':
echo $kga['usr']['timespace_in'];
break;
}
?>

View File

@@ -0,0 +1,570 @@
<?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>

View File

@@ -0,0 +1,41 @@
{* IMPORTANT NOTE:
Javascript or jQuery stuff that should run when your extension *has finished loading*
should sit in an special onload function like this:
*}
{literal}
<script type="text/javascript">
$(document).ready(function() {
summary_ext_onload();
});
</script>
<style>
.mytable {
border-collapse: collapse;
border-spacing: 0;
margin-bottom:30px;
}
.myth {
text-align: left;
font-weight: bold;
}
.myth {
border-right: 1px solid #999999;
padding: 5px;
}
.myth:first-child { border-left: 1px solid #999999; }
.mytd {
border-right: 1px solid #999999;
padding: 5px;
}
.mytd:first-child { border-left: 1px solid #999999; }
</style>
{/literal}
<div id="summary_ext_wrap" width="100%">
<div id ="summary_ext" width="100%">

View File

@@ -0,0 +1,338 @@
<?php
ini_set('max_execution_time', 5000);
$hostname="localhost";
$username="kimai";
$password="kimai";
$dbname="kimai";
$dbport = "3306";
$html = '';
$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>");
$sql = "SELECT DATE(NOW()) as 'current_date', DATE(NOW()) - INTERVAL 1 WEEK as 'week_start'";
$result = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_array($result)) {
$current_date = $row['current_date'];
$week_start = $row['week_start'];
}
if (isset($_GET['fromdate'])) {
$fromdate = $_GET['fromdate'];
} else {
$fromdate = $week_start;
}
if (isset($_GET['todate'])) {
$todate = $_GET['todate'];
$todatefront = $_GET['todate'];
} else {
$todate = $current_date;
$todatefront = $current_date;
}
$date = $todate;
$date1 = str_replace('-', '/', $date);
$todate = date('Y-m-d',strtotime($date1 . "+1 days"));
$sql = "SELECT (5 * (DATEDIFF('$todate', '$fromdate') DIV 7) + MID('0123455501234445012333450122234501101234000123450',
7 * WEEKDAY('$fromdate') + WEEKDAY('$todate') + 1, 1)) * 8.5 AS TotalResolutionTimeBusinessDays ";
$result = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_array($result)) {
$corehours = $row['TotalResolutionTimeBusinessDays'];
}
?>
<html>
<head>
<link href="css/bootstrap.min.css" rel="stylesheet" media="screen"/>
<link href="css/bootstrap-datetimepicker.min.css" rel="stylesheet" media="screen"/>
<script type="text/javascript" src="js/jquery-1.8.3.min.js" charset="UTF-8"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
<link rel='stylesheet' type='text/css' href='http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css'/>
<script src="js/jquery.highchartTable.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$('table.highchart').highchartTable();
});
$(document).ready(function() {
$("#fromdate").datepicker({ dateFormat: 'yy-mm-dd' });
$("#todate").datepicker({ dateFormat: 'yy-mm-dd' });
});
</script>
<script src="http://code.highcharts.com/stock/highstock.js"></script>
<script src="http://code.highcharts.com/stock/modules/exporting.js"></script>
<style>
.div {
-moz-border-radius: 20px;
-khtml-border-radius: 20px;
-webkit-border-radius: 20px;
border-radius: 20px;
overflow:hidden;
background:#eee;
-webkit-box-shadow:0 0 4em rgb(4,6,5);
-moz-box-shadow:0 0 3em rgb(6,7,8);
box-shadow:0 0 1em rgb(5,9,2);
border:20px solid #ddd;
font-family:Verdana, 20Geneva, sans-serif;
right: 1%;
left: 1%;
position: absolute;
padding: 2%;
alignment-adjust: central;
margin: 25px;
}
table {
border-collapse: collapse;
border-spacing: 0;
margin-bottom:30px;
}
th {
text-align: left;
font-weight: bold;
}
th {
border-right: 1px solid #999999;
padding: 5px;
}
th:first-child { border-left: 1px solid #999999; }
td {
border-right: 1px solid #999999;
padding: 5px;
}
td:first-child { border-left: 1px solid #999999; }
</style>
</head>
<body>
<?php
if (!isset($_GET['print'])) {
$html .= '<div class="div">';
}
?>
<legend>Date Selection</legend>
<form method="get">
<?php
if (!isset($_GET['print'])) {
$html .= "<a href='time.php?fromdate=$fromdate&todate=$todate&print' style='right: 1%; position: absolute; background: #ccc; text-decoration: none; color: black; padding: 10px;'><div>PRINT</div></a>";
}
?>
<label>From Date</label> <input type="text" id="fromdate" name="fromdate" value="<?php $html .= $fromdate ?>"><br/>
<label>To Date</label> <input type="text" id="todate" name="todate" value="<?php $html .= $todatefront ?>"><br/>
<input type="submit" value="submit">
</form>
<br/>
<legend>Summary Chart</legend>
<center>
<table border="1px" style="margin: 10px; width: 100%" class="highchart" data-graph-container-before="1" data-graph-type="column" >
<thead>
<tr>
<th>Name</th>
<th>Total Hours</th>
<th data-graph-type="line">Core Working Hours</th>
<th>Difference</th>
</tr>
</thead>
<tbody>
<?php
$sql = "select u.usr_alias as 'alias',
round(sum(e.zef_time) / 3600,2) as time_spent,
((5 * (DATEDIFF('$todate', '$fromdate') DIV 7) + MID('0123455501234445012333450122234501101234000123450', 7 * WEEKDAY('$fromdate') + WEEKDAY('$todate') + 1, 1)) * 8.5) AS needed_time,
round(((sum(e.zef_time) / 3600) - ((5 * (DATEDIFF('$todate', '$fromdate') DIV 7) + MID('0123455501234445012333450122234501101234000123450', 7 * WEEKDAY('$fromdate') + WEEKDAY('$todate') + 1, 1)) * 8.5)),2) as diff
from kimai_zef e
inner join kimai_usr u on e.zef_usrID=u.usr_ID
inner join kimai_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'))
group by u.usr_name
";
$result = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_array($result)) {
$name = $row['alias'];
$time_spent = $row['time_spent'];
$needed_time = $row['needed_time'];
$diff = $row['diff'];
$html .= "<tr><td>$name</td><td>$time_spent</td><td>$needed_time</td><td>$diff</td><tr>";
}
?>
</tbody>
</table>
</center>
<br/>
<legend>Detailed Summary</legend>
<table border="1px" style="margin: 10px; width: 100%">
<thead>
<tr>
<th>Project Name</th>
<?php
$sql = "select u.usr_name as 'name', u.usr_alias as 'alias' from kimai_zef e
inner join kimai_usr u on e.zef_usrID=u.usr_ID
inner join kimai_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'))
group by u.usr_name
";
$result = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_array($result)) {
$name = $row['name'];
$alias = $row['alias'];
$html .= "<th>$alias</th>";
$names[] = $name;
}
?>
<th>TOTAL</th>
</tr>
</thead>
<?php
$sql = "select p.pct_name as project, ROUND(SUM(e.zef_time) / 3600, 1) as project_total from kimai_zef e
inner join kimai_usr u on e.zef_usrID=u.usr_ID
inner join kimai_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'))
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'];
$html .= "<tr><td>$project</td>";
foreach ($names as $name) {
$sqla = "select ROUND(SUM(e.zef_time) / 3600, 1) as 'totaltime'
from kimai_zef e
inner join kimai_usr u on e.zef_usrID=u.usr_ID
inner join kimai_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'
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'];
$html .= "<td>$time</td>";
}
} else {
$html .= "<td></td>";
}
}
$html .= "<td>$projecttotal</td>";
$html .= "</tr>";
$totalforreport = $totalforreport + $projecttotal;
}
?>
<tr>
<td>TOTAL</td>
<?php
foreach ($names as $name) {
$sql = "select u.usr_alias as name, ROUND(SUM(e.zef_time) / 3600, 1) as 'totaltime'
from kimai_zef e
inner join kimai_usr u on e.zef_usrID=u.usr_ID
inner join kimai_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'
group by u.usr_name;";
$result = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_array($result)) {
$time = $row['totaltime'];
$html .= "<td>$time</td>";
}
}
$html .= "<td>$totalforreport</td>";
?>
</tr>
<tr>
<td>Core Working Hours</td>
<?php
$totalcorehours = 0;
foreach ($names as $name) {
$html .= "<td>$corehours</td>";
$totalcorehours = $totalcorehours + $corehours;
}
$html .= "<td>$totalcorehours</td>";
?>
</tr>
<tr>
<td>Difference</td>
<?php
foreach ($names as $name) {
$sql = "select u.usr_alias as name, ROUND(SUM(e.zef_time) / 3600, 2) as 'totaltime'
from kimai_zef e
inner join kimai_usr u on e.zef_usrID=u.usr_ID
inner join kimai_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'
group by u.usr_name;";
$result = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_array($result)) {
$time = $row['totaltime'] - $corehours;
$html .= "<td>$time</td>";
}
}
$difference = $totalforreport - $totalcorehours;
$html .= "<td>$difference</td>";
?>
</tr>
</table>
<?php
if (!isset($_GET['print'])) {
$html .= '</div>';
}
?>
<?php if (isset($_GET['print'])) {
$html .= '<script type="text/javascript">'
. '$(document).ready(function(){window.print();window.history.back();});'
. '</script>';
}
?>
</body>
</html>