Twig doesn't approximate number - php

I have a strange situation. My code is :
{% set total_amount=0 %}
{% for result in a_result %}
<tr>
<td>{% set total_amount=total_amount+("%.2f"|format(result.tva*result.prix_ht)) %}
{{ "%.2f"|format(result.tva*result.prix_ht) }}
</td>
/tr>
{% endfor %}
<tr>
<td colspan="5">Total</td>
<td>{{ total_amount }}</td>
</tr>
As result I have :
15.98, 25.49, 25.49
And Total = 65 but total should be equal with 65.96. I don't understand where is the problem. Can you help me please ?

I suggest you to use the round and number_format filter as follow:
{% set total_amount=0 %}
{% for result in a_result %}
{% set value = (result.tva* result.prix_ht)|round(2) %}
{% set total_amount=total_amount+value %}
<tr>
<td>
{{ value|number_format(2, '.', ',') }}
</td>
/tr>
{% endfor %}
<tr>
<td colspan="5">Total</td>
<td>{{ total_amount|number_format(2, '.', ',') }}</td>
</tr>
A running example with sample data in this twigfiddle files
Hope this help

Related

Tables side by side

How can I put two arrays side by side using twig ?
This is my input
{% for key, item in CompareArray %}
{% for x in item %}
<tr>
{% if key =='last' %}
<td> last</td>
{% endif %}
{% if key == 'primary' %}
<td> primary</td>
{% endif %}
</tr>
{% endfor %}
{% endfor %}
The desired output
table,td{
border: 1px solid black;
padding: 1px;
}
<table>
<tr>
<td> last.val1 </td>
<td> last.val2 </td>
<td> last.val3 </td>
<td> #### </td>
<td> primary.val1 </td>
<td> primary.val2 </td>
<td> primary.val3 </td>
</tr>
<tr>
<td> ... </td>
<td> ... </td>
<td> ... </td>
<td> ... </td>
<td> ... </td>
<td> ... </td>
<td> ... </td>
</tr>
<table>
Based on the shared information I see a couple of possible solutions.
But first confirm if I understand correctly what you're trying to achieve.
You want to have table where the item information of the last group is displayed first with a separator column and then the item information of the primary group on the left? And as seen in the screen shot of the array the number of items in the group isn't even necessarily the same?
First think to consider would be should we create two different tables one for primary group and one for last and style them through css to look as if they're in they are side by side.
{% for groupKey, items in CompareArray %}
<table>
{% for item in items %}
<tr>
<td>{{ groupKey }}.{{ item.prop1 }}</td>
<td>{{ groupKey }}.{{ item.prop2 }}</td>
<td>{{ groupKey }}.{{ item.prop3 }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
Second solution would be a complicated use of attribute this means that both arrays have to have same keys. Here you'd iterate over the largest group and then add the corresponding value from the other group. I'm using some macros to better separate the logic. The block named myTemplate is the code you'd insert where you wanted the data to be displayed.
{% block myTemplate %}
{% if CompareArray.last|length > CompareArray.primary|length %}
{{ _self.lastIsLonger(CompareArray.last, CompareArray.primary) }}
{% else %}
{{ _self.primaryIsLonger(CompareArray.last, CompareArray.primary) }}
{% endif %}
{% endblock %}
{% macro lastIsLonger(lastGroup, primaryGroup) %}
{% set primaryLenght = primaryGroup|length %}
<table>
{% for k,item in lastGroup %}
<tr>
{{ _self.buildElementData(item) }}
<td> #### </td>
{{ _self.buildElementData(loop.index <= primaryLenght ? attribute(primaryGroup, k) : {}) }}
</tr>
{% endfor %}
</table>
{% endmacro %}
{% macro primaryIsLonger(lastGroup, primaryGroup) %}
{% set lastGroupLength = lastGroup|length %}
<table>
{% for k,item in primaryGroup %}
<tr>
{{ _self.buildElementData(loop.index <= lastGroupLength ? attribute(lastGroup, k) : {}) }}
<td> #### </td>
{{ _self.buildElementData(item) }}
</tr>
{% endfor %}
</table>
{% endmacro %}
{% macro buildElementData(item) %}
<td>{{ item.prop1 ?? '' }}</td>
<td>{{ item.prop2 ?? '' }}</td>
<td>{{ item.prop3 ?? '' }}</td>
{% endmacro %}
If I understand what you're doing I think a third solution I think would be best. That is that from the PHP side you matched which items you wanted to compare so the data you'd insert would look something like this:
[
[
'last' => [
'prop1' => '...',
'prop2' => '...',
'prop3' => '...',
],
'primary' => [
'prop1' => '...',
'prop2' => '...',
'prop3' => '...',
],
], [
'last' => [
'prop1' => '...',
'prop2' => '...',
'prop3' => '...',
],
'primary' => [
'prop1' => '...',
'prop2' => '...',
'prop3' => '...',
],
]
];
This way you're not relying on dirty tricks and do most of the logic where it belongs. The corresponding generation template generation is thus much more pleasing.
{% block myTemplate %}
<table>
{% for row in CompareArray %}
<tr>
{{ _self.buildElementData(row.last ?? {}) }}
<td> #### </td>
{{ _self.buildElementData(row.primary ?? {}) }}
</tr>
{% endfor %}
</table>
{% endblock %}
{% macro buildElementData(item) %}
<td>{{ item.prop1 ?? '' }}</td>
<td>{{ item.prop2 ?? '' }}</td>
<td>{{ item.prop3 ?? '' }}</td>
{% endmacro %}

PHP loop: How can I repeat this loop after it happend once

So I have this loop
{% if employees %}
{% set count = 1 %}
{% set multiplier = 1 %}
{% for employeeIndex, employee in employees %}
<tr>
<td>{{ employee.werknemers }}</td>
{% for workdayIndex, workday in workdays %}
{% if (employeeIndex * multiplier) == workdayIndex %}
<td>x</td>
{% if count == (employees|length) %}
{% set multiplier = multiplier * employees|length %}
{% set count = count + 1 %}
{% endif %}
{% else %}
<td></td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
{% endif %}
The result is this :
What I want too happen is for the loop too repeat it self after every employee has a date assigned to them. As u can see the first X begins at 3 and goes down too 13. What I want is the X to begin from 14 again and go down the same way. This should be possible in Twig I believe. Thanks for helping out!!
I did not test this because I can't right now test twig but I think this should work
{% if employees %}
{% set employeeCount = (employees|length) %}
{% for employeeIndex, employee in employees %}
<tr>
<td>{{ employee.werknemers }}</td>
{% for workdayIndex, workday in workdays %}
{% if (workdayIndex - employeeIndex) is divisible by (employeeCount) %}
<td>x</td>
{% else %}
<td></td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
{% endif %}

PHP, symfony list data in table

This is a project for school!!!
Let's say that I want to store and show working hours in an HTML table.
I want something like, 'if' the date from DB which user added is equal to the date from the weekly calendar than show me an EDIT button else show me an ADD button?
I want to show Add for the rest of the users who didn't create any data in DB.
<table class="table" id="week">
<thead>
<tr>
<th scope="col">users</th>
{% for day in days %}
<th class="{{ day|date("D-d") }}">
<span>{{ day|date("D") }}</span>
<span>{{ day|date("d") }}</span>
</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for user in users %}
<tr class="days">
<th scope="row">{{ users.username }}</th>
{% for day in days %}
<td id="my_cell {{ day|date("d-m") }}">
{% for time in findTime %}
{% if d|date("d-m-Y") == time.date|date('d-m-Y') and users.id == time.getUser().id %}
{{ time.timeFrom|date("H:i") }} - {{ time.timeTo|date("H:i") }}
{% endif %}
{% endfor %}
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
I am currently using DB doctrine ORM on symfony 3.4v
I don't have an idea how to solve this problem, I tried with different array function in PHP but I did not find solutions.
Thank you for understanding.

