Scripting Issue with Netsuite Advanced PDF/HTML Template - html

I need help with the Freemarker format for Netsuite (Advanced PDF/HTML Templates)
There are 3 important data values pulled for this records;
${item.quantity} *Order Value*
${item.fulfilled} *Fulfilled Value*
${item.backordered} *Backorder Value*
Basically, what I try to accomplish is, to only show items that are "on backorder"
However this task seems to be a much harder than I have the time and skill for.
So, my plan B is using a separate template for the backorders (which is working well so far!)
The problem is that if I came across an item which is a NON-INVENTORY item, Netsuite does not calculate any qty for ${item.backordered}
SO
Is there any way I can "calculate" the backorder value with scripting in the template?
Can I use an arithmetic function (like below)?
item.quantity - item.fulfilled = item.backordered
Here is the basic format of the text surrounding this query;
<#if record.item?has_content>
<table><#list record.item as item><#if item_index==0>
<thead>
<tr>
<th> QTY </th>
</tr>
</thead>
</#if>
<tr>
<td> ${item.backordered} </td>
</tr>
</#list></table>
</#if>
I have a basic understanding of HTML and CSS, but scripting is still very new to me, so please only constructive criticism.

Try adding the following Freemarker helper function to your template:
<#function toNumber val>
<#if val?has_content && val?length gt 0 >
<#return val?html?replace('[^0-9.]','','r')?number >
<#else>
<#return 0 >
</#if>
</#function>
This will ensure that all fields are correctly parsed as numbers, and you should be able to perform mathematical calculations on the fields without errors.
So you can replace:
<td> ${item.backordered} </td>
with:
<td> ${toNumber(item.quantity) - toNumber(item.fulfilled)} </td>

See the answer to suitescript set custom column value netsuite for an example that uses arithmetic on line item values.

So I believe the root problem lays with the Java JAR NetSuite is using. It appears it has a null pointer bug with empty int/number type values.
I would recommend adding a UserEvent script to change the values to zero that are empty. This will prevent the error you are getting. You should be able to catch the PRINT type on the before load event. If the zero value is not carried over to the template, you can add a custom column field that is not stored and push the value there.

Related

Visualforce / Apex: Access two objects with one controller

I'm forcing the problem that I have to set up a visualforce page rendered as pdf, which outputs a automatically generated invoice. Because of intern workflows this page has to be set up to the Opportunity object.
Most of the fields used are taken from the Opportunity object itself and work fine.
But I also need access to the OpportunityLineItem fields to display the products on the invoice.
How can this be realized? Do I have to write a controller extension in apex or is it possible without?
As an alternative, would this eventually be possible with cross formula fields referring from Opportunity to OpportunityLineItem? I tried this, but could not find any possibility to select OpportunityLineItem in a formula field in the Opportunity object.
Any help is much appreciated. Thanks!!
Below is a sample page accessing the OpportunityLineItems for a given Opportunity using the standard controller ammended from this doc reference.
<apex:page standardController="Opportunity">
<table border="0" >
<tr>
<th>Description</th><th>Quantity</th>
<th>Unit Price</th><th>Name</th>
</tr>
<apex:repeat var="oli" value="{!Opportunity.OpportunityLineItems}">
<tr>
<td>{!oli.Description}</td>
<td>{!oli.quantity}</td>
<td>{!oli.unitprice}</td>
<td>{!oli.Name}</td>
</tr>
</apex:repeat>
</table>
</apex:page>
With respect to formula fields, you cannot access child fields in a formula on the parent for the simple reason that it is a one to many relationship. The parent Opportunity would not know which of the children to lookup to.
The best you can do is make a regular (text or whatever) field, run a Process Builder triggered by a change to the relevant field(s) on the parent (opportunity) and trigger a Flow to loop over the children (LineItems) and make the changes to the parent based on some condition you specify.

Trying to loop through a list of options for an item but not print the very last option

<#list orderItem.options as option>
<tr>
<td class="order-item-detail">
${option.name} :
</td>
</tr>
<tr>
<td class="order-item-red">
${option.value}
</td>
</tr>
</#list>
The above code(inside of html) is what I am using in order to loop through a list of options inside of an item. At the current moment it loops through all options and prints them all. However I would like to make it so it does not print the final option inside of this list.
I am a bit limited because I have to do this through html alone. I am assuming I need some type of if statement to either tell it to stop when it reaches the last option or tell it specifically which option content to stop at but I can't seem to figure out how to write it.
option_index gives you the index of the current option and ?size gives you the length, you just need to compare them with an if statement
The option_index is 0 based so you need to minus 1 from the size to not include the last item
Note - you can also use option?index to get the index, depending on which version of freemarker you are using, but option_index will work in newer freemarker versions as well as older
For completeness I will also add the ?is_last, credit goes to ddekany's answer, usage <#if option?is_last>
Altogether if you have an updated freemarker version, the if statement can be written like so
Updated - assuming Freemarker 2.3.23 or later
<#if option?is_last>
....
</#if>
Original answer
<#list orderItem.options as option>
<#if option_index < orderItem.options?size - 1>
<tr>
<td class="order-item-detail">
${option.name} :
</td>
</tr>
<tr>
<td class="order-item-red">
${option.value}
</td>
</tr>
</#if>
</#list>
Documentation for size
https://freemarker.apache.org/docs/ref_builtins_sequence.html#ref_builtin_size
The number of sub variables in sequence (as a numerical value). The
highest possible index in sequence s is s?size - 1 (since the index of
the first subvariable is 0) assuming that the sequence has at least
one subvariable.
Documentation for index
https://freemarker.apache.org/docs/ref_builtins_loop_var.html#ref_builtin_index
Returns the 0-based index where the iteration (which is identified by
the loop variable name) currently stands.
You could cut off the last item of the list (beware, this gives error for an already empty list):
<#list orderItem.options[0 ..< orderItem.options?size - 1] as x>
...
</#list>
Alternatively, you can use ?is_last to check if you are at the last item, then add a nested #if that uses that:
<#list orderItem.options as option>
<#if !option?is_last>
...
</#if>
</#list>

