Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Expand
titleTemplate details

You need to do three steps:

  1. Upload static resource

  2. Create Apex Class

  3. Create Visualforce page

Upload the following static resource with the name ‘invoice’

View file
nameinvoice.zip

class:

Code Block
public with sharing class Ctrl_InvoiceLayout {

    private Subscription25__Invoice__c invoice;
    public InvoiceItem[] items {get; private set;}

    public Id companyLogoId {get; private set;}

    public Decimal sum {get; private set;}
    public Decimal total {get; private set;}
    public Decimal taxAmount {get; private set;}

    public Boolean hasICP {get; private set;}

    public Ctrl_InvoiceLayout(ApexPages.StandardController stdController) {
        this.invoice = (Subscription25__Invoice__c)stdController.getRecord();

        List<Order> orders = this.getOrders();
        this.items = new InvoiceItem[]{};
        this.hasICP = false;
        for (Order order : orders) {
            for (OrderItem item : order.OrderItems) {
                this.items.add(new InvoiceItem(item));
                this.hasICP = this.hasICP || item.Subscription25__Use_ICP__c;
            }
        }

        this.taxAmount = 0;
        this.sum = 0;
        for (InvoiceItem item : this.items) {
            this.sum += item.price * item.quantity;
            this.taxAmount += item.price * item.quantity * item.tax / 100;
        }
        this.sum = Ctrl_InvoiceLayout.format(this.sum);
        this.taxAmount = Ctrl_InvoiceLayout.format(this.taxAmount);
        this.total = Ctrl_InvoiceLayout.format(this.sum + this.taxAmount);

        //try to load an attachment of the administration that starts with logo, if present, use that as a logo, otherwise, fall back
        //to the company logo as defined in the custom setting
        List<Attachment> atts = this.getAttachments();
        this.companyLogoId = atts.size() > 0 ? atts.get(0).Id : Ctrl_InvoiceLayout.getSubscription25LogoIdgetLogoId();
    }

    private List<Attachment> getAttachments() {
        Id adminId = this.invoice.Subscription25__Administration__c;
        String query = 'SELECT Name FROM Attachment WHERE ParentId = :adminId AND Name LIKE \'Logo%\'';
        return Database.query(query);
    }

    private List<Order> getOrders() {
        Id invoiceId = this.invoice.Id;
        return [
            SELECT Name, AccountId, Account.Name, 
                Subscription25__Reseller_Customer__c, Subscription25__Reseller_Customer__r.Name, 
                Subscription25__Invoice__r.Subscription25__Account__r.Name,
                (
                    SELECT Id, Subscription25__VAT_Percentage__c, Quantity,
                        UnitPrice, Description, Subscription25__Use_ICP__c,
                        Subscription25__Hide_VAT_On_Invoice__c, Subscription25__Product__c, Subscription25__Product__r.Name,
                        OrderId, Order.Name, Order.Id, Order.AccountId, Order.Account.Name,
                        Order.Subscription25__Reseller_Customer__c, Order.Subscription25__Reseller_Customer__r.Name,
                        Order.Subscription25__Invoice__c, Order.Subscription25__Invoice__r.Subscription25__Account__c, Order.Subscription25__Invoice__r.Subscription25__Account__r.Name
                    FROM OrderItemOrderItems
                )
                FROM Order
                WHERE Subscription25__Invoice__c = :invoiceId
        ];
    }

    private static Decimal format(Decimal amount) {
        return amount.setScale(2, RoundingMode.HALF_UP);
    }

    private static Id getLogoId(){
        String query = 'SELECT Id FROM Document WHERE DeveloperName LIKE \'%Subscription25_Logo\' LIMIT 1';
        List<Document> docs = Database.query(query);
        return docs.size() > 0 ? docs[0].Id : null;
    }


    private class InvoiceItem {
        public Decimal quantity {get; private set;}
        public String accountLabel {get; private set;} //used for resellers and bill to parent
        public String label {get; private set;}
        public Decimal price {get; private set;}
        public Decimal tax {get; private set;}
        public String description {get; private set;}

        public InvoiceItem(OrderItem oi) {
            this.quantity = oi.Quantity;
            this.label = oi.Subscription25__Product__r.Name;
            this.price = oi.UnitPrice;
            this.tax = oi.Subscription25__VAT_Percentage__c;
            this.description = oi.Description;

            if(oi.Order.Subscription25__Reseller_Customer__c != null){
                this.accountLabel = oi.Order.Subscription25__Reseller_Customer__r.Name;
            }
            if(oi.Order.AccountId != oi.Order.Subscription25__Invoice__r.Subscription25__Account__c){
                this.accountLabel = oi.Order.Account.Name;
            }
        }

        public Decimal getTotal() {
            Decimal total = this.price * this.quantity;
            return Ctrl_InvoiceLayout.format(total);
        }
    }
}

