# Flows: Best Practices

A good quality Flow, adhering to these recommended practices will:

* Satisfy the end user's business logic seamlessly
* Produce accurate and precise Flows
* Reduce the risk of errors

## GENERAL

### 1. If, Else handlers after an API call

**Purpose:** To verify the status of the API response.

The response of every API Call returns a dictionary or JSON with keys: `status`, `status_code`, and `response`. A good and recommended practice is to ensure that the `status`and `status_code` values from this response are processed after the API call is made.

Sample Response: `{‘status’: true, ‘status_code’: 200, ‘data’:[]}`

The `status` (true or false) depends on the `status_code` variable. If `status_code`returned is `200`, then the `status`is true, otherwise it is false for all other status codes.

Usually, the If condition is used to verify the `status`, as 'true' or 'false'.

* If `status` = true, it is logged as Success and/or you can proceed with your own logic inside the If condition.
* If `status` = false, it is marked as a Failure and also a static/dynamic message may be logged.

The If condition can also verify the response, based on the 'status code' as: `response[‘status_code’] == 300.`

```python
Create Orders API call to Epicor P21 Custom Server
If specified condition matched
    Increment variable records_passed by value 1
    Log Success message Synchronized
Else
    Log Failure message Invalid Response
```

In this example, in the If condition, the response `status` is evaluated for true or false.

If it is true, it is logged as Success and also the variable, `records_passed` is incremented by 1, to keep track of passing entities. For other status codes, a Failure message is logged.

###

### 2. Try catch inside the Loop Handler

**Purpose:** To catch errors on an item level (inside the loop).

When an error occurs while processing one item in the list, the Try block ensures that the Flow proceeds to execute the synchronization of other items in the list, instead of terminating the entire synchronization.

```python
Loop till specified condition matched
    Try block
    Create Customer API call to Epicor P21 Custom Server
    ....
    Catch Exception
    Log Failure message Some Error Occurred
```

This block of code is written to create customers one by one from a list, from another system. If an error occurs while creating one particular customer (say customer\_X), it will be logged as a Failure;

And since the try-catch handler is used inside the loop, the execution continues to move on to the next item and process it. Eventually, all the customers' information will be synchronized except customer\_X.

{% hint style="danger" %}
&#x20;The Try Catch Handler should be used only inside the loop.
{% endhint %}

### 3. Dashboard Customers and Orders

**Purpose**: To display the total number of customers and total number of orders in the Dashboard screen.

`dashboard_customers` and `dashboard_orders` are two built-in variables which need to incremented within the Flow, in order to display these numbers in the dashboard screen.

```python
Create Orders API call to Epicor P21 Custom Server
If specified condition matched
    Increment variable records_passed by value 1
    Increment variable dashboard_orders by value 1
    Log Success message Synchronized
Else
    Log Failure message Invalid Response
```

These built in variables should be used only to increment new customers and new orders.

In this example, every time the incrementer is executed, the built-in variable, `dashboard_orders`is incremented by 1, thereby increasing the order count and the respective number in the dashboard screen. This incrementer is usually used after an API call in the Flow.

In the same way, the built-in variable `dashboard_customers`is used to keep count of new customers.

Note: These built-in variables are used only to increment new customers and new orders. It should not be used while updating existing customer details or updating inventory.

###

### 4. Return the data if it is a dynamic call

**Purpose:** To return the value of a variable in real-time for a dynamic pipe.

```python
Return value formatted_data
```

A Dynamic pipe, containing a Flow with the above Handler, implies that the variable formatted\_data, which is mapped and prepared by DCKAP Integrator, is returned to the caller when the dynamic call is made.

```python
P21 Get Back Order Detail API call to Epicor P21 Custom Server
If specified condition matched
    Increment variable records_passed by value 1
    Log Success message Customer Fetched
    Return value P21_Res['data']
Else
    Log Failure message Failed
```

&#x20;In this example, a dynamic API call is made to the Epicor P21 Server. And when the specified condition is True, the If block is executed and the data in the variable `P21_Res['data']`is returned in the API response to the caller.

###

### 5. Reasonable variable names

**Purpose**: To easily comprehend the meaning of the Handler and the Flow.

Following are some recommended rules to establish a good variable name:

* Lowercase alphabets separated by an underscore
  * Example: `customer_data`, `order_data`
* It can be alphanumeric, but cannot start with a number
  * Example: `customer_id1`
* Meaningful names over random names are preferred
  * Example: `customer_data`not cust\_dat
* Avoid lengthy names
  * Example: `mailing_address`not address\_to\_ship\_item

## LOGS

### 6. Maintain total records, records processed and records passed count

**Purpose**: To keep track of processed records and also to view the result in the progress bar during the sync process.

Three built-in variables, `total_records`, `records_processed`and `records_passed`are incremented within the Flow and are used in the Step Progress handler to denote the progress of data processed inside a loop.

```python
Increment variable total_records by value 1

Increment variable records_processed by value 1

Increment variable records_passed by value 1
```

Every time these built-in variables are incremented, the progress bar in the Integrations page is updated and the number (`records_processed`out of `total_records`) is displayed as a percentage value, during the sync process.

These variables are used in the Step Progress handler, as follows.

<div align="center"><img src="https://2655769465-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2Fpaper-cup%2F-Lxepv4O__EDxStr48ER%2F-LxeqcQxrfshmbdBWn0-%2F0.png?generation=1578045705172711&#x26;alt=media" alt=""></div>

###

### 7. Using step level logger inside the Loop handler

**Purpose**: To log item-level errors inside a loop.

The Step Logger handler is used to display short and detailed messages of every processed entity inside the loop. It is usually used in combination with the If and Else handlers in order to log Success and Failure messages.

```python
Loop till specified condition matched
    ....
    If specified condition matched
          Log Success message Synchronized
    Else
          Log Failure message Invalid Response
```

Here, the Loop processes every entity in the list as per the specified condition, say `products_info['data'].` These records are then sent to the If and Else handler to check if the data is valid. If true, then log that entry as "Success"; else log that entry as "Failure".

{% hint style="danger" %}
Step logger should not be used outside the Loop except when you are processing only one record.
{% endhint %}

###

### 8. Use general logger to log only general errors

**Purpose:** To detect any kind of high level errors in the code, outside of the loop.

**Example:**

```python
Get Orders API call to Epicor P21 Custom Server
If specified condition matched
    ....
Else
    Log general message customers
```

In this example, the If handler is used to check for any given condition (say, `status code == 200`). If the condition is not satisfied, the Logger records a failure and it is displayed upon clicking the View button from the Logs page.

{% hint style="danger" %}
&#x20;The recommended practice is to use the Logger outside the loop for overall logging purposes. It should not be used inside the Loop.
{% endhint %}

## OTHERS

### **9. Advanced**

Batch-wise calls like processing group of 10/20 records

### 10. Variable Names for Project and Pipe&#x20;

Project Name and Pipe Name is accessible through a variable in Flows Module namely current\_project, current\_pipe.&#x20;

## WORKAROUND

### 11. Get last synchronized time workaround

**Purpose**: To override the last updated time of the pipe.

```python
Assign last updated time to variable set_sync_time from system Magento 2
Assign value 01-01-2020 00:00:00 to variable set_sync_time
```

This workaround is used when the developer wants to assign a value for the `last updated time` and initiate the sync process from the newly assigned time("set\_sync\_time") onward.
