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

53
templates/lists/evt.tpl Normal file
View File

@@ -0,0 +1,53 @@
{cycle values="odd,even" reset=true print=false}
<table>
<tbody>
{section name=row loop=$arr_evt}
{if $arr_evt[row].evt_visible}
<tr id="row_evt{$arr_evt[row].evt_ID}" class="{cycle values="odd,even"}" >
<td nowrap class="option">
{if $kga.usr && $kga.usr.usr_sts != 2}
<a href ="#" onClick="editSubject('evt',{$arr_evt[row].evt_ID}); $(this).blur(); return false;"><img src='../skins/{$kga.conf.skin|escape:'html'}/grfx/edit2.gif' width='13' height='13' alt='{$kga.lang.edit}' title='{$kga.lang.edit} (ID:{$arr_evt[row].evt_ID})' border='0' /></a>
{/if}
<a href ="#" onClick="lists_update_filter('evt',{$arr_evt[row].evt_ID}); $(this).blur(); return false;"><img src='../skins/{$kga.conf.skin|escape:'html'}/grfx/filter.png' width='13' height='13' alt='{$kga.lang.filter}' title='{$kga.lang.filter}' border='0' /></a>
<a href ="#" class="preselect" onClick="buzzer_preselect('evt',{$arr_evt[row].evt_ID},'{$arr_evt[row].evt_name|replace:"'":"\\'"|escape:'html'}',0,0); return false;" id="ps{$arr_evt[row].evt_ID}"><img src='../skins/{$kga.conf.skin|escape:'html'}/grfx/preselect_off.png' width='13' height='13' alt='{$kga.lang.select}' title='{$kga.lang.select} (ID:{$arr_evt[row].evt_ID})' border='0' /></a>
</td>
<td width="100%" class="events" onClick="buzzer_preselect('evt',{$arr_evt[row].evt_ID},'{$arr_evt[row].evt_name|replace:"'":"\\'"|escape:'html'}',0,0); return false;" onmouseover="lists_change_color(this,true);" onmouseout="lists_change_color(this,false);">
{if $arr_evt[row].evt_visible != 1}<span style="color:#bbb">{/if}
{if $kga.conf.showIDs == 1}<span class="ids">{$arr_evt[row].evt_ID}</span> {/if}{$arr_evt[row].evt_name|escape:'html'}
{if $arr_evt[row].evt_visible != 1}</span>{/if}
</td>
<td nowrap class="annotation">
{$arr_evt[row].zeit|escape:'html'}
</td>
</tr>
{/if}
{/section}
{if $arr_evt == '0'}
<tr>
<td colspan='3'>
<strong style="color:red">{$kga.lang.noItems}</strong>
</td>
</tr>
{/if}
</tbody>
</table>

52
templates/lists/knd.tpl Normal file
View File

@@ -0,0 +1,52 @@
{cycle values="odd,even" reset=true print=false}
<table>
<tbody>
{section name=row loop=$arr_knd}
{if $arr_knd[row].knd_visible}
<tr id="row_knd{$arr_knd[row].knd_ID}" class="knd knd{$arr_knd[row].knd_ID} {cycle values="odd,even"}">
{* --- option cell ---*}
<td nowrap class="option">
{if $kga.usr && $kga.usr.usr_sts != 2}
<a href ="#" onClick="editSubject('knd',{$arr_knd[row].knd_ID}); $(this).blur(); return false;"><img src='../skins/{$kga.conf.skin|escape:'html'}/grfx/edit2.gif' width='13' height='13' alt='{$kga.lang.edit}' title='{$kga.lang.edit}' border='0' /></a>
{/if}
<a href ="#" onClick="lists_update_filter('knd',{$arr_knd[row].knd_ID}); $(this).blur(); return false;"><img src='../skins/{$kga.conf.skin|escape:'html'}/grfx/filter.png' width='13' height='13' alt='{$kga.lang.filter}' title='{$kga.lang.filter}' border='0' /></a>
</td>
{* --- name cell ---*}
<td width="100%" class="clients" onmouseover="lists_change_color(this,true);" onmouseout="lists_change_color(this,false);" onClick="lists_knd_prefilter({$arr_knd[row].knd_ID},'highlight'); $(this).blur(); return false;">
{if $arr_knd[row].knd_visible != 1}<span style="color:#bbb">{/if}
{if $kga.conf.showIDs == 1}<span class="ids">{$arr_knd[row].knd_ID}</span> {/if}{$arr_knd[row].knd_name|escape:'html'}
{if $arr_knd[row].knd_visible != 1}</span>{/if}
</td>
{* --- annotation cell ---*}
<td nowrap class="annotation">
{$arr_knd[row].zeit|escape:'html'}
</td>
</tr>
{/if}
{/section}
{if $arr_knd == '0'}
<tr>
<td colspan='3'>
<strong style="color:red">{$kga.lang.noItems}</strong>
</td>
</tr>
{/if}
</tbody>
</table>

54
templates/lists/pct.tpl Normal file
View File