Visualforce:

Code Block
<apex:page standardController="Subscription25__Invoice__c" extensions="Ctrl_InvoiceLayout" renderAs="pdf" sidebar="false" showHeader="false" applyBodyTag="false">
    <head>
    <link media="print" rel="stylesheet" type="text/css" href="{!URLFOR($Resource.invoice, 'css/invoice.css')}" />
    </head>
    <body>
        <div class="header">
            <apex:image value="/servlet/servlet.FileDownload?file={!companyLogoId}" styleClass="logo"/>
        </div>
        <div class="header">
            <div class="logoContainer">
                <apex:image value="/servlet/servlet.FileDownload?file={!companyLogoId}" styleClass="logo" />
            </div>
            <table class="invoiceRulesHeader">
                <thead>
                    <tr>
                        <th class="number">Quantity</th>
                        <th class="description">Description</th>
                        <th class="price right">Price</th>
                        <th class="total right">Total</th>
                        <th class="vat right">VAT</th>
                    </tr>
                </thead>
            </table>
        </div>
        <div class="footer">
            <div class="container">
                <ul>
                    <li>
                        <apex:outputField value="{!Subscription25__Invoice__c.Subscription25__Administration__r.Subscription25__Billing_Name__c}" />
                    </li>
                    <li>
                        <apex:outputText value="{!Subscription25__Invoice__c.Subscription25__Administration__r.Subscription25__Billing_Street__c}" />
                    </li>
                    <li>
                        <apex:outputText value="{!Subscription25__Invoice__c.Subscription25__Administration__r.Subscription25__Billing_Postal_Code__c} {!Subscription25__Invoice__c.Subscription25__Administration__r.Subscription25__Billing_City__c}" />
                    </li>
                    <li class="last">
                        <apex:outputText value="{!Subscription25__Invoice__c.Subscription25__Administration__r.Subscription25__Billing_Country__c}" />
                    </li>
                </ul>
                <ul>
                    <li>
                        <apex:outputText value="VAT {!Subscription25__Invoice__c.Subscription25__Administration__r.Subscription25__VAT_Number__c}" />
                    </li>
                    <li>
                        <apex:outputText value="Bank {!Subscription25__Invoice__c.Subscription25__Administration__r.Subscription25__Bank__c}" />
                    </li>
                    <li>
                        <apex:outputText value="IBAN {!Subscription25__Invoice__c.Subscription25__Administration__r.Subscription25__IBAN__c}" />
                    </li>
                    <li class="last">
                        <apex:outputText value="BIC_Swift {!Subscription25__Invoice__c.Subscription25__Administration__r.Subscription25__BIC__c}" />
                    </li>
                </ul>
            </div>
            <div class="pageNumbers">Page <span class="pagenumber"/> Of <span class="pagecount"/></div>
        </div>
        <div class="container">
            <div class="invoicevat">
                <apex:outputText value="INVOICE" />
            </div>
            <table class="contactDetails">
                <tr>
                    <td class="contactName"><apex:outputText value="{!Subscription25__Invoice__c.Subscription25__Account__r.Name}" /></td>
                </tr>
                <apex:outputPanel layout="none" rendered="true">
                    <tr>
                        <td>
                            <apex:outputText value="Attn {!Subscription25__Invoice__c.Subscription25__Contact_Person__r.Name}" rendered="{!Subscription25__Invoice__c.Subscription25__Contact_Person__c != null}"/>
                        </td>
                    </tr>
                </apex:outputPanel>
                <tr>
                    <td><apex:outputText value="{!Subscription25__Invoice__c.Subscription25__Billing_Street__c}" /></td>
                </tr>
                <tr>
                    <td><apex:outputText value="{!Subscription25__Invoice__c.Subscription25__Billing_Postal_Code__c} {!Subscription25__Invoice__c.Subscription25__Billing_City__c}" /></td>
                </tr>
                <tr>
                    <td><apex:outputText value="{!Subscription25__Invoice__c.Subscription25__Billing_Country__c}" /></td>
                </tr>
                <tr>
                    <td><apex:outputText value="{!Subscription25__Invoice__c.Subscription25__VAT_Number__c}" /></td>
                </tr>
            </table>

            <table class="invoiceDetails">
                <tr>
                    <td class="leftColumn">InvoiceDate:</td>
                    <td><apex:outputField value="{!Subscription25__Invoice__c.Subscription25__Invoice_Date__c}" /></td>
                </tr>
                <tr>
                    <td>DueDate:</td>
                    <td><apex:outputField value="{!Subscription25__Invoice__c.Subscription25__Due_Date__c}" /></td>
                </tr>
                <tr>
                    <td>InvoiceNumber:</td>
                    <td><apex:outputField value="{!Subscription25__Invoice__c.Subscription25__Invoice_Number__c}" /></td>
                </tr>
            </table>
            <apex:outputPanel rendered="{!NOT(ISBLANK(Subscription25__Invoice__c.Subscription25__Description__c))}" layout="none">
                <div class="subject">
                    <apex:outputText value="Regarding: {!Subscription25__Invoice__c.Subscription25__Description__c}" />
                </div>
            </apex:outputPanel>
            <table class="invoiceRules">
                <thead>
                    <tr>
                        <th class="number">Quantity</th>
                        <th class="description">Description</th>
                        <th class="price right">Price</th>
                        <th class="total right">Total</th>
                        <th class="vat right">VAT</th>
                    </tr>
                </thead>
                <tbody>
                    <apex:repeat var="item" value="{!items}">
                        <tr>
                            <td class="number right">
                                <apex:outputText value="{0, number,###,###,##0.00}">
                                    <apex:param value="{!item.quantity}" />
                                </apex:outputText>
                            </td>
                            <td class="description">
                                <div><apex:outputText value="{!item.accountLabel}" /></div>
                                <apex:outputText value="{!item.label}" />
                                <div class="subText"><apex:outputText value="{!item.description}" /></div>
                            </td>
                            <td class="price right">
                                <apex:outputText value="€{0, number,###,###,##0.00}">
                                    <apex:param value="{!item.price}" />
                                </apex:outputText>
                            </td>
                            <td class="total right">
                                <apex:outputText value="€{0, number,###,###,##0.00}">
                                    <apex:param value="{!item.total}" />
                                </apex:outputText>
                            </td>
                            <td class="vat right">
                                <apex:outputText value="{0, number,###,###,##0.00}%">
                                    <apex:param value="{!item.tax}" />
                                </apex:outputText>
                            </td>
                        </tr>
                    </apex:repeat>
                </tbody>
            </table>
            <div class="paymentDetails">
                <table class="invoiceRulesFooter">
                    <tbody>
                        <tr>
                            <td class="number"></td>
                            <td colspan="2" class="totalText">Subtotal (ExclTax)</td>
                            <td class="total right">
                                <apex:outputText value="€{0, number,###,###,##0.00}">
                                    <apex:param value="{!sum}" />
                                </apex:outputText>
                            </td>
                            <td class="vat"></td>
                        </tr>
                        <tr>
                            <td class="number"></td>
                            <td colspan="2" class="totalText">Tax</td>
                            <td class="total right">
                                <apex:outputText value="€{0, number,###,###,##0.00}">
                                    <apex:param value="{!taxAmount}" />
                                </apex:outputText>
                            </td>
                            <td class="vat"></td>
                        </tr>
                    </tbody>
                    <tfoot>
                        <tr>
                            <td class="number"></td>
                            <td colspan="2" class="totalText">Total (InclTax)</td>
                            <td class="total right">
                                <apex:outputText value="€{0, number,###,###,##0.00}">
                                    <apex:param value="{!total}" />
                                </apex:outputText>
                            </td>
                            <td class="vat"></td>
                        </tr>
                    </tfoot>
                </table>
                <apex:outputPanel styleClass="timeleyPayment" rendered="{!hasICP}">
                    ICPLawMessage
                </apex:outputPanel>
                <div class="timeleyPayment">
                    Please reference invoice number <strong>{!Subscription25__Invoice__c.Subscription25__Invoice_Number__c}</strong> with your payment. We appreciate your timely payment.
                </div>
                <table class="paymentInfo">
                    <tr>
                        <td class="first">Wire transfer to:</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td>Bank Name:</td>
                        <td><apex:outputField value="{!Subscription25__Invoice__c.Subscription25__Administration__r.Subscription25__Bank__c}" /></td>
                    </tr>
                    <tr>
                        <td>Bank Account Name:</td>
                        <td><apex:outputField value="{!Subscription25__Invoice__c.Subscription25__Administration__r.Subscription25__Billing_Name__c}" /></td>
                    </tr>
                    <tr>
                        <td>BIC Swift:</td>
                        <td><apex:outputField value="{!Subscription25__Invoice__c.Subscription25__Administration__r.Subscription25__BIC__c}" /></td>
                    </tr>
                    <tr>
                        <td>IBAN:</td>
                        <td><apex:outputField value="{!Subscription25__Invoice__c.Subscription25__Administration__r.Subscription25__IBAN__c}" /></td>
                    </tr>
                </table>
                <apex:outputPanel rendered="{!NOT(ISBLANK(Subscription25__Invoice__c.Subscription25__Foot_Note__c))}" layout="none">
                    <div class="via-email">
                        <apex:outputField value="{!Subscription25__Invoice__c.Subscription25__Foot_Note__c}" />
                    </div>
                </apex:outputPanel>
            </div>
        </div>
    </body>
    <apex:outputText rendered="none" value="Subscription25__Invoice__c.Subscription25__Administration__c}" />
</apex:page>

...