Help with Jinja templating for a custom script report

I have the below template script for a custom report.

{%
	var report_columns = report.get_columns_for_print();
%}

<h2 class="text-center">{{ __("KENYA REVENUE AUTHORITY") }}</h2>
<h2 class="text-center">{{ __("DOMESTIC TAXES DEPARTMENT") }}</h2>
<h2 class="text-center">{{ __("TAX DEDUCTION CARD YEAR") }} {%= filters.fiscal_year %}</h2>
<br>

#Begin of lines causing errors
{% set company_tax_id = frappe.db.get_value('Company', {%= filters.company %}, ['tax_id']) %}
<tr class="text-left">{{ __("Employer's Name:") }} {%= filters.company %}</tr>
<tr class="text-left">{{ __("Employer's PIN:") }} {{ company_tax_id }}</tr>

{% set first_name, middle_name, last_name, emp_tax_id = frappe.db.get_value('Employee', {%= filters.employee %}, ['first_name', 'middle_name', 'last_name', 'tax_id']) %}
<tr class="text-left">{{ __("Employee's Main Name:") }} {%= first_name %}</tr>
<tr class="text-left">{{ __("Employee's Middle Name:") }} {%= middle_name %}</tr>
<tr class="text-left">{{ __("Employee's Last Name:") }} {%= last_name %}</tr>
<tr class="text-left">{{ __("Employee's PIN:") }} {%= emp_tax_id %}</tr>
#End of Lines causing errors
	
<hr>
<table class="table-bordered table-sm table-responsive">
	<thead>
		<tr>
			{% for (let i=0, l=report_columns.length; i<l; i++) { %}
				<th class="text-right">{%= report_columns[i].label %}</th>
			{% } %}
		</tr>
	</thead>
	<tbody>
		{% for(let j=0, k=data.length; j<k; j++) { %}
			{%
				var row = data[j];
			%}
			<tr>
				{% for(let i=0, l=report_columns.length; i<l; i++) { %}
					<td class="text-right">
						{% const fieldname = report_columns[i].fieldname; %}
						{% if (!is_null(row[fieldname])) { %}
							{%= frappe.format(row[fieldname], report_columns[i], {}, row) %}
						{% } %}
					</td>
				{% } %}
			</tr>
		{% } %}
	</tbody>
</table>
<p class="text-right text-muted">
	Printed On {%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}
</p>

I get the console error below, due to the lines marked with #Begin and End of lines causing errors

Uncaught TypeError: frappe.template.compile(…) is not a function
at Object.frappe.render (microtemplate.js:74)
at Object.frappe.render_template (microtemplate.js:85)
at Object.frappe.render_grid (microtemplate.js:105)
at QueryReport.print_report (query_report.js:1007)
at query_report.js:1201
at print.js:538
at frappe.ui.Dialog. (messages.js:76)
at HTMLButtonElement. (dialog.js:141)
at HTMLButtonElement.dispatch (jquery.min.js:3)
at HTMLButtonElement.r.handle (jquery.min.js:3)

Also the below.

If you check this link: https://jinja.palletsprojects.com/en/2.11.x/templates/ you’ll notice that you’re not using the right syntax.
Jinja isn’t JS, it has his own way of doing things. Ex: to define a variable, you need to use ‘set’ instead of ‘var’, the foreach can/need be use with list directly (instead of incrementing it manually), you need to close the if/for condition with {% endif %} or {% endfor %}, …
In fact, Jinja syntax looks like Python.

Hope this helps,

2 Likes

I will re-look at it. Thank you.

I think I might have mislabeled this to Jinja, because this code I just copied from an existing report in ERPNext and edited. It works well, until I introduce the lines below.

#Begin of lines causing errors
{% set company_tax_id = frappe.db.get_value(‘Company’, {%= filters.company %}, [‘tax_id’]) %}

{{ __("Employer's Name:") }} {%= filters.company %} {{ __("Employer's PIN:") }} {{ company_tax_id }}

{% set first_name, middle_name, last_name, emp_tax_id = frappe.db.get_value(‘Employee’, {%= filters.employee %}, [‘first_name’, ‘middle_name’, ‘last_name’, ‘tax_id’]) %}

{{ __("Employee's Main Name:") }} {%= first_name %} {{ __("Employee's Middle Name:") }} {%= middle_name %} {{ __("Employee's Last Name:") }} {%= last_name %} {{ __("Employee's PIN:") }} {%= emp_tax_id %} #End of Lines causing errors

So the looping, and var portions work just fine.

I might be confusing js/jinja as used in custom reports

@glz Although the same commands are use to render the templates in js client side and python server side
frappe.render_template
but they work differently. If you want to use jinja template use the server side rendering. JS side rendering has a limited scope.

The below link clarified the problem, and pointed to general ledger report, which is a good example of the scenario.

Eventually, I used hidden fields on the js to store required data, and displayed them as below.

{% if (filters.employee_name) { %} {%= __("Employee's Name: ")%} {%= filters.employee_name %} {% } %}

{% if (filters.employee_tax_id) { %} {%= __("Employee's PIN: ")%} {%= filters.employee_tax_id %} {% } %}