Calculation improvements for custom fields

So, I had a perfectly working theme that stopped doing calculations. @lubos
Something changed?
Seems to be that The result of math operations on two variables can’t be assigned anymore to a third variable.
Also I will add that on the Theme Preview (Lorem Ipsum) Looks like it brings the Result and assigns correctly.
Mind that Total Weight in Template Shows Zero as Weight Custom Column won’t show in Theme Preview.

And below is the real example trat USED to work.

{% for column in table.columns %}
{% if column.label == “Weight” %}
{% assign weightIndex = forloop.index0 %} (Gets the position of the Weight Column)
{% endif %}
{% if column.label == “Qty” %}
{% assign quantityIndex = forloop.index0 %} (Gets the position of the Qty Column)
{% endif %}
{% endfor %}



{% for row in table.rows %}
{% assign Weight = row.cells[weightIndex].text %} (Gets the Weight of the Product) Works
{% assign Quant = row.cells[quantityIndex].text %} (Gets the Qty of the Product) Works
{{Weight}} Weight <-------------------- This displays the Weight correctly
{{Quant}} Quant <-------------------- This displays the Quantity correctly
{% assign rowWeightSum = Weight | times: Quant %} <-------------------- This should multiply the weight of each item to the Qty of the item.
rowWeightSum {{rowWeightSum}} rowWeightSum <-------------------- This gives an empty Result. Should Display the sum of the row Weight * Qty
{% assign totalWeight = totalWeight | plus: rowWeightSum %}
{% assign NQuant = Quant | times: 1 %}
{% assign totalQuant = totalQuant | plus: NQuant %}

Complete Theme Below

<table style="padding: 30px">
    <thead>
        <tr>
            <td colspan="99">
                <table style="margin-bottom: 20px"><tr>
                    <td style="font-weight: bold; font-size: 32px">{{ title }}</td>
                    {% if business.logo != null %}<td style="text-align: right"><img src="{{ business.logo }}" style="max-height: 150px; max-width: 300px" /></td>{% endif %}
                </tr></table>
                
                <table style="margin-bottom: 20px"><tr>
                    <td>
                        <div style="font-weight: bold">{{ recipient.name }}</div>
                        <div>{{ recipient.address | newline_to_br }}</div>
                        <div>{{ recipient.identifier }}</div>
                    </td>
                    <td style="{% if business.address != null %}border-right-width: 1px; padding-right: 20px; {% endif %}text-align: right">
                        {% for field in fields %}
                        <div style="font-weight: bold">{{ field.label }}</div>
                        <div style="margin-bottom: 10px">{{ field.text }}</div>
                        {% endfor %}
                    </td>
                    {% if business.address != null %}
                    <td style="padding-left: 20px; width: 1px; white-space: nowrap">
                        <div style="font-weight: bold">{{ business.name }}</div>
                        <div>{{ business.address | newline_to_br }}</div>
                        <div>{{ business.identifier }}</div>
                    </td>
                    {% endif %}
                </tr></table>

                <div style="font-size: 14px; font-weight: bold; margin-bottom: 20px">{{ description }}</div>
            </td>
        </tr>
        <tr><td colspan='99' style="text-align: right; passing: 10px"><!--Page Counter--></td></tr>
        <tr>
            {% for column in table.columns %}
            <td style="font-weight: bold; padding: 5px 10px; text-align: {{ column.align }}; border-left-width: 1px; border-bottom-width: 1px; border-top-width: 1px{% if forloop.last == true %}; border-right-width: 1px{% endif %}{% if column.nowrap %}; width: 80px{% endif %}">{{ column.label }}</td>
            {% endfor %}
            {% for column in table.columns %}
                {% if column.label == "Weight" %}
                    {% assign weightIndex = forloop.index0 %}
                {% endif %}
                {% if column.label == "Qty" %}
                    {% assign quantityIndex = forloop.index0 %}
                {% endif %}
            {% endfor %}
        </tr>
    </thead>
    <tbody>
        {% for row in table.rows %}
        {% assign Weight = row.cells[weightIndex].text %}
        {% assign Quant = row.cells[quantityIndex].text %}
        {% assign rowWeightSum = Weight | times: Quant %}
        {% assign totalWeight = totalWeight | plus: rowWeightSum %}
        {% assign NQuant = Quant | times: 1 %}
        {% assign totalQuant = totalQuant | plus: NQuant %}
        <tr>
            {% for cell in row.cells %}
            <td style="padding: 5px 10px; text-align: {{ table.columns[forloop.index0].align }}; border-left-width: 1px{% if forloop.last == true %}; border-right-width: 1px{% endif %}{% if table.columns[forloop.index0].nowrap %}; white-space: nowrap; width: 80px{% endif %}">{{ cell.text | newline_to_br }}</td>
            {% endfor %}
        </tr>
        {% endfor %}
        <tr>
        {% for column in table.columns %}
            <td style="border-bottom-width: 1px; border-left-width: 1px{% if forloop.last == true %}; border-right-width: 1px{% endif %}">&nbsp;</td>
        {% endfor %}
        </tr>
        {% for total in table.totals %}
        <tr>
            <td colspan="{{ table.columns | size | minus:1 }}" style="padding: 5px 10px; text-align: right{% if total.emphasis == true %}; font-weight: bold{% endif %}">{{ total.label }}</td>
            <td style="border-left-width: 1px; white-space: nowrap; border-right-width: 1px; border-bottom-width: 1px; padding: 5px 10px; text-align: right{% if total.emphasis == true %}; font-weight: bold{% endif %}">{{ total.text }}</td>
        </tr>
        {% endfor %}

        {% for field in custom_fields %}
        <tr>
            <td colspan="99">
                <div style="font-weight: bold; padding-top: 20px">{{ field.label }}</div>
                <div>{{ field.text | newline_to_br }}</div>
            </td>
        </tr>
        {% endfor %}

        <tr>
            <td colspan="99">
                {% if emphasis.text != null and emphasis.positive %}
                <div style="text-align: center; margin-top: 40px"><span style="color: #006400; border-width: 5px; border-color: #006400; padding: 10px; font-size: 20px">{{ emphasis.text | upcase }}</span></div>
                {% endif %}

                {% if emphasis.text != null and emphasis.negative %}
                <div style="text-align: center; margin-top: 40px"><span style="color: #FF0000; border-width: 5px; border-color: #FF0000; padding: 10px; font-size: 20px">{{ emphasis.text | upcase }}</span></div>
                {% endif %}
            </td>
        </tr>
    </tbody>
