ecLearn - Learning Management System built on top of Microsoft Dataverse for Power Platform and Dynamics 365 users

ENGINEERED CODE BLOG

Power Apps Portals: Print Invoices

The topic of my first Portals Community Call back in January was the how to build a portal that allows a customer to view and print invoices. While solutions for this have been described by others (including Megan V. Walker’s excellent post), I also presented a different approach that I thought was worth covering in a blog post so that I could get a bit more into the technical details.

The Problem

The Portals Community Call all started with Megan V. Walker‘s MVP Advent Calendar. As a participant, I offered a couple hours of free Portals consulting services to the person who was randomly chosen from all of the people who had entered the contest. The winner was Edrei Mpanduki who, rather than keep the gift all to himself, decided to share his time with the entire community. I then decided to offer a one hour session every month where we cover a different topic about Portals for the Power Platform. The topic Edrei requested for the first month was about a portal that customers could use to view and print invoices.

The ability to view invoices can be done with out-of-the-box features, specifically Entity Lists, Entity Forms and Entity Permissions. Entity Lists can be used to show a list of invoices, Entity Forms can be used to display the details of the invoice, and Entity Permissions can be used to ensure that only invoices related to the contact are displayed on the portal. However, the requirement to print the invoices is a bit more challenging because by default, when you print a page that is displaying an Entity Form, it’s not in the nice invoice format a user might expect.

When people think “printable”, often their first reaction is to think PDFs. This is how Megan V. Walker approached it in her blog post. While this approach is great and probably what a lot of users are expecting, it is a bit complicated and, in some situations, it might be a bit overkill.

An Alternative Approach

Rather than generating a PDF document, you can instead rely on the browser’s built-in ability to print pages.

As mentioned above, if you print a page displaying an Entity Form, it’s probably not going to look great. So instead, in this approach we create a separate Page Template, which displays the invoice in a more print-friendly format using Liquid.

To implement this technique, you’ll need:

  • A new Web Template – let’s call it “Printable Invoice”. We’ll get into the details of what to put on this Web Template in a minute.
  • A new Page Template – let’s call it “Printable Invoice”. It should be a Web Template type Page Template referring to the Web Template above, and you should uncheck Use Website Header and Footer.
  • A new Web Page – let’s call it “Printable Invoice”. It uses the Page Template from above.

The Web Template Implementation

Once you’ve got those records mentioned above created, let’s look at what we will be including in our Printable Invoice Web Template. The idea is that we are going to use Liquid to display the invoice in a print-friendly way.

Here is a really basic implementation for the Web Template:

<html>
    <body>
        {% assign invoice = entities.invoice[request.params.id] -%}

        Name: {{invoice.name}}<br/>

        Products:

        <table>
            <tr>
                <th>Product</th>
                <th>Price</th>
            </tr>    
        {% for d in invoice.invoice_details -%}
            <tr>
                <td>{{d.productname}}</td>
                <td>${{d.extendedamount | round: 2}}</td>
            </tr>
        {% endfor %}
        </table>

        Total: ${{invoice.totalamount | round: 2}}
        <script>
            window.print();
        </script>
    </body>
</html>

Starting at the top, you’ll see that we’ve got <html> and <body> tags. Because we did not select Use Website Header and Footer on our Page Template, we are responsible for the entire markup of this page.

Next, we’ve got the Liquid code that gets a specific invoice based on a query string parameter (in this case, “id”). Following that, we are using Liquid to display the name, followed by the products using a for loop, and the invoice total. Keep in mind that if you want to show invoice line items then you need to enable Entity Permissions for both invoice and invoicedetail.

Finally, we’ve got a single line of JavaScript that will prompt the user to print the page as soon as it is opened.

Tying it Back to the Entity Form

With the Web Template now in place, we need to provide the user a way to get to the page, including passing the ID of invoice on the query string. I’m assuming you’ve got an Entity Form that displays the invoice, and we’ll be adding a button to the form that allows the user to print. We’ll do that with a bit of JavaScript in the Custom JavaScript field on our Entity Form:

$(document).ready(function() {
    $('#EntityFormControl').before($('<a href="/printable-invoice?id={{request.params.id}}" target="_blank" rel="noopener noreferrer">Print</a>'));
});

This code adds a link to the Entity Form that, when clicked, opens up a new tab with the printable invoice. It uses Liquid to grab the ID of the current invoice from the query string so that it can be included in the link. Be sure to put in the correct URL to your printable invoice page, if it isn’t /printable-invoice.

Now you’ve got a link on your Entity Form that pops open a new page with a print-friendly template for your invoice. Obviously there is more work to be done to make the invoice look more professional, but hopefully this at least gets you started!

5 responses to “Power Apps Portals: Print Invoices”

  1. […] post Power Apps Portals: Print Invoices appeared first on Engineered […]

  2. AndKan says:

    Construction is clear so far and genious simple.

    Whats about data for invoice from related tables like customer name, company name?

    Thanks.

  3. AndKan says:

    Inspired by your idea another way for simple printable view: Use CSS media.

    I added into my Web Template:

    Print

    @media print {
    .noprint, footer, div.navbar { display:none; }
    }

    Onclick it opens the browser print preview and all page elements, which should not be printed have display:none .
    In this way, there is no second web template needed and other design definitions like font-size, font-family keep alive.

    Ty,
    AndKan

  4. AndKan says:

    … seems my Code is parsed … 🙁
    <div class=”noprint”>
    <a href=”#” onclick=”self.print();”>Drucken</a>
    </div>

    <style type="text/css">
    @media print {
    .noprint, footer, div.navbar { display:none; }
    }
    </style>

Leave a Reply

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

Contact

Engineered Code is a web application development firm and Microsoft Partner specializing in web portals backed by Dynamics 365 & Power Platform. Led by a professional engineer, our team of technology experts are based in Regina, Saskatchewan, Canada.