HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /home/timetracker.panomity.com/templates/timesheet/index.html.twig
{% extends 'datatable.html.twig' %}
{% import "macros/widgets.html.twig" as widgets %}
{% import "macros/datatables.html.twig" as tables %}

{% block datatable_outer %}
    {% set checkOverlappingDesc = false %}
    {% set checkOverlappingAsc = false %}
    {% set query = dataTable.getQuery() %}
    {% if query.orderBy == 'begin' or query.orderBy == 'end' %}
        {% set checkOverlappingDesc = (query.order == 'DESC') %}
        {% set checkOverlappingAsc = not checkOverlappingDesc %}
    {% endif %}

    {% set day = null %}
    {% set dayDuration = 0 %}
    {% set dayRate = {} %}
    {% set dayInternalRate = {} %}
    {% set dayHourlyRate = 0 %}
    {% set lastEntry = null %}

    {% for entry in dataTable %}
        {%- if day is same as(null) -%}
            {% set day = entry.begin|date_short %}
        {% endif %}
        {%- if showSummary and day is not same as(entry.begin|date_short) -%}
            {{ _self.summary(day, dayDuration, dayHourlyRate, dayInternalRate, dayRate, sortedColumns, dataTable) }}
            {% set day = entry.begin|date_short %}
            {% set dayDuration = 0 %}
            {% set dayRate = {} %}
            {% set dayInternalRate = {} %}
            {% set dayHourlyRate = 0 %}
        {%- endif -%}
        {%- set customerCurrency = entry.project.customer.currency -%}
        {%- set entryHourlyRate = entry.hourlyRate|money(customerCurrency) -%}
        {% block datatable_row %}
            <tr{{ block('datatable_row_attr') }}>
                {% for column, data in sortedColumns %}
                    {{ block('datatable_column') }}
                {% endfor %}
            </tr>
        {% endblock %}
        {%- if entry.end -%}
            {% if dayRate[customerCurrency] is not defined %}
                {% set dayRate = dayRate|merge({(customerCurrency): 0}) %}
            {% endif %}
            {% if dayInternalRate[customerCurrency] is not defined %}
                {% set dayInternalRate = dayInternalRate|merge({(customerCurrency): 0}) %}
            {% endif %}
            {% set dayRate = dayRate|merge({(customerCurrency): dayRate[customerCurrency] + entry.rate}) %}
            {% set dayInternalRate = dayInternalRate|merge({(customerCurrency): dayInternalRate[customerCurrency] + entry.internalRate}) %}
        {%- endif -%}
        {% if dayHourlyRate is not null %}
            {% if dayHourlyRate == 0 %}
                {% set dayHourlyRate = entryHourlyRate %}
            {% elseif dayHourlyRate != entryHourlyRate %}
                {% set dayHourlyRate = null %}
            {% endif %}
        {% endif %}
        {%- set dayDuration = dayDuration + entry.duration -%}
        {% set lastEntry = entry %}
    {% endfor %}
    {% if showSummary %}
        {{ _self.summary(day, dayDuration, dayHourlyRate, dayInternalRate, dayRate, sortedColumns, dataTable) }}
    {% endif %}
{% endblock %}

{% block status %}
    {% if stats.duration > 0 %}
        {% from "macros/status.html.twig" import status_duration %}
        {{ status_duration(stats.duration|duration) }}
    {% endif %}
{% endblock %}

{% block datatable_row_attr %}
    {% set class = '' %}
    {% if checkOverlappingDesc or checkOverlappingAsc %}
        {% if lastEntry is not null and entry.end is not null and entry.user is same as (lastEntry.user) %}
            {% if checkOverlappingDesc and entry.end.timestamp > lastEntry.begin.timestamp %}
                {% set class = class ~ ' overlapping' %}
            {% elseif checkOverlappingAsc and entry.begin.timestamp < lastEntry.end.timestamp %}
                {% set class = class ~ ' overlapping' %}
            {% endif %}
        {% endif %}
    {% endif %}
    {% if not entry.end %}
        {% set class = class ~ ' recording' %}
    {% endif %}
    {% if is_granted('edit', entry) %} class="modal-ajax-form open-edit{{ class }}" data-href="{{ path(editRoute, {'id': entry.id}) }}"{% endif %}
{% endblock %}

{% block datatable_column %}
    <td class="{{ tables.class(dataTable, column) }}{% if column == 'description' %} timesheet-description{% endif %}">
    {% if column == 'id' %}
            {% if is_granted('edit', entry) or is_granted('delete', entry) %}
                {{ tables.datatable_multiupdate_row(entry.id) }}
            {% endif %}
    {% elseif column == 'date' %}
        {{ entry.begin|date_short }}
    {% elseif column == 'starttime' %}
        {{ entry.begin|time }}
    {% elseif column == 'endtime' %}
        {% if entry.end %}
            {{ entry.end|time }}
        {% else %}
            &dash;
        {% endif %}
    {% elseif column == 'duration' %}
        {% if entry.end %}
            {{ entry.duration|duration }}
        {% else %}
            <i data-since="{{ entry.begin.format(constant('DATE_ISO8601')) }}">{{ entry|duration }}</i>
        {% endif %}
    {% elseif column == 'hourlyRate' %}
        {{ entryHourlyRate }}
    {% elseif column == 'rate' %}
        {% if not entry.end or not view_rate %}
            &dash;
        {% else %}
            {{ entry.rate|money(customerCurrency) }}
        {% endif %}
    {% elseif column == 'internalRate' %}
        {% if not entry.end or not view_rate %}
            &dash;
        {% else %}
            {{ entry.internalRate|money(customerCurrency) }}
        {% endif %}
    {% elseif column == 'customer' %}
        {{ widgets.label_customer(entry.project.customer) }}
    {% elseif column == 'project' %}
        {{ widgets.label_project(entry.project) }}
    {% elseif column == 'activity' %}
        {% if entry.activity is not null %}
            {{ widgets.label_activity(entry.activity) }}
        {% endif %}
    {% elseif column == 'description' %}
        {% if allowMarkdown %}
            {{ entry.description|desc2html }}
        {% else %}
            {{ entry.description|nl2br }}
        {% endif %}
    {% elseif column == 'tags' %}
        {{ widgets.tag_list(entry.tags) }}
    {% elseif column == 'billable' %}
        {{ widgets.label_boolean(entry.billable) }}
    {% elseif column == 'exported' %}
        {{ widgets.label_boolean(entry.exported) }}
    {% elseif column == 'username' %}
        {{ widgets.label_user(entry.user) }}
    {% elseif column == 'actions' %}
        {% set event = actions(app.user, action_single, 'index', {'timesheet': entry}) %}
        {{ widgets.table_actions(event.actions) }}
    {% elseif column starts with 'mf_' %}
            {{ widgets.meta_field_value(entry, data) }}
    {% endif %}
    </td>
{% endblock %}

{% macro summary(day, duration, dayHourlyRate, dayInternalRates, dayRates, sortedColumns, dataTable) %}
    {% import "macros/datatables.html.twig" as tables %}
    <tr class="summary info">
    {% for column, data in sortedColumns %}
        <td class="{{ tables.class(dataTable, column) }}">
        {% if column == 'date' %}
            {{ day }}
        {% elseif column == 'duration' %}
            {{ duration|duration }}
        {% elseif column == 'hourlyRate' %}
            {% if dayHourlyRate is not null and dayHourlyRate != 0 %}
                {{ dayHourlyRate }}
            {% endif %}
        {% elseif column == 'rate' %}
            {% for currency, rate in dayRates %}
                {{ rate|money(currency) }}
                {% if not loop.last %}
                    <br>
                {% endif %}
            {% endfor %}
        {% elseif column == 'internalRate' %}
            {% for currency, rate in dayInternalRates %}
                {{ rate|money(currency) }}
                {% if not loop.last %}
                    <br>
                {% endif %}
            {% endfor %}
        {% else %}

        {% endif %}
        </td>
    {% endfor %}
    </tr>
{% endmacro %}