<tr>
<td colspan="30">
<div style="font-weight: bold; padding-top: 20px">Total Weight</div>
</td>
</tr>
<tr>
<td>{{totalWeight}} kgs</td>
</tr>
<tr>
<td colspan="30"><div style="font-weight: bold; padding-top: 20px">Total Quantity</div></td>
</tr>
<tr>
<td>
{{totalQuant}}
</td>
</tr>
</table>

Nothing have changed in this regard for long time as far as Manager code goes so I assume this must result in some new behaviour in .NET itself.

So I assume times filter no longer works when using text variables.

Also, this is quite convoluted way to solve fairly generic requirement. I think items could have Weight field as built-in and then this could all work out of the box without any custom themes.

I can’t see how this is possible with the current manager version.

Do you mean there is another way , currently available to make this work?

image

From What I see When i change the times operator to | plus: 0 , it adds a zero to the end of the number, thus not converting the string to number as before when using |times: 1 or |plus: 0

Also for the sake of argument the “Text” does not compute anymore,
I’ll explicitly convert the text to numbers and then do the math.
Still not working in real scenario, but Theme Preview looks good.

    {% for row in table.rows %}
    {% assign Weight = row.cells[weightIndex].text | convert: "number" %}
    {% assign Quant = row.cells[quantityIndex].text | convert: "number" %}
    {% assign rowWeight = Weight | times: Quant %}
    {% assign totalWeight = totalWeight | plus: rowWeight %}
    {% assign totalQuant = totalQuant | plus: Quant %}

Live Example if I try to debug of whats happening with:

Ok Now I get it.
You could implement this in the future I mean, with Sums and everything!
Ok , would love to see that :slight_smile:

Please Add as a feature the option to have Custom Field Sum for numbers
in delivery forms and Invoice forms.
And Quantity Sum at the bottom as well.

This way we can Sum the weight, quantities and other things people might be interested in.
ie. litres for example

Until recently this could be achieved by using the Liquid programming language in Themes.
This doesn’t work now due to unforeseen changes in .NET as @lubos hypothesized.

