Hi,
I tried to enable timesheet printing in Sales invoices. With some additional features.
with the help of this post: https://discuss.frappe.io/t/sales-invoice-from-timesheet-function/26856/6
I created an aditional block in our invoices. This works, more or less. We need to have at least the date in the list, when this activity happend.
{% if doc.timesheets and doc.print_timesheets -%}
<div class="page-break"></div>
<h4>{{ _("Timesheets") }}</h4>
<table class="table table-bordered table-condensed">
<thead>
<tr>
<th style="width: 40px" class="table-sr">{{ _("Sr") }}</th>
<th style="width: 150px;">
{{ _("Date") }}</th>
<th style="width: 300px;">
{{ _("Note") }}</th>
<th style="width: 80px;" class="text-right">
{{ _("Hours") }}</th>
</tr>
</thead>
<tbody>
{% for ts in doc.timesheets %}
<tr>
<td class="table-sr">{{ loop.index }}</td>
<td>
<div class="value">
{{ frappe.utils.formatdate(ts.from_time) }} - {{ ts.start_date }}
</div>
</td>
<td>
<div class="value">
{{ ts.activity_type }} - {{ ts.description }}
</div>
</td>
<td class="text-right">
<div class="value">
{{ ts.billing_hours | round(2, 'ceil') }}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
I guess, I need to have start date/time in this list to get it print. But I was not able to do this, because start date is comming from a child - child table.
Thank you
rmeyer
August 28, 2021, 5:35pm
2
Hi @Andreas_Thuer , there have been some changes to sales invoice timesheet between v12 and v13. What version are you using?
1 Like
Hi @rmeyer ,
we are using V13.8 on the way to 13.9
Thank you
hi @rmeyer ,
do you have any helpfull information for us?
Thank you
Andreas
rmeyer
September 9, 2021, 4:50pm
5
Maybe try something like this. Couldn’t test it yet, but the from_time is not in the sales invoice timesheet table by default, so we’ll have to fetch it explicitly.
You can check which fields are available here .
{% if doc.timesheets and doc.print_timesheets -%}
<div class="page-break"></div>
<h4>{{ _("Timesheets") }}</h4>
<table class="table table-bordered table-condensed">
<thead>
<tr>
<th style="width: 40px" class="table-sr">{{ _("Sr") }}</th>
<th style="width: 150px;">
{{ _("Date") }}</th>
<th style="width: 300px;">
{{ _("Note") }}</th>
<th style="width: 80px;" class="text-right">
{{ _("Hours") }}</th>
</tr>
</thead>
<tbody>
{% for ts in doc.timesheets %}
{% set from_time = frappe.get_value("Timesheet Detail", ts.timesheet_detail, "from_time") %}
<tr>
<td class="table-sr">{{ loop.index }}</td>
<td>
<div class="value">
{{ frappe.utils.get_formatted(from_time, "dd.mm.yyyy") }}
</div>
</td>
<td>
<div class="value">
{{ ts.activity_type }} - {{ ts.description }}
</div>
</td>
<td class="text-right">
<div class="value">
{{ ts.billing_hours | round(2, 'ceil') }}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
rmeyer
September 9, 2021, 5:29pm
6
This should work as well:
{% if doc.timesheets -%}
<div style="page-break-after: always"></div>
<div class="timesheets">
<h3>Zeiterfassung</h3>
<div data-fieldname="timesheets" data-fieldtype="Table">
<table class="w-100 table table-bordered table-condensed">
<thead>
<tr>
<th style="width: 10%" class="table-sr">{{ _("Sr") }}</th>
<th style="width: 20%;" class="" data-fieldname="timesheets" data-fieldtype="Table">
{{_("Date")}}</th>
<th style="width: 20%;" class="" data-fieldname="timesheets" data-fieldtype="Table">
{{_("Employee")}}</th>
<th style="width: 40%;" class="" data-fieldname="timesheets" data-fieldtype="Table">
{{_("Note")}}</th>
<th style="width: 10%;" class="text-right" data-fieldname="timesheets" data-fieldtype="Table">
{{_("Hours")}}</th>
</tr>
</thead>
<tbody>
{% for ts in doc.timesheets %}
{% set timesheet = frappe.get_doc("Timesheet", ts.time_sheet)%}
{% if ts.billing_hours > 0 %}
<tr style="page-break-inside: avoid;">
<td class="table-sr">{{ loop.index }}</td>
<td class="" data-fieldname="timesheets" data-fieldtype="Table">
<div class="value">
{{ timesheet.get_formatted('start_date') }}
</div>
</td>
<td class="" data-fieldname="timesheets" data-fieldtype="Table">
<div class="value">
{{ timesheet.employee_name }}
</div>
</td>
<td class="" data-fieldname="timesheets" data-fieldtype="Table">
<div class="value">
{{ ts.description }}
</div>
</td>
<td class="text-right" data-fieldname="timesheets" data-fieldtype="Table">
<div class="value">
{{ "{:.2f}".format(ts.billing_hours) | replace(".", ",") }}
</div>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</div>
{%- endif %}
This approach takes the start date and employee name from the timesheet and the description and time from the timesheet detail .
It also doesn’t check for the custom field “print timesheets”. You can add that to the if-condition if needed.
1 Like
I have to write again. I am also in the process of adding time tracking to the invoice. However, I do not get the activity_type output. Unfortunately I need this. Can someone help me?
{% for ts in doc.timesheets | sort(attribute='start_date') %}
{% set timesheet = frappe.get_doc("Timesheet", ts.time_sheet)%}
<!-- {% if timesheet.total_billable_amount > 0 and timesheet.customer_note %} --> <!-- {% endif %} -->
<tr style="page-break-inside: avoid;">
<td class="" data-fieldname="timesheets" data-fieldtype="Table">
<div class="value">
{{ frappe.utils.formatdate(timesheet.start_date, "dd.mm.yyyy") }}
</div>
</td>
<td class="" data-fieldname="timesheets" data-fieldtype="Table">
<div class="value">
{{ timesheet.note }}
</div>
</td>
<td class="text-right" data-fieldname="timesheets" data-fieldtype="Table">
<div class="value">
{{ "{:.2f}".format(timesheet.total_billable_hours) | replace(".", ",") }}
</div>
</td>
<td >
<div class="value">
{{ timesheet.activity_type }}
{{ timesheet.employee_name }}
</div>
</td>
</tr>
{% endfor %}