Skip to content

Instantly share code, notes, and snippets.

@michoelchaikin
Created February 9, 2020 09:44
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save michoelchaikin/0cbe70c350e6078a356b516bc4f8ab38 to your computer and use it in GitHub Desktop.
Save michoelchaikin/0cbe70c350e6078a356b516bc4f8ab38 to your computer and use it in GitHub Desktop.
NetSuite Advanced PDF/HTML Invoice Template with the products grouped by class
<?xml version="1.0"?><!DOCTYPE pdf PUBLIC "-//big.faceless.org//report" "report-1.1.dtd">
<pdf>
<head>
<link name="NotoSans" type="font" subtype="truetype" src="${nsfont.NotoSans_Regular}" src-bold="${nsfont.NotoSans_Bold}" src-italic="${nsfont.NotoSans_Italic}" src-bolditalic="${nsfont.NotoSans_BoldItalic}" bytes="2" />
<#if .locale == "zh_CN">
<link name="NotoSansCJKsc" type="font" subtype="opentype" src="${nsfont.NotoSansCJKsc_Regular}" src-bold="${nsfont.NotoSansCJKsc_Bold}" bytes="2" />
<#elseif .locale == "zh_TW">
<link name="NotoSansCJKtc" type="font" subtype="opentype" src="${nsfont.NotoSansCJKtc_Regular}" src-bold="${nsfont.NotoSansCJKtc_Bold}" bytes="2" />
<#elseif .locale == "ja_JP">
<link name="NotoSansCJKjp" type="font" subtype="opentype" src="${nsfont.NotoSansCJKjp_Regular}" src-bold="${nsfont.NotoSansCJKjp_Bold}" bytes="2" />
<#elseif .locale == "ko_KR">
<link name="NotoSansCJKkr" type="font" subtype="opentype" src="${nsfont.NotoSansCJKkr_Regular}" src-bold="${nsfont.NotoSansCJKkr_Bold}" bytes="2" />
<#elseif .locale == "th_TH">
<link name="NotoSansThai" type="font" subtype="opentype" src="${nsfont.NotoSansThai_Regular}" src-bold="${nsfont.NotoSansThai_Bold}" bytes="2" />
</#if>
<macrolist>
<macro id="nlheader">
<table class="header" style="width: 100%;"><tr>
<td rowspan="3"><#if companyInformation.logoUrl?length != 0><img src="${companyInformation.logoUrl}" style="float: left; margin: 7px" /> </#if> <span class="nameandaddress">${companyInformation.companyName}</span><br /><span class="nameandaddress">${companyInformation.addressText}</span></td>
<td align="right"><span class="title">${record@title}</span></td>
</tr>
<tr>
<td align="right"><span class="number">#${record.tranid}</span></td>
</tr>
<tr>
<td align="right">${record.trandate}</td>
</tr></table>
</macro>
<macro id="nlfooter">
<table class="footer" style="width: 100%;"><tr>
<td><barcode codetype="code128" showtext="true" value="${record.tranid}"/></td>
<td align="right"><pagenumber/> of <totalpages/></td>
</tr></table>
</macro>
</macrolist>
<style type="text/css">* {
<#if .locale == "zh_CN">
font-family: NotoSans, NotoSansCJKsc, sans-serif;
<#elseif .locale == "zh_TW">
font-family: NotoSans, NotoSansCJKtc, sans-serif;
<#elseif .locale == "ja_JP">
font-family: NotoSans, NotoSansCJKjp, sans-serif;
<#elseif .locale == "ko_KR">
font-family: NotoSans, NotoSansCJKkr, sans-serif;
<#elseif .locale == "th_TH">
font-family: NotoSans, NotoSansThai, sans-serif;
<#else>
font-family: NotoSans, sans-serif;
</#if>
}
table {
font-size: 9pt;
table-layout: fixed;
}
th {
font-weight: bold;
font-size: 8pt;
vertical-align: middle;
padding: 5px 6px 3px;
background-color: #e3e3e3;
color: #333333;
}
td {
padding: 4px 6px;
}
td p { align:left }
b {
font-weight: bold;
color: #333333;
}
table.header td {
padding: 0px;
font-size: 10pt;
}
table.footer td {
padding: 0px;
font-size: 8pt;
}
table.itemtable th {
padding-bottom: 10px;
padding-top: 10px;
}
table.body td {
padding-top: 2px;
}
table.total {
page-break-inside: avoid;
}
tr.totalrow {
background-color: #e3e3e3;
line-height: 200%;
}
td.totalboxtop {
font-size: 12pt;
background-color: #e3e3e3;
}
td.addressheader {
font-size: 8pt;
padding-top: 6px;
padding-bottom: 2px;
}
td.address {
padding-top: 0px;
}
td.totalboxmid {
font-size: 28pt;
padding-top: 20px;
background-color: #e3e3e3;
}
td.totalboxbot {
background-color: #e3e3e3;
font-weight: bold;
}
span.title {
font-size: 28pt;
}
span.number {
font-size: 16pt;
}
span.itemname {
font-weight: bold;
line-height: 150%;
}
hr {
width: 100%;
color: #d3d3d3;
background-color: #d3d3d3;
height: 1px;
}
</style>
</head>
<body header="nlheader" header-height="10%" footer="nlfooter" footer-height="20pt" padding="0.5in 0.5in 0.5in 0.5in" size="Letter">
<table style="width: 100%; margin-top: 10px;"><tr>
<td class="addressheader" colspan="3"><b>${record.billaddress@label}</b></td>
<td class="addressheader" colspan="3"><b>${record.shipaddress@label}</b></td>
<td class="totalboxtop" colspan="5"><b>${record.total@label?upper_case}</b></td>
</tr>
<tr>
<td class="address" colspan="3" rowspan="2">${record.billaddress}</td>
<td class="address" colspan="3" rowspan="2">${record.shipaddress}</td>
<td align="right" class="totalboxmid" colspan="5">${record.total}</td>
</tr>
<tr>
<td align="right" class="totalboxbot" colspan="5"><b>${record.duedate@label}:</b> ${record.duedate}</td>
</tr></table>
<table class="body" style="width: 100%; margin-top: 10px;"><tr>
<th>${record.terms@label}</th>
<th>${record.duedate@label}</th>
<th>${record.otherrefnum@label}</th>
<th>${record.salesrep@label}</th>
<th>${record.shipmethod@label}</th>
<th>${record.partner@label}</th>
</tr>
<tr>
<td>${record.terms}</td>
<td>${record.duedate}</td>
<td>${record.otherrefnum}</td>
<td>${record.salesrep}</td>
<td>${record.shipmethod}</td>
<td>${record.partner}</td>
</tr></table>
<#if record.item?has_content>
<#assign previousClass = "">
<#list record.item?sort_by('class') as item>
<#if item.class != previousClass>
<#assign currentClass = item.class>
<#assign subtotal = 0>
<h4>${currentClass}</h4>
<table class="itemtable" style="width: 100%; margin-top: 10px;">
<thead>
<tr>
<th align="center" colspan="3">${item.quantity@label}</th>
<th colspan="12">${item.item@label}</th>
<th colspan="3">${item.options@label}</th>
<th align="right" colspan="4">${item.rate@label}</th>
<th align="right" colspan="4">${item.amount@label}</th>
</tr>
</thead>
<#-- A cleaner way of doing this would be using ?filter builtin, or even <#continue>. However
this is not supported by the version of Freemarker currently used by NetSuite -->
<#list record.item?sort_by('class') as item>
<#if item.class == currentClass>
<tr>
<td align="center" colspan="3" line-height="150%">${item.quantity}</td>
<td colspan="12"><span class="itemname">${item.item}</span><br />${item.description}</td>
<td colspan="3">${item.options}</td>
<td align="right" colspan="4">${item.rate}</td>
<td align="right" colspan="4">${item.amount}</td>
</tr>
<#assign subtotal = subtotal + item.amount>
</#if>
</#list>
<tr>
<td align="right" colspan="22"><b>${currentClass} ${record.subtotal@label}</b></td>
<td align="right" colspan="4">${nsformat_currency(subtotal)}</td>
</tr>
</table>
</#if>
<#assign previousClass = item.class>
</#list>
<hr />
</#if>
<table class="total" style="width: 100%; margin-top: 10px;"><tr>
<td colspan="4">&nbsp;</td>
<td align="right"><b>${record.subtotal@label}</b></td>
<td align="right">${record.subtotal}</td>
</tr>
<tr>
<td colspan="4">&nbsp;</td>
<td align="right"><b>${record.taxtotal@label} (${record.taxrate}%)</b></td>
<td align="right">${record.taxtotal}</td>
</tr>
<tr class="totalrow">
<td background-color="#ffffff" colspan="4">&nbsp;</td>
<td align="right"><b>${record.total@label}</b></td>
<td align="right">${record.total}</td>
</tr></table>
</body>
</pdf>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment