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,95 @@
{literal}
<script type="text/javascript">
$(document).ready(function() {
$('#help').hide();
$('#floater input#timeformat').attr('value',$('#xp_ext_timeformat').attr('value'));
$('#floater input#dateformat').attr('value',$('#xp_ext_dateformat').attr('value'));
$('#floater input#default_location').attr('value',$('#default_location').attr('value'));
$('#floater input#axValue').attr('value',filterUsr.join(":")+'|'+filterKnd.join(":")+'|'+filterPct.join(":")+'|'+filterEvt.join(":"));
$('#floater input#filter_cleared').attr('value',$('#xp_ext_tab_filter_cleared').attr('value'));
$('#floater input#filter_refundable').attr('value',$('#xp_ext_tab_filter_refundable').attr('value'));
$('#floater input#filter_type').attr('value',$('#xp_ext_tab_filter_type').attr('value'));
$('#floater input#axColumns').attr('value',xp_enabled_columns());
$('.floater_content fieldset label').css('width','200px');
$('#floater input#first_day').attr('value',new Date($('#pick_in').val()).getTime()/1000);
$('#floater input#last_day').attr('value',new Date($('#pick_out').val()).getTime()/1000);
});
</script>
{/literal}
<div id="floater_innerwrap">
<div id="floater_handle">
<span id="floater_title">{$kga.lang.xp_ext.exportCSV}</span>
<div class="right">
<a href="#" class="close" onClick="floaterClose();">{$kga.lang.close}</a>
</div>
</div>
<div id="help">
<div class="content">
</div>
</div>
<div class="floater_content">
<form id="xp_ext_form_export_CSV" action="../extensions/ki_export/processor.php" method="post">
<fieldset>
<ul>
<li>
<label for="column_delimiter">{$kga.lang.xp_ext.column_delimiter}:</label>
<input type="text" value="{$prefs.column_delimiter|escape:'html'}" name="column_delimiter" id="column_delimiter" size="1"/>
</li>
<li>
<label for="quote_char">{$kga.lang.xp_ext.quote_char}:</label>
<input type="text" value="{$prefs.quote_char|escape:'html'}" name="quote_char" id="quote_char" size="1">
</li>
<li>
<label for="reverse_order">{$kga.lang.xp_ext.reverse_order}:</label>
<input type="checkbox" value="true" name="reverse_order" id="reverse_order"/>
</li>
<li>
{$kga.lang.xp_ext.dl_hint}
</li>
</ul>
{* -------------------------------------------------------------------- *}
<!-- <input name="id" type="hidden" value="" /> -->
<input name="axAction" type="hidden" value="export_csv" />
<input name="axValue" id="axValue" type="hidden" value="" />
<input name="first_day" id="first_day" type="hidden" value="" />
<input name="last_day" id="last_day" type="hidden" value="" />
<input name="axColumns" id="axColumns" type="hidden" value=""/>
<input name="timeformat" id="timeformat" type="hidden" value=""/>
<input name="dateformat" id="dateformat" type="hidden" value=""/>
<input name="default_location" id="default_location" type="hidden" value=""/>
<input name="filter_cleared" id="filter_cleared" type="hidden" value=""/>
<input name="filter_refundable" id="filter_refundable" type="hidden" value=""/>
<input name="filter_type" id="filter_type" type="hidden" value=""/>
<div id="formbuttons">
<input class='btn_norm' type='button' value='{$kga.lang.cancel}' onClick='floaterClose(); return false;' />
<input class='btn_ok' type='submit' value='{$kga.lang.submit}' onClick="floaterClose();"/>
</div>
{* -------------------------------------------------------------------- *}
</fieldset>
</form>
</div>
</div>

View File

@@ -0,0 +1,121 @@
{literal}
<script type="text/javascript">
$(document).ready(function() {
$('#help').hide();
$('#floater input#timeformat').attr('value',$('#xp_ext_timeformat').attr('value'));
$('#floater input#dateformat').attr('value',$('#xp_ext_dateformat').attr('value'));
$('#floater input#default_location').attr('value',$('#xp_ext_default_location').attr('value'));
$('#floater input#axValue').attr('value',filterUsr.join(":")+'|'+filterKnd.join(":")+'|'+filterPct.join(":")+'|'+filterEvt.join(":"));
$('#floater input#filter_cleared').attr('value',$('#xp_ext_tab_filter_cleared').attr('value'));
$('#floater input#filter_refundable').attr('value',$('#xp_ext_tab_filter_refundable').attr('value'));
$('#floater input#filter_type').attr('value',$('#xp_ext_tab_filter_type').attr('value'));
$('#floater input#axColumns').attr('value',xp_enabled_columns());
$('.floater_content fieldset label').css('width','200px');
$('#floater input#first_day').attr('value',new Date($('#pick_in').val()).getTime()/1000);
$('#floater input#last_day').attr('value',new Date($('#pick_out').val()).getTime()/1000);
});
</script>
{/literal}
<div id="floater_innerwrap">
<div id="floater_handle">
<span id="floater_title">{$kga.lang.xp_ext.exportPDF}</span>
<div class="right">
<a href="#" class="close" onClick="floaterClose();">{$kga.lang.close}</a>
</div>
</div>
<div id="help">
<div class="content">
</div>
</div>
<div class="floater_content">
<form id="xp_ext_form_export_PDF" action="../extensions/ki_export/processor.php" method="post" target="_blank">
<fieldset>
<ul>
<li>
<label for="print_comments">{$kga.lang.xp_ext.print_comment}:</label>
<input type="checkbox" value="true" name="print_comments" id="print_comments" {if $prefs.print_comments}checked="checked"{/if}/>
</li>
<li>
<label for="print_summary">{$kga.lang.xp_ext.print_summary}:</label>
<input type="checkbox" value="true" name="print_summary" id="print_summary" {if $prefs.print_summary}checked="checked"{/if}>
</li>
<li>
<label for="create_bookmarks">{$kga.lang.xp_ext.create_bookmarks}:</label>
<input type="checkbox" value="true" name="create_bookmarks" id="create_bookmarks" {if $prefs.create_bookmarks}checked="checked"{/if}/>
</li>
<li>
<label for="download_pdf">{$kga.lang.xp_ext.download_pdf}:</label>
<input type="checkbox" value="true" name="download_pdf" id="download_pdf" {if $prefs.download_pdf}checked="checked"{/if}/>
</li>
<li>
<label for="customer_new_page">{$kga.lang.xp_ext.customer_new_page}:</label>
<input type="checkbox" value="true" name="customer_new_page" id="customer_new_page" {if $prefs.customer_new_page}checked="checked"{/if}/>
</li>
<li>
<label for="reverse_order">{$kga.lang.xp_ext.reverse_order}:</label>
<input type="checkbox" value="true" name="reverse_order" id="reverse_order" {if $prefs.reverse_order}checked="checked"{/if}/>
</li>
<li>
<label for="reverse_order">{$kga.lang.comment}:</label>
<textarea name="document_comment" id="document_comment"></textarea>
</li>
<li>
<label for="axAction">{$kga.lang.xp_ext.pdf_format}:</label>
<select name="axAction" id="axAction">
<option value="export_pdf" {if $prefs.pdf_format=='export_pdf'}selected="selected"{/if}>{$kga.lang.xp_ext.export_pdf}</option>
<option value="export_pdf2" {if $prefs.pdf_format=='export_pdf2'}selected="selected"{/if}>{$kga.lang.xp_ext.export_pdf2}</option>
</select>
</li>
<li>
{$kga.lang.xp_ext.dl_hint}
</li>
</ul>
{* -------------------------------------------------------------------- *}
<!-- <input name="id" type="hidden" value="" /> -->
<input name="axValue" id="axValue" type="hidden" value="" />
<input name="first_day" id="first_day" type="hidden" value="" />
<input name="last_day" id="last_day" type="hidden" value="" />
<input name="axColumns" id="axColumns" type="hidden" value=""/>
<input name="timeformat" id="timeformat" type="hidden" value=""/>
<input name="dateformat" id="dateformat" type="hidden" value=""/>
<input name="default_location" id="default_location" type="hidden" value=""/>
<input name="filter_cleared" id="filter_cleared" type="hidden" value=""/>
<input name="filter_refundable" id="filter_refundable" type="hidden" value=""/>
<input name="filter_type" id="filter_type" type="hidden" value=""/>
<div id="formbuttons">
<input class='btn_norm' type='button' value='{$kga.lang.cancel}' onClick='floaterClose(); return false;' />
<input class='btn_ok' type='submit' value='{$kga.lang.submit}' onClick="floaterClose();"/>
</div>
{* -------------------------------------------------------------------- *}
</fieldset>
</form>
</div>
</div>

View File

@@ -0,0 +1,87 @@
{literal}
<script type="text/javascript">
$(document).ready(function() {
$('#help').hide();
$('#floater input#timeformat').attr('value',$('#xp_ext_timeformat').attr('value'));
$('#floater input#dateformat').attr('value',$('#xp_ext_dateformat').attr('value'));
$('#floater input#default_location').attr('value',$('#default_location').attr('value'));
$('#floater input#axValue').attr('value',filterUsr.join(":")+'|'+filterKnd.join(":")+'|'+filterPct.join(":")+'|'+filterEvt.join(":"));
$('#floater input#filter_cleared').attr('value',$('#xp_ext_tab_filter_cleared').attr('value'));
$('#floater input#filter_refundable').attr('value',$('#xp_ext_tab_filter_refundable').attr('value'));
$('#floater input#filter_type').attr('value',$('#xp_ext_tab_filter_type').attr('value'));
$('#floater input#axColumns').attr('value',xp_enabled_columns());
$('.floater_content fieldset label').css('width','200px');
$('#floater input#first_day').attr('value',new Date($('#pick_in').val()).getTime()/1000);
$('#floater input#last_day').attr('value',new Date($('#pick_out').val()).getTime()/1000);
});
</script>
{/literal}
<div id="floater_innerwrap">
<div id="floater_handle">
<span id="floater_title">{$kga.lang.xp_ext.exportXLS}</span>
<div class="right">
<a href="#" class="close" onClick="floaterClose();">{$kga.lang.close}</a>
</div>
</div>
<div id="help">
<div class="content">
</div>
</div>
<div class="floater_content">
<form id="xp_ext_form_export_XLS" action="../extensions/ki_export/processor.php" method="post">
<fieldset>
<ul>
<li>
<label for="decimal_separator">{$kga.lang.decimal_separator}:</label>
<input type="text" value="{$kga.conf.decimalSeparator|escape:'html'}" name="decimal_separator" id="decimal-separator" size="1"/>
</li>
<li>
<label for="reverse_order">{$kga.lang.xp_ext.reverse_order}:</label>
<input type="checkbox" value="true" name="reverse_order" id="reverse_order" {if $prefs.reverse_order}checked="checked"{/if}/>
</li>
<li>
{$kga.lang.xp_ext.dl_hint}
</li>
</ul>
{* -------------------------------------------------------------------- *}
<input name="axAction" type="hidden" value="export_xls" />
<input name="axValue" id="axValue" type="hidden" value="" />
<input name="first_day" id="first_day" type="hidden" value="" />
<input name="last_day" id="last_day" type="hidden" value="" />
<input name="axColumns" id="axColumns" type="hidden" value=""/>
<input name="timeformat" id="timeformat" type="hidden" value=""/>
<input name="dateformat" id="dateformat" type="hidden" value=""/>
<input name="default_location" id="default_location" type="hidden" value=""/>
<input name="filter_cleared" id="filter_cleared" type="hidden" value=""/>
<input name="filter_refundable" id="filter_refundable" type="hidden" value=""/>
<input name="filter_type" id="filter_type" type="hidden" value=""/>
<div id="formbuttons">
<input class='btn_norm' type='button' value='{$kga.lang.cancel}' onClick='floaterClose(); return false;' />
<input class='btn_ok' type='submit' value='{$kga.lang.submit}' onClick="floaterClose();"/>
</div>
{* -------------------------------------------------------------------- *}
</fieldset>
</form>
</div>
</div>

View File

