CONSOLIDATED LINE ITEMS IN THE GROUP INVOICE PDF

This is the sample Advanced PDF template where the items from the different invoices of the group are consolidated into a single line item and the VAT type tax item is excluded from the list.

<?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>
                                <@filecabinet nstype="image" 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">Invoice</span>
                            <span class="number">#${record.invoicegroupnumber}</span>
                        </td>
                    </tr>
                    <tr>
                        <td align="right">${record.trandate}</td>
                    </tr>
                </table>
            </macro>
        </macrolist>
        <style>
            * {
                <#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>
            }
        </style>
    </head>
    <body header="nlheader" header-height="10%" padding="0.5in 0.5in 0.5in 0.5in" size="Letter">
        &nbsp;
        <table style="width: 677px;">
            <tr>
                <td colspan="5" style="width: 196px;">
                    <table>
                        <tr>
                            <td style="font-size: 13pt; font-weight: bold;">${record.billaddress@label}</td>
                        </tr>
                        <tr>
                            <td>${record.billaddress}</td>
                        </tr>
                    </table>
                </td>
                <td align="right" colspan="7" style="width: 471px;">
                    <table style="break-inside: avoid; margin-top: 10px; width: 347px;">
                        <tr>
                            <td align="left" style="background-color: #d3d3d3; font-weight: bold;">${record.amountpaid@label}</td>
                            <td align="right">${record.amountpaid}</td>
                        </tr>
                        <tr>
                            <td align="left" style="background-color: #d3d3d3; font-weight: bold;">${record.amountdue@label}</td>
                            <td align="right">${record.amountdue}</td>
                        </tr>
                        <tr>
                            <td align="left" style="background-color: #d3d3d3; font-weight: bold;">${record.total@label}</td>
                            <td align="right">${record.total}</td>
                        </tr>
                    </table>
                </td>
            </tr>
        </table>


        <table style="width: 100%; margin-top: 10px;">
            <tr>
                <td align="left"><strong>${label.primaryinformation}</strong></td>
            </tr>
        </table>


        <table class="body" style="width: 100%; margin-top: 10px;">
            <tr style="background-color: #d3d3d3;">
                <!-- <th align="center" style="font-weight: bold; border: 1px solid black;" width="150pt">${record.customer@label}</th> -->
                <th align="center" style="font-weight: bold; border: 1px solid black;" width="150pt">Date</th>
                <th align="center" style="font-weight: bold; border: 1px solid black;" width="150pt">${record.terms@label}</th>
                <th align="center" style="font-weight: bold; border: 1px solid black;" width="150pt">${record.duedate@label}</th>
                <th align="center" style="font-weight: bold; border: 1px solid black;" width="200pt">${record.subsidiary@label}</th>
                <th align="center" style="font-weight: bold; border: 1px solid black;" width="150pt">${record.currency@label}</th>
            </tr>
            <tr>
                <!-- <td align="center" style="border: 1px solid black;">${record.customername}</td> -->
                <td align="center" style="border: 1px solid black;">${record.trandate}</td>
                <td align="center" style="border: 1px solid black;">${record.terms}</td>
                <td align="center" style="border: 1px solid black;">${record.duedate}</td>
                <td align="center" style="border: 1px solid black;">${record.subsidiary}</td>
                <td align="center" style="border: 1px solid black;">${record.currency}</td>
            </tr>
        </table>


        <!-- Grouped Invoices Detail - Consolidated by Item -->
        <#if groupedinvoices_detailed?has_content>
            <table style="break-inside: avoid; margin-top: 10px; width: 647px;">
                <tr>
                    <td align="left"><strong>Invoice Detail</strong></td>
                </tr>
            </table>


            <!-- Initialize a map to store consolidated totals -->
            <#assign itemTotals = {} />


            <!-- First loop: calculate totals for each unique item -->
            <#list groupedinvoices_detailed as invoice_details>
                <#assign itemName = invoice_details.item>
                <#assign fxRate = invoice_details.fxrate?trim!''>


                <!-- Skip items with a VAT rate as a percentage -->
                <#if fxRate?matches(".*%") == false>
                    <#if itemTotals?has_content && itemTotals[itemName]?exists>
                        <#assign currentItem = itemTotals[itemName] />
                        
                        <!-- Update only the quantity and gross, keep rate as is -->
                        <#assign currentItem = {
                            "rate": currentItem.rate,
                            "totalQuantity": currentItem.totalQuantity + invoice_details.quantity,
                            "totalGross": currentItem.totalGross + invoice_details.fxgrossamount
                        } />
                        
                        <!-- Update the map with the new totals -->
                        <#assign itemTotals = itemTotals + { (itemName): currentItem } />
                    <#else>
                        <!-- If the item doesn't exist, create a new entry, and use the current rate -->
                        <#assign itemTotals = itemTotals + {
                            (itemName): {
                                "rate": fxRate,
                                "totalQuantity": invoice_details.quantity,
                                "totalGross": invoice_details.fxgrossamount
                            }
                        } />
                    </#if>
                </#if>
            </#list>


            <!-- Display the unique items in a single line with the summed totals -->
            <table style="width: 100%; margin-top: 10px; border-collapse: collapse;">
                <thead>
                    <tr style="background-color: #d3d3d3;">
                        <th align="center" style="font-weight: bold; border: 1px solid black;" width="130pt;">Item Description</th>
                        <th align="center" style="font-weight: bold; border: 1px solid black;" width="100pt;">${label.rate}</th>
                        <th align="center" style="font-weight: bold; border: 1px solid black;" width="70pt;">${label.quantity}</th>
                        <th align="center" style="font-weight: bold; border: 1px solid black;" width="150pt;">${label.grossamount}</th>
                    </tr>
                </thead>
                <tbody>
                    <#list itemTotals?keys as uniqueItem>
                        <#assign itemData = itemTotals[uniqueItem] />
                        <!-- Check if quantity is greater than zero to prevent printing unnecessary rows -->
                        <#if itemData.totalQuantity != 0>
                            <tr style="background-color: #d3d3d3;">
                                <td align="left" style="border: 1px solid black;">${uniqueItem}</td>
                                <td align="right" style="border: 1px solid black;">${itemData.rate}</td>
                                <td align="center" style="border: 1px solid black;">${itemData.totalQuantity}</td>
                                <td align="right" style="border: 1px solid black;">${itemData.totalGross}</td>
                            </tr>
                        </#if>
                    </#list>
                </tbody>
            </table>
        </#if>


        <table style="width: 100%; margin-top: 10px; border: 1px solid black; border-collapse: collapse;">
            <tr>
                <td align="left" style="font-weight: bold; border: 1px solid black;">${record.taxtotal@label}</td>
                <td align="right" style="border: 1px solid black;">${record.taxtotal}</td>
            </tr>
            <#if record.shippingcost?has_content>
                <tr>
                    <td align="left" style="font-weight: bold; border: 1px solid black;">${record.shippingcost@label}</td>
                    <td align="right" style="border: 1px solid black;">${record.shippingcost}</td>
                </tr>
            </#if>
            <#if record.handlingcost?has_content>
                <tr>
                    <td align="left" style="font-weight: bold; border: 1px solid black;">${record.handlingcost@label}</td>
                    <td align="right" style="border: 1px solid black;">${record.handlingcost}</td>
                </tr>
            </#if>
            <tr>
                <td align="left" style="font-weight: bold; border: 1px solid black;">${record.total@label}</td>
                <td align="right" style="border: 1px solid black;">${record.total}</td>
            </tr>
        </table>
    </body>
</pdf>

 

Leave a comment

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