@@ -0,0 +1,54 @@
{cycle values="odd,even" reset=true print=false}
<table>
<tbody>
{section name=row loop=$arr_pct}
{if $arr_pct[row].pct_visible}
<tr id="row_pct{$arr_pct[row].pct_ID}" class="pct knd{$arr_pct[row].knd_ID} {cycle values="odd,even"}" >
<td nowrap class="option">
{if $kga.usr && $kga.usr.usr_sts != 2}
<a href ="#" onClick="editSubject('pct',{$arr_pct[row].pct_ID}); $(this).blur(); return false;"><img src='../skins/{$kga.conf.skin|escape:'html'}/grfx/edit2.gif' width='13' height='13' alt='{$kga.lang.edit}' title='{$kga.lang.edit} (ID:{$arr_pct[row].pct_ID})' border='0' /></a>
{/if}
<a href ="#" onClick="lists_update_filter('pct',{$arr_pct[row].pct_ID}); $(this).blur(); return false;"><img src='../skins/{$kga.conf.skin|escape:'html'}/grfx/filter.png' width='13' height='13' alt='{$kga.lang.filter}' title='{$kga.lang.filter}' border='0' /></a>
<a href ="#" class="preselect" onClick="buzzer_preselect('pct',{$arr_pct[row].pct_ID},'{$arr_pct[row].pct_name|replace:"'":"\\'"|escape:'html'}',{$arr_pct[row].knd_ID},'{$arr_pct[row].knd_name|replace:"'":"\\'"|escape:'html'}'); lists_reload('evt'); return false;" id="ps{$arr_pct[row].pct_ID}"><img src='../skins/{$kga.conf.skin|escape:'html'}/grfx/preselect_off.png' width='13' height='13' alt='{$kga.lang.select}' title='{$kga.lang.select} (ID:{$arr_pct[row].pct_ID})' border='0' /></a>
</td>
<td width="100%" class="projects" onmouseover="lists_change_color(this,true);" onmouseout="lists_change_color(this,false);" onClick="buzzer_preselect('pct',{$arr_pct[row].pct_ID},'{$arr_pct[row].pct_name|replace:"'":"\\'"|escape:'html'}',{$arr_pct[row].knd_ID},'{$arr_pct[row].knd_name|replace:"'":"\\'"|escape:'html'}'); lists_reload('evt'); return false;">
{if $arr_pct[row].pct_visible != 1}<span style="color:#bbb">{/if}
{if $kga.conf.flip_pct_display}
{if $kga.conf.showIDs == 1}<span class="ids">{$arr_pct[row].pct_ID}</span> {/if}<span class="lighter">{$arr_pct[row].knd_name|truncate:30:"..."|escape:'html'}:</span> {$arr_pct[row].pct_name|escape:'html'}
{else}
{if $kga.conf.pct_comment_flag == 1}
{if $kga.conf.showIDs == 1}<span class="ids">{$arr_pct[row].pct_ID}</span> {/if}{$arr_pct[row].pct_name|escape:'html'} <span class="lighter">{if $arr_pct[row].pct_comment}({$arr_pct[row].pct_comment|truncate:30:"..."|escape:'html'}){else}<span class="lighter">({$arr_pct[row].knd_name|truncate:30:"..."|escape:'html'})</span>{/if}</span>
{else}
{if $kga.conf.showIDs == 1}<span class="ids">{$arr_pct[row].pct_ID}</span> {/if}{$arr_pct[row].pct_name|escape:'html'} <span class="lighter">({$arr_pct[row].knd_name|truncate:30:"..."|escape:'html'})</span>
{/if}
{/if}
{if $arr_pct[row].pct_visible != 1}</span>{/if}
</td>
<td class="annotation">
{$arr_pct[row].zeit|escape:'html'}
</td>
</tr>
{/if}
{/section}
{if $arr_pct == '0'}
<tr>
<td nowrap colspan='3'>
<strong style="color:red">{$kga.lang.noItems}</strong>
</td>
</tr>
{/if}
</tbody>
</table>

44
templates/lists/usr.tpl Normal file
View File

@@ -0,0 +1,44 @@
{cycle values="odd,even" reset=true print=false}
<table>
<tbody>
{section name=row loop=$arr_usr}
<tr id="row_usr{$arr_usr[row].usr_ID}" class="{cycle values="odd,even"}">
{* --- option cell ---*}
<td nowrap class="option">
<a href ="#" onClick="lists_update_filter('usr',{$arr_usr[row].usr_ID}); $(this).blur(); return false;"><img src='../skins/{$kga.conf.skin|escape:'html'}/grfx/filter.png' width='13' height='13' alt='{$kga.lang.filter}' title='{$kga.lang.filter}' border='0' /></a>
</td>
{* --- name cell ---*}
<td width="100%" class="clients">
{$arr_usr[row].usr_name|escape:'html'}
</td>
{* --- annotation cell ---*}
<td nowrap class="annotation">
</td>
</tr>
{/section}
{if $arr_usr == '0'}
<tr>
<td colspan='3'>
<strong style="color:red">{$kga.lang.noItems}</strong>
</td>
</tr>
{/if}
</tbody>
</table>