@@ -0,0 +1,55 @@
<div id="floater_innerwrap">
<div id="floater_handle">
<span id="floater_title">{$kga.lang.xp_ext.export_timeformat_help}</span>
<div class="right">
<a href="#" class="close" onClick="floaterClose();">{$kga.lang.close}</a>
</div>
</div>
<div class="floater_content">
<table class="xp_time_help_table">
<tr> <td class="xp_time_shortcut">a</td> <td class="xp_time_description">abbreviated weekday name according to the current locale</td> </tr>
<tr> <td class="xp_time_shortcut">A</td> <td class="xp_time_description">full weekday name according to the current locale</td> </tr>
<tr> <td class="xp_time_shortcut">b</td> <td class="xp_time_description">abbreviated month name according to the current locale</td> </tr>
<tr> <td class="xp_time_shortcut">B</td> <td class="xp_time_description">full month name according to the current locale</td> </tr>
<tr> <td class="xp_time_shortcut">c</td> <td class="xp_time_description">preferred date and time representation for the current locale</td> </tr>
<tr> <td class="xp_time_shortcut">C</td> <td class="xp_time_description">century number (the year divided by 100 and truncated to an integer, range 00 to 99)</td> </tr>
<tr> <td class="xp_time_shortcut">d</td> <td class="xp_time_description">day of the month as a decimal number (range 01 to 31)</td> </tr>
<tr> <td class="xp_time_shortcut">D</td> <td class="xp_time_description">same as m/d/y</td> </tr>
<tr> <td class="xp_time_shortcut">e</td> <td class="xp_time_description">day of the month as a decimal number, a single digit is preceded by a space (range 1 to 31)</td> </tr>
<tr> <td class="xp_time_shortcut">g</td> <td class="xp_time_description">Week-based year within century [00,99]</td> </tr>
<tr> <td class="xp_time_shortcut">G</td> <td class="xp_time_description">Week-based year, including the century [0000,9999]</td> </tr>
<tr> <td class="xp_time_shortcut">h</td> <td class="xp_time_description">same as b</td> </tr>
<tr> <td class="xp_time_shortcut">H</td> <td class="xp_time_description">hour as a decimal number using a 24-hour clock (range 00 to 23)</td> </tr>
<tr> <td class="xp_time_shortcut">I</td> <td class="xp_time_description">hour as a decimal number using a 12-hour clock (range 01 to 12)</td> </tr>
<tr> <td class="xp_time_shortcut">j</td> <td class="xp_time_description">day of the year as a decimal number (range 001 to 366)</td> </tr>
<tr> <td class="xp_time_shortcut">k</td> <td class="xp_time_description">Hour (24-hour clock) single digits are preceded by a blank. (range 0 to 23)</td> </tr>
<tr> <td class="xp_time_shortcut">l</td> <td class="xp_time_description">hour as a decimal number using a 12-hour clock, single digits preceeded by a space (range 1 to 12)</td> </tr>
<tr> <td class="xp_time_shortcut">m</td> <td class="xp_time_description">month as a decimal number (range 01 to 12)</td> </tr>
<tr> <td class="xp_time_shortcut">M</td> <td class="xp_time_description">minute as a decimal number</td> </tr>
<tr> <td class="xp_time_shortcut">n</td> <td class="xp_time_description">newline character</td> </tr>
<tr> <td class="xp_time_shortcut">p</td> <td class="xp_time_description"> either `am' or `pm' according to the given time value, or the corresponding strings for the current locale</td> </tr>
<tr> <td class="xp_time_shortcut">r</td> <td class="xp_time_description">time in a.m. and p.m. notation</td> </tr>
<tr> <td class="xp_time_shortcut">R</td> <td class="xp_time_description">time in 24 hour notation</td> </tr>
<tr> <td class="xp_time_shortcut">S</td> <td class="xp_time_description">second as a decimal number</td> </tr>
<tr> <td class="xp_time_shortcut">t</td> <td class="xp_time_description">tab character</td> </tr>
<tr> <td class="xp_time_shortcut">T</td> <td class="xp_time_description">current time, equal to H:M:S</td> </tr>
<tr> <td class="xp_time_shortcut">u</td> <td class="xp_time_description">weekday as a decimal number [1,7], with 1 representing Monday</td> </tr>
<tr> <td class="xp_time_shortcut">U</td> <td class="xp_time_description">week number of the current year as a decimal number, starting with the first Sunday as the first day of the first week</td> </tr>
<tr> <td class="xp_time_shortcut">V</td> <td class="xp_time_description">The ISO 8601:1988 week number of the current year as a decimal number, range 01 to 53, where week
1 is the first week that has at least 4 days in the current year, and with Monday as the first day of the week.</td> </tr>
<tr> <td class="xp_time_shortcut">w</td> <td class="xp_time_description">day of the week as a decimal, Sunday being 0</td> </tr>
<tr> <td class="xp_time_shortcut">W</td> <td class="xp_time_description">week number of the current year as a decimal number, starting with the first Monday
as the first day of the first week</td> </tr>
<tr> <td class="xp_time_shortcut">x</td> <td class="xp_time_description">preferred date representation for the current locale without the time</td> </tr>
<tr> <td class="xp_time_shortcut">X</td> <td class="xp_time_description">preferred time representation for the current locale without the date</td> </tr>
<tr> <td class="xp_time_shortcut">y</td> <td class="xp_time_description">year as a decimal number without a century (range 00 to 99)</td> </tr>
<tr> <td class="xp_time_shortcut">Y</td> <td class="xp_time_description">year as a decimal number including the century</td> </tr>
<tr> <td class="xp_time_shortcut">Z</td> <td class="xp_time_description">time zone or name or abbreviation</td> </tr>
</table>
</div>
</div>

View File

@@ -0,0 +1,83 @@
{literal}
<script type="text/javascript">
$(document).ready(function() {
$('#help').hide();
$('#floater input#timeformat').attr('value',$('#xp_ext_timeformat').attr('value'));
$('#floater input#dateformat').attr('value',$('#xp_ext_dateformat').attr('value'));
$('#floater input#default_location').attr('value',$('#default_location').attr('value'));
$('#floater input#axValue').attr('value',filterUsr.join(":")+'|'+filterKnd.join(":")+'|'+filterPct.join(":")+'|'+filterEvt.join(":"));
$('#floater input#filter_cleared').attr('value',$('#xp_ext_tab_filter_cleared').attr('value'));
$('#floater input#filter_refundable').attr('value',$('#xp_ext_tab_filter_refundable').attr('value'));
$('#floater input#filter_type').attr('value',$('#xp_ext_tab_filter_type').attr('value'));
$('#floater input#axColumns').attr('value',xp_enabled_columns());
$('.floater_content fieldset label').css('width','200px');
$('#floater input#first_day').attr('value',new Date($('#pick_in').val()).getTime()/1000);
$('#floater input#last_day').attr('value',new Date($('#pick_out').val()).getTime()/1000);
});
</script>
{/literal}
<div id="floater_innerwrap">
<div id="floater_handle">
<span id="floater_title">{$kga.lang.xp_ext.print}</span>
<div class="right">
<a href="#" class="close" onClick="floaterClose();">{$kga.lang.close}</a>
</div>
</div>
<div id="help">
<div class="content">
</div>
</div>
<div class="floater_content">
<form id="xp_ext_form_print" action="../extensions/ki_export/processor.php" method="post" target="_blank">
<fieldset>
<ul>
<li>
{$kga.lang.xp_ext.print_hint}
</li>
<li>
<label for="print_summary">{$kga.lang.xp_ext.print_summary}:</label>
<input type="checkbox" value="true" name="print_summary" id="print_summary" {if $prefs.print_summary}checked="checked"{/if}>
</li>
<li>
<label for="reverse_order">{$kga.lang.xp_ext.reverse_order}:</label>
<input type="checkbox" value="true" name="reverse_order" id="reverse_order" {if $prefs.reverse_order}checked="checked"{/if}/>
</li>
</ul>
{* -------------------------------------------------------------------- *}
<input name="axAction" type="hidden" value="export_html" />
<input name="axValue" id="axValue" type="hidden" value="" />
<input name="first_day" id="first_day" type="hidden" value="" />
<input name="last_day" id="last_day" type="hidden" value="" />
<input name="axColumns" id="axColumns" type="hidden" value=""/>
<input name="timeformat" id="timeformat" type="hidden" value=""/>
<input name="dateformat" id="dateformat" type="hidden" value=""/>
<input name="default_location" id="default_location" type="hidden" value=""/>
<input name="filter_cleared" id="filter_cleared" type="hidden" value=""/>
<input name="filter_refundable" id="filter_refundable" type="hidden" value=""/>
<input name="filter_type" id="filter_type" type="hidden" value=""/>
<div id="formbuttons">
<input class='btn_norm' type='button' value='{$kga.lang.cancel}' onClick='floaterClose(); return false;' />
<input class='btn_ok' type='submit' value='{$kga.lang.submit}' onClick="floaterClose();"/>
</div>
{* -------------------------------------------------------------------- *}
</fieldset>
</form>
</div>
</div>