translate tabledata in twig

I fill my table with data in this way
<tbody>
{% for post in posts %}
<tr>
<td>{{ post.title }}</td>
<td>{{ post.status }}</td>
</tr>
{% endfor %}
</tbody>
I need translate values from status, but it does not work. post.status has only 2 values in database PO_DRAFT and PO_ACCEPT and I need it translate. Is it possible?
I tried in this way but it is wrong
<td>{% trans %}{{ post.status }}{% endtrans %}</td>
Twig's i18n documentation mentions a trans filter, so maybe this would work?
{{ post.status | trans }}

Twig if/else not working

I'm not sure why my code isn't executing. I know that it should be working this way but all that happens now is that it doesn't do the else portion.
In debugging I know descriptions is not null and descriptions show for those that have it.
{% if descriptions is not null %}
{{ dump(descriptions) }}
{% for description in descriptions %}
<td>{{ description.productDesciption }}</td>
{% endfor %}
{% else %}
<td>
Create a Description for this Product
</td>
{% endif %}
You can simplify using the The else Clause of the for statement:
{% for description in descriptions %}
<td>
{{ description.productDesciption }}
</td>
{% else %}
<td>
Create a Description for this Product
</td>
{% endfor %}
Hope this help
You can use if into for loop.
{% for description in descriptions if descriptions is not null %}
<td>
{{ description.productDesciption }}
</td>
{% else %}
<td>
Create a Description for this Product
</td>
{% endfor %}

Categories