How do I print the specific vendor bills reference numbers that are being paid in a check (NetSuite)?

I am printing a check form in NetSuite. I would like the check printout to list all of the vendor bill reference numbers that are being paid as a part of this check. Is there a way to do that? I am using the below code to obtain the Vendor Payment related to the check, but I'm unable to retrieve the vendor bill reference numbers themselves.
Thank you.
<table style="position: absolute;overflow: hidden;left: 36pt;top: 15pt;width: 436pt;"><tr>
<td>${check.tranid}</td>
<td>${check.transactionNumber}</td>
<td>${check.postingPeriod}</td>
<td align="right">${check.amount}</td>
</tr></table>
vendorpayment.apply gives you the sequence of bills to which the vendor payment is applied. I have tested this by customizing the "Standard Check PDF/HTML Template" with the following code, which shows how to get the reference number, application date and amount.
<?xml version="1.0"?>
<!DOCTYPE pdf PUBLIC "-//big.faceless.org//report" "report-1.1.dtd">
<pdf>
<body>
<#list records as vendorpayment>
<div>
<#if vendorpayment.apply?has_content>
<#list vendorpayment.apply as bill>
<table>
<tr>
<td>${bill.applydate}</td>
<td>${bill.refnum}</td>
<td>${bill.amount}</td>
</tr>
</table>
</#list>
</#if>
</div>
</#list>
</body>
</pdf>
Notes:
#if vendorpayment.apply?has_content is required in case the payment is not applied to any bills (such as when previewing or saving; vendorpayment.apply then evaluates to com.netledger.templates.model.StringModel, which cannot be iterated over).
The div is required so that the body has a child element if the table is not there because of the #if.
The documentation for the apply sublist of a VendorPayment is here: https://system.netsuite.com/help/helpcenter/en_US/srbrowser/Browser2017_1/script/record/vendorpayment.html#field_apply_
You cannot print information that is not on the Check record or linked via another field. Global search "Page: Checks". Select one of the records. Are the Vendor Bill reference numbers on the record currently? Or are the Vendor Bills linked to the Check record? If not, you cannot print the information. First get the information onto the record you're printing, then try to print it.
If the information is on the Check record, then where is it? Is there a Vendor Bill list? Is it under the Expenses & Items subtab? How you print it will depend on how the information is shown/linked on the record.

Creating a dynamic table In HTML and AngularJS from contents of a Javascript array

I need help creating a dynamic table in the format of a round robin competition using HTML and AngularJS. An array of strings will be given and then the table will be created based on how many names were in the list so part of the table will be generated dynamically and part of the table will always be the same. This is an example of a table that would be generated if I passed an array with 8 names. Only columns A, B, and C should have any information when the table is generated though I kept everything blank for simplicity's sake. The rest of the boxes should all be text input fields.
Until now most of the tables I have done have been pretty simple and I am a little out of my depth here, any help would be much appreciated.
Assuming you always have a full 8 teams this would get you started
<table>
<tr>
<th>club</th>
<th>team</th>
<th>#</th>
<th ng-repeat="item in items">{{$index+1}}</th>
<th>V</th>
<th>TS</th>
</tr>
<tr ng-repeat="item in items">
<td>{{item.club}}</td>
<td>{{item.team}}</td>
<td>{{item.rank}}</td>
<td ng-repeat="item in items" ng-class="{black:$index==$parent.$index}"></td>
<td><input ng-model="item.v"></td>
<td><input ng-model="item.ts"></td>
</tr>
</table>
DEMO
This is a really nice example of using nested ng-repeat elements.
Please see this plunker for a working demo.
The main trick for detecting when to black out a box is to use ng-init="$rowIndex=$index" on the outer ng-repeat (where we generate a row for each entry). This allows the inner ng-repeat (where we generate a column for each entry) to have an ng-class="{'blackout': $index==$rowIndex}"

Parameters and Loops in snippets

I would like to make a snippet that makes an HTML table.
Here are some examples of things to type :
table name address city
- table team wins losses draws
- table views clicks clickthrough
This is what I want it to output : a table with a columns for each of the fields (with 'table' triggering the snippet).
I'd also like to run these field names through a function to transform them (for example to field names - "First Name" -> 'first_name'.
Is this possible? How would I do it?
Not exactly what you want, but I would go with Emmet (here is a handy cheet sheet). There is a Sublime package available, so it's easy to install. It might be a little overwhelming at first, but once you start to use it, you will get the hang of it and it will speed up your html/css production.
Type table>tr*3>th and hit tab at the end. This will produce:
<table>
<tr>
<th></th>
</tr>
<tr>
<th></th>
</tr>
<tr>
<th></th>
</tr>
</table>
Then you can tab to the ths to type in your column headers.