# Account PDF Viewer

{% @arcade/embed flowId="k4LHu3RnMrTqO8kpG1c2" url="<https://app.arcade.software/share/k4LHu3RnMrTqO8kpG1c2>" %}

{% hint style="danger" %}
This use case has some configuration prerequisites. Make sure you review the [**Set up**](#f1104ea9-b30d-4396-b858-55c41b4cffd1) section of this page before building!
{% endhint %}

{% hint style="success" %}

#### **Learning focus points**

* Go in-depth with the **PDF viewer** dynamic component
* Combining Dynamic components and flows to pass data
* Working with **variables** in Dynamic components
* Using component **visibility rules**
  {% endhint %}

***

## Objective <a href="#id-5f56e1d2-78d8-4f63-af33-0db54f71471a" id="id-5f56e1d2-78d8-4f63-af33-0db54f71471a"></a>

Allow users to quickly and seamlessly **display an Invoice PDF** from an account, without app navigation and with no-code.

***

## Solution <a href="#a25298b6-ce1d-426e-8db8-aa41f1cf4fca" id="a25298b6-ce1d-426e-8db8-aa41f1cf4fca"></a>

This solution uses **Avonni Dynamic Components** combined with **Salesforce automation**, all built with **no code**.

User get a clear view of related Invoices where they can view PDF documents in one click.

### How It Works (User Perspective) <a href="#c75990c5-3e25-41fc-89d6-31e1dcfed9ca" id="c75990c5-3e25-41fc-89d6-31e1dcfed9ca"></a>

* A user opens an account record and navigates to the Invoice list
* They click on an Open PDF button next to the Invoice
* The related PDF is automatically displayed
* If there are multiple PDFs, a picklist offers them to choose from before the selected document is displayed

### What we'll create <a href="#id-228f54ff-be7f-4ab7-a30a-3582c52d5dfa" id="id-228f54ff-be7f-4ab7-a30a-3582c52d5dfa"></a>

* 1 **Avonni Dynamic Component** to allow users to view records and take action
* 1 **screen Flow** to handle automation
* 1 **custom Bill object** representing our invoices that will hold the ContentDocuments

***

## Set up <a href="#f1104ea9-b30d-4396-b858-55c41b4cffd1" id="f1104ea9-b30d-4396-b858-55c41b4cffd1"></a>

### Prerequisite: Create the Bill Custom Object

* Create a Bill\_\_c custom object to represent your Invoices, with a lookup to Account.
* Use all other configurations you'd like

### Configure the Screen Flow

{% @arcade/embed flowId="8qy2rEmbqSToWWaKvRV3" url="<https://app.arcade.software/share/8qy2rEmbqSToWWaKvRV3>" %}

{% stepper %}
{% step %}

#### **In Flow Builder, create a Screen Flow**

* Although it won't have screens, this needs to be a screen flow in order to be launched from a row-level action within the Dynamic component
* For this example, tour flow will be named `AV_Get_ContendDocument_for_Bills`. This will be referenced further in the Dynamic Component.
  {% endstep %}

{% step %}

#### **Create variables**

* Create a text input variable : `recordId`
  * This will store the Bill Id
* Create a text collection output variable : `vContentDocumentIds`
* Create a text single output variable : `vContentDocId`
* Create a number variable : `vDocCount`&#x20;
  {% endstep %}

{% step %}

#### Retrieve related ContentDocumentLinks

* Use a Get record element to retrieve all the ContentDocumentLinks related to the `recordId`
  {% endstep %}

{% step %}

#### Count Documents

* Count the retrieved records to allow for specific handling when one or many records are found
* Use an assignment element to count the retrieved records and populate the `vDocCount` variable with the value
  {% endstep %}

{% step %}

#### Transform the Document collection

* Use a Transform element to map the ContentDocumentLinks into a text collection of Ids
  {% endstep %}

{% step %}

#### Evaluate your number of documents

* Use a decision element to evaluate how many documents your bill has (use the `vDocCount` variable)
  {% endstep %}

{% step %}

#### If multiple ContentDocumentLinks where found

* Assign all ContentDocumentIds to an output text collection variable `vContentDocumentIds`
  {% endstep %}

{% step %}

#### If only one ContentDocumentLink was found

* Use a loop to pass the ContentDocumentId into a text `vContentDocId` output variable
  {% endstep %}

{% step %}

#### Review

{% endstep %}
{% endstepper %}

***

## **Create the Dynamic Component**

{% @arcade/embed flowId="8UtV9OARFaWhHkP4zz8y" url="<https://app.arcade.software/share/8UtV9OARFaWhHkP4zz8y>" %}

{% stepper %}
{% step %}

#### Create the Dynamic component

* Create the Dynamic component in the Avonni Experience App, make sure it's **Target Page Object is Account** to allow for record context
  {% endstep %}

{% step %}

#### Create Variables

* Create 2 text variables matching the flow output variables
  * `vContentDocumentIds` : collection variable&#x20;
  * `vContentDocumentTxt` : single variable
    {% endstep %}

{% step %}

#### Configure the Data Table

* Use a **Data Table** to display all `Bill__c` record related to the current account
  * Create a Query on the `Bill__c` object&#x20;
  * Create the `Open PDF` **row level action button as a Data Table column**
    {% endstep %}

{% step %}

#### Create an interaction to assign variables

* Create an Assignment interaction from the Open PDF row-level button
* Assign the constant null value both `vContentDocumentTxt` and `vContentDocumentIds` .

{% hint style="warning" %}

#### **Why this matters**&#x20;

This will ensure all variables are cleared and the displayed data is always up to date.
{% endhint %}
{% endstep %}

{% step %}

#### Launch the Flow from an interaction

Create a **Flow Dialog Interaction** to launch the flow from the row-level button

* **Important** : Make sure to pass the row record id into the flow `recordId` input variable
* **Important** :&#x20;
  * Make sure to retrieve the flow `vContentDocId` output variable into a text `vContentDocumentTxt` variable
  * Make sure you retrieve the flow `vContentDocumentIds` into a text collection variable `vContentDocumentIds`
    {% endstep %}

{% step %}

#### Set up an Alert component

Add an **Alert** to let users know if multiple PDFs were found

* Display the component only if `vContentDocumentIds` is not empty
* Set up conditional visibility. The component should only display if multiple documents were retrieved by the flow :  if `vContentDocumentIds` is not empty
  {% endstep %}

{% step %}

#### Build a Combobox component

Add a **Combobox** component to let users choose from a document list if multiple PDFs were found

* Set the Data source to a query
  * Get Content Documents where their Id is IN the `vContentDocumentIds` collection
* Set up an interaction to assign the selected record Id to the variable `vContentDocumentTxt`
* Set up conditional visibility. The component should only display if multiple documents were retrieved by the flow :  if `vContentDocumentIds` is not empty
  {% endstep %}

{% step %}

#### **Add the PDF viewer component**

Add a **PDF viewer** component

* Set the source to the `vContentDocumentTxt` variable
* In the Style tab, set the Height to `1200` to enhance PDF readability&#x20;
  {% endstep %}

{% step %}

#### Save and review

{% endstep %}
{% endstepper %}

***

## Going further

**Dynamic components used in this use case**

{% content-ref url="/spaces/ODPvvv7Cx9Z9RECLn3oV/pages/r9ngSWRD3zShebRW8shA" %}
[Alert](/dynamic-components/components/alert.md)
{% endcontent-ref %}

{% content-ref url="/spaces/ODPvvv7Cx9Z9RECLn3oV/pages/u1Ca9FusJlXueSEMtf8v" %}
[Combobox](/dynamic-components/components/combobox.md)
{% endcontent-ref %}

{% content-ref url="/spaces/ODPvvv7Cx9Z9RECLn3oV/pages/By0CvRSNEZiVKHeDjgLv" %}
[Data Table](/dynamic-components/components/data-table.md)
{% endcontent-ref %}

{% content-ref url="/spaces/ODPvvv7Cx9Z9RECLn3oV/pages/aL3Wdy4lBlX4QOEXvDzX" %}
[PDF Viewer](/dynamic-components/components/pdf-viewer.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.avonnicomponents.com/projects/use-cases/account-pdf-viewer.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
