Reputation: 53
in our company we are using Celigo middleware to get orders from eshop (US branch) into our accounting system (EU HQ). They are using kinda tricky field mapping process between these two systems, if you want to use conditions or any other function they are using handlebars: https://docs.celigo.com/hc/en-us/articles/360039326071-Handlebars-helper-reference link to their documentation with basic helpers, etc.
I come into situation when I want to do sum of tax rates but only when tax amount is greater than zero... For instance, you can have four different tax rates in US, however for shipping only two-three of them are applied, but in the payload all four are available so I want to filter out rates with zero amount.
origin handlebar without conditions:
{{#if shipping_lines_1.price}}
{{multiply
(sum shipping_lines_1.tax_lines.[0].rate
shipping_lines_1.tax_lines.[1].rate
shipping_lines_1.tax_lines.[2].rate
shipping_lines_1.tax_lines.[3].rate)
100}}
{{/if}}
part of the payload regarding "shipping_lines":
{"shipping_lines_1":
{"id": 1111111111,"carrier_identifier": null,"code": "Standard Shipping","delivery_category": null,"discounted_price": "8.90","discounted_price_set": {"shop_money": {"amount": "8.90","currency_code": "USD"},"presentment_money": {"amount": "8.90","currency_code": "USD"}},"phone": null,"price": "8.90","price_set": {"shop_money": {"amount": "8.90","currency_code": "USD"},"presentment_money": {"amount": "8.90","currency_code": "USD"}},"requested_fulfillment_service_id": null,"source": "shopify","title": "Standard Shipping",
"tax_lines": [
{"price": 0.09,
"price_set": {"shop_money": {"amount": "0.09","currency_code": "USD"},"presentment_money": {"amount": "0.09","currency_code": "USD"}},
"rate": 0.0625,
"title": "IL STATE TAX"},
{"price": 0.00,
"price_set": {"shop_money": {"amount": "0.00","currency_code": "USD"},"presentment_money": {"amount": "0.00","currency_code": "USD"}},
"rate": 0,
"title": "IL COUNTY TAX"},
{"price": 0.00,
"price_set": {"shop_money": {"amount": "0.00","currency_code": "USD"},"presentment_money": {"amount": "0.00","currency_code": "USD"}},
"rate": 0.01,
"title": "IL CITY TAX"},
{"price": 0.07,
"price_set": {"shop_money": {"amount": 0.07,"currency_code": "USD"},"presentment_money": {"amount": "0.07","currency_code": "USD"}},
"rate": 0.0075,
"title": "IL SPECIAL TAX"}],
"discount_allocations": []
}}
as you can see the tax code with a name "IL CITY TAX" has rate 0.01 however amount is zero, which leads into miscalculation in the accounting system when imported shipping tax rate is 8% instead of 7%
So I've added conditions to check tax amount/price at the first place and then do sum of rates when tax amount is greater than zero (in their system 0 or 0.00 is considered as falsy as well when you use #if):
{{#if shipping_lines_1.price}}
{{multiply
(sum
({{#if shipping_lines_1.tax_lines.[0].price}}{{shipping_lines_1.tax_lines.[0].rate}}{{else}}0{{/if}})
({{#if shipping_lines_1.tax_lines.[1].price}}{{shipping_lines_1.tax_lines.[1].rate}}{{else}}0{{/if}})
({{#if shipping_lines_1.tax_lines.[2].price}}{{shipping_lines_1.tax_lines.[2].rate}}{{else}}0{{/if}})
({{#if shipping_lines_1.tax_lines.[3].price}}{{shipping_lines_1.tax_lines.[3].rate}}{{else}}0{{/if}})
)100
}}
{{else}}0{{/if}}
Unfortunately, I always get an error: " Could not compile handle bar ... Parse error on line 4 ... Expecting 'ID', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', got 'OPEN_BLOCK'"
The "sum" and "multiply" helpers/functions are already implemented in the middleware system as per documentation attached above. AFAIK I am not able to register any additional helpers, however I was testing in on http://tryhandlebarsjs.com/ with following registered helpers:
Handlebars.registerHelper("multiply",function(a, b) {
return Number(a) * Number(b);
});
Handlebars.registerHelper("sum", function() {
var args = [].concat.apply([], arguments);
var len = args.length;
var sum = 0;
while (len--) {
if (!isNaN(args[len])) {
sum += Number(args[len]);
}
}
return sum;
});
My question here is: is there any Handlebars limitation, am I dumb I don't see missing parenthesis, should I take other approach for sum function or anything else?
Do you have any ideas for handlebars to correct the issue, please? Thank you in advance.
Upvotes: 1
Views: 644
Reputation: 9003
Handlebars does not support nesting mustache expressions within each other. So {{multiply... {{#if...
is simply not valid. The problem you are encountering is a good example of why a templating language, which is used for formatting output, should not be used for performing business logic, as it is doing with the tax calculation in your example.
Truly, I think the most correct solution would be to abandon the sum
and multiply
Handlebars helpers and perform the tax calculation in JavaScript and pass the result to Handlebars to format.
If, for some reason, this is not an option, and you absolutely must perform this calculation in the template, then you will need to write a custom helper that takes three arguments and, if the first is truthy, returns the second, else returns the third.
The helper would be quite simple:
Handlebars.registerHelper("ifThenElse", function (condition, ifTrue, ifFalse) {
return condition ? ifTrue : ifFalse;
});
You would then use the helper in your template as a Handlebars Subexpression, which allows you to nest helpers:
{{#if shipping_lines_1.price}}
{{multiply
(sum
(ifThenElse shipping_lines_1.tax_lines.[0].price shipping_lines_1.tax_lines.[0].rate 0)
(ifThenElse shipping_lines_1.tax_lines.[1].price shipping_lines_1.tax_lines.[1].rate 0)
(ifThenElse shipping_lines_1.tax_lines.[2].price shipping_lines_1.tax_lines.[2].rate 0)
(ifThenElse shipping_lines_1.tax_lines.[3].price shipping_lines_1.tax_lines.[3].rate 0)
)
100
}}
{{/if}}
I have created a fiddle for reference.
Upvotes: 2