I have read your other post and I kind of get your idea.

How about making your request about enabling summation of line custom fields of type number. This way everybody can benefit from it.

Cheers

2 Likes

Check the latest version (21.9.0). I have changed a few things so these plus and times filters work on text values.

I am sorry @lubos but that doesn’t seem to work on my side. I am on cloud version 2.9.1
Qty still does not convert to number.
Custom field | times: 1 works, but Qty | times: Custom Field doesn’t.
Qty | times: 1 produces 0 i.e. 30 to 0
Qty : plus: 0 appends a 0 i.e. 30 to 300

In Theme Preview seems Qty to work. Not on real scenario.

If I multiply Quantity with 1 , get a 0 , but if I don’t I get the following error:

Liquid error: Input string was not in a correct format. Liquid error: Input string was not in a correct format. Liquid error: Input string was not in a correct format.

This one here gives 0 for quantity but produces correct result in Theme Preview

       {% for column in table.columns %}
                {% if column.label == "Weight" %}
                    {% assign weightIndex = forloop.index0 %}
                {% endif %}
                {% if column.label == "Qty" %}
                    {% assign quantityIndex = forloop.index0 %}
                {% endif %}
            {% endfor %}
        </tr>
    </thead>
    <tbody>
        {% for row in table.rows %}
        {% assign Weight = row.cells[weightIndex].text %}
        {% assign Quant = row.cells[quantityIndex].text %}
        {% assign rowWeightSum = Weight | times: Quant %}
        {% assign totalWeight = totalWeight | plus: rowWeightSum %}
        {% assign NQuant = Quant | times: 1 %}
        {% assign totalQuant = totalQuant | plus: NQuant %}

The one below gives the error about Input string not in correct format.

Liquid error: Input string was not in a correct format. Liquid error: Input string was not in a correct format. Liquid error: Input string was not in a correct format.

          {% for column in table.columns %}
                {% if column.label == "Weight" %}
                    {% assign weightIndex = forloop.index0 %}
                {% endif %}
                {% if column.label == "Qty" %}
                    {% assign quantityIndex = forloop.index0 %}
                {% endif %}
            {% endfor %}
        </tr>
    </thead>
    <tbody>
        {% for row in table.rows %}
        {% assign Weight = row.cells[weightIndex].text %}
        {% assign Quant = row.cells[quantityIndex].text %}
        {% assign rowWeightSum = Weight | times: Quant %}
        {% assign totalWeight = totalWeight | plus: rowWeightSum %}
        {% assign totalQuant = totalQuant | plus: Quant %}

@lubos Thank you for your constant support.

We have been using to convert text with abs and adds the value in total as late fee for payment after the due date. Above changes does not resolve our problem yet, we would appreciate if you can update for text to number conversion and adding a value in it.

We need assistance for text to number for total value [total.text]. We are in stuck position, please assist!!

I am not sure why, but I decided to recreate my custom invoice from the “Plain” theme.
I changed how I wrote the calculation because changing a string to a number won’t work like it used to. I discovered that cell.text has a few extra hidden characters. You can find the starting number of the slice by outputting {{ cell.text | size }}. I had a few “blank” lines in the total column that were actually 6 characters long! I got rid of the extra characters with the slice filter.
{% assign mycustom_celltext = cell.text | slice: 5, 8 %}
Adding in the filter " | decimal ".
See my section of the code below. Hope this helps!

                         {% assign mycustom_celltext = cell.text | slice: 5, 8 %}
                         {% if mycustom_celltext contains "-" %}
                            {% assign mycustom_celltext = mycustom_celltext | slice: 2, 8 %}
                            {% assign mycustom_size = mycustom_celltext.size %}
                            {% if mycustom_size > 1 %}
                                {% assign mycustom_celltext = mycustom_celltext | remove: "," %}
                                {% assign mycustom_subtotal = mycustom_subtotal | decimal | minus: mycustom_celltext | decimal %}
                            {% endif %}
                        {% else %}
                            {% assign mycustom_size = mycustom_celltext.size %}
                            {% if mycustom_size > 1 %}
                                {% assign mycustom_celltext = mycustom_celltext | remove: "," %}
                                {% assign mycustom_subtotal = mycustom_subtotal | decimal | plus: mycustom_celltext | decimal %}
2 Likes