FreeMarker/NetSuite PDF Template – Double sorting by date, with possible empty values

<table>

  <tr>
    <th>name</th>
    <th>quantity</th>
    <th>dateFrom</th>
    <th>dateTo</th>
  </tr>

  <!-- Print entries with from/to dates -->
  <#list records?filter(x -> x.custcol_from_date?has_content && x.custcol_to_date?has_content)?sort_by("custcol_to_date")?sort_by("custcol_from_date") as record>
    <tr>
      <td>${record.name}</td>
      <td>${record.quantity}</td>
      <td>${record.custcol_from_date}</td>
      <td>${record.custcol_to_date}</td>
    </tr>
  </#list>

  <!-- Print entries without from/to date at the end of table -->
  <#list records?filter(x -> !x.custcol_from_date?has_content || !x.custcol_to_date?has_content) as record>
   <tr>
      <td>${record.name}</td>
      <td>${record.quantity}</td>
      <td>${record.custcol_from_date}</td>
      <td>${record.custcol_to_date}</td>
    </tr>
  </#list>

</table>

Working of the freemarker code:

### Explanation of the Logic and Filter Functionality


The given code is designed to generate an HTML table from a list of records, using FreeMarker Template Language (FTL). The logic filters and sorts the records based on the presence and values of `custcol_from_date` and `custcol_to_date` fields. Let's break down the code step-by-step:


#### HTML Table Structure


```html
<table>
  <tr>
    <th>name</th>
    <th>quantity</th>
    <th>dateFrom</th>
    <th>dateTo</th>
  </tr>
</table>
```


This sets up an HTML table with four columns: `name`, `quantity`, `dateFrom`, and `dateTo`.


#### Printing Entries with Both `from` and `to` Dates


```html
<#list records?filter(x -> x.custcol_from_date?has_content && x.custcol_to_date?has_content)?sort_by("custcol_to_date")?sort_by("custcol_from_date") as record>
  <tr>
    <td>${record.name}</td>
    <td>${record.quantity}</td>
    <td>${record.custcol_from_date}</td>
    <td>${record.custcol_to_date}</td>
  </tr>
</#list>
```


1. **Filter**: `records?filter(x -> x.custcol_from_date?has_content && x.custcol_to_date?has_content)`
   - This filters the `records` list to include only those records where both `custcol_from_date` and `custcol_to_date` have content (i.e., are not null or empty).
   
2. **Sort**: `?sort_by("custcol_to_date")?sort_by("custcol_from_date")`
   - The filtered list is sorted first by `custcol_from_date` and then by `custcol_to_date`. The sorting is done twice because FreeMarker's `sort_by` does a stable sort, meaning the first sort order is preserved while applying the second.
   
3. **List Iteration**: `as record`
   - Iterates over the sorted and filtered list, outputting each record as a row in the table.


#### Printing Entries Without `from` or `to` Dates


```html
<#list records?filter(x -> !x.custcol_from_date?has_content || !x.custcol_to_date?has_content) as record>
  <tr>
    <td>${record.name}</td>
    <td>${record.quantity}</td>
    <td>${record.custcol_from_date}</td>
    <td>${record.custcol_to_date}</td>
  </tr>
</#list>
```


1. **Filter**: `records?filter(x -> !x.custcol_from_date?has_content || !x.custcol_to_date?has_content)`
   - This filters the `records` list to include only those records where either `custcol_from_date` or `custcol_to_date` (or both) do not have content.
   
2. **List Iteration**: `as record`
   - Iterates over this filtered list, outputting each record as a row in the table.


### Summary


- The first block of code filters records that have both `custcol_from_date` and `custcol_to_date` filled, sorts them by these dates, and displays them in the table.
- The second block of code filters records that are missing either `custcol_from_date` or `custcol_to_date`, and displays them at the end of the table without sorting.
- The use of `?filter` and `?sort_by` functions helps manage the display order and grouping of records based on the specified criteria.

Leave a comment

Your email address will not be published. Required fields are marked *