# Apex 클래스를 활용해 다양한 방식으로 데이터 가져오기

{% hint style="warning" %}
버전 1.37부터 ‘**데이터소스(Data Source)**’가 ‘**비즈니스 규칙(Business Rule)**’으로 명칭이 변경되었습니다.
{% endhint %}

**외부 API 서버에서 데이터를 조회**하거나, 데이터 조회 및 결합 시 **복잡한 로직이 요구**되는 경우에 사용됩니다. 해당 비즈니스 규칙을 설정하려면 **Apex 클래스를 작성**해야 합니다. Apex 클래스를 사용해 구현하므로 데이터를 더 자유롭게 가져올 수 있다는 장점이 있습니다.

<figure><img src="https://3985481653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FA2fSsDo5KsIVkUoDIV1b%2Fuploads%2FC01uCA3STZir93PNuTfM%2Fimage.png?alt=media&#x26;token=f0206935-ef0a-43a0-be35-09fdeea712e4" alt=""><figcaption></figcaption></figure>

***

## 설정 과정

{% stepper %}
{% step %}
**Apex 클래스 작성**

Apex 클래스를 작성할 때, SmallBuilder에서 제공하는 인터페이스를 구현해야 합니다.
{% endstep %}

{% step %}
**비즈니스 규칙 설정**

Apex 클래스 구현이 완료되면, 빌더에서 비즈니스 규칙 설정을 진행합니다.
{% endstep %}
{% endstepper %}

## STEP 1: 비즈니스 규칙에 사용할 Apex 클래스를 작성하기 위한 인터페이스 구현

비즈니스 규칙 설정에서 사용할 Apex 클래스를 작성하려면 반드시 `SBLI.DataSourceService.Fetchable` **인터페이스를 구현**해야 합니다.

이 인터페이스에는 `execute` 메서드가 포함되어 있으며, 해당 메서드에 데이터 처리를 위한 로직 구현 후 처리된 데이터와 조회 또는 라인 아이템 간의 매핑 정보를 담은 `SBLI.DataSourceService.Result` 객체를 반환해야 합니다.

#### 예시 코드

해당 예시 코드는 외부 API를 호출하여 제품 코드별 재고 수량을 가져온 후, 조회 또는 라인 아이템의 재고 필드(`Inventory__c`)에 매핑한다고 가정하였습니다.

{% hint style="warning" %}
`SBLI.DataSourceService.Fetchable` 인터페이스는 패키지에서 제공되는 인터페이스이므로, 패키지 외부에서 접근하려면 Apex 클래스와 제공되는 메서드 모두 **`global`**&#xB85C; 선언해야 합니다.
{% endhint %}

{% code lineNumbers="true" %}

```java
global class DataSourceInventory implements SBLI.DataSourceService.Fetchable {
    global SBLI.DataSourceService.Result execute(SBLI.DataSourceService.Parameter params) {
        // 부모 레코드 가져오기
        SObject parentRecord = params.getParentRecord();

        // 조회 개체 레코드 가져오기
        List<SObject> lookupRecords = params.getLookupRecords();
        
        // 외부 API를 호출하여 재고 정보 가져오기
        // 키: 제품 코드, 값: 재고 수량
        Map<String, Integer> inventoryData = new Map<String, Integer>(); 
        inventoryData.put('Product001', 10);
        inventoryData.put('Product002', 20);

        // 결과 객체 생성
        SBLI.DataSourceService.Result result = new SBLI.DataSourceService.Result();

        // 조회/라인 아이템 개체와 결과 값 매핑
        for (String productCode : inventoryData.keySet()) {
            SBLI.DataSourceService.Action action = new SBLI.DataSourceService.Action();
            action.setKeyValue(productCode); // 조회/라인 아이템 레코드와 매핑할 Key 값 설정
            action.putSourceToTargetField(
                inventoryData.get(productCode), // 결과 값: 재고 정보
                'Inventory__c'                 // 조회/라인 아이템 필드 API명
            );
            result.addAction(action); // Action 추가
        }
        
        return result; // 결과 반환
    }
}
```

{% endcode %}

<figure><img src="https://3985481653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FA2fSsDo5KsIVkUoDIV1b%2Fuploads%2F6Y1dgeY5NLuWSWPhm94B%2Fimage.png?alt=media&#x26;token=b4e2a676-01d1-4510-993b-449e62a09652" alt=""><figcaption></figcaption></figure>

{% stepper %}
{% step %}

#### 부모 레코드 및 조회 레코드 가져오기

* `params.getParentRecord()`: 부모 개체의 레코드를 가져옵니다.
* `params.getLookupRecords()`: 조회 개체의 레코드 목록을 가져옵니다.

```java
// 부모 레코드 가져오기
SObject parentRecord = params.getParentRecord();
// 조회 개체 레코드 가져오기
List<SObject> lookupRecords = params.getLookupRecords();
```

[SBLI.DataSourceService.Parameter 참고 >](#sbli.datasourceservice.parameter)
{% endstep %}

{% step %}

#### &#x20;비즈니스 규칙 값 준비

* 외부 API 서버에서 데이터를 호출하여 재고 정보를 가져온다고 가정합니다.
* 예시에서는 제품 코드(`ProductCode`)를 기반으로 재고 정보를 매핑합니다.

```java
Map<String, Integer> inventoryData = new Map<String, Integer>(); 
inventoryData.put('Product001', 10);
inventoryData.put('Product002', 20);
```

{% endstep %}

{% step %}

#### 결과 생성

* [`SBLI.DataSourceService.Action`](#sbli.datasourceservice.action) 객체를 생성하여 비즈니스 규칙 값(재고 정보)과 조회 필드(`Inventory__c`)를 매핑합니다.
* 생성된 Action 객체를 [`SBLI.DataSourceService.Result`](#sbli.datasourceservice.result)에 추가합니다.

```java
// 결과 객체 생성
SBLI.DataSourceService.Result result = new SBLI.DataSourceService.Result();

// 조회/라인 아이템 개체와 비즈니스 규칙으로 가져온 값 매핑
for (String productCode : inventoryData.keySet()) {
    SBLI.DataSourceService.Action action = new SBLI.DataSourceService.Action();
    action.setKeyValue(productCode); // 조회/라인 아이템 레코드와 매핑할 Key 값 설정
    action.putSourceToTargetField(
        inventoryData.get(productCode), // 비즈니스 규칙 값: 재고 정보
        'Inventory__c'                 // 조회/라인 아이템 필드 API명
    );
    result.addAction(action); // Action 추가
}
```

{% endstep %}

{% step %}

#### 반환

매핑된 결과를 담은 Result 객체를 반환하여, 편집기에 매핑 정보를 전달합니다.
{% endstep %}
{% endstepper %}

### SBLI.DataSourceService.Parameter

빌더에서 설정한 **부모와 조회** **파라미터 정보**를 가진 객체입니다.

#### 예시 코드

<pre class="language-java" data-title="DataSourceInventory.cls" data-line-numbers><code class="lang-java">global SBLI.DataSourceService.Result execute(SBLI.DataSourceService.Parameter params) {
<strong>    SObject parentRecord = params.getParentRecord();
</strong><strong>    List&#x3C;SObject> lookupRecords = params.getLookupRecords();
</strong>    ...
}
</code></pre>

#### Methods

**`SObject getParentRecord()`**

부모 레코드를 반환합니다. 빌더에서 추가한 부모 파라미터가 없는 경우, 값은 비어 있습니다.

**`List<SObject> getLookupRecords()`**

조회 레코드를 반환합니다. 빌더에서 추가한 조회 파라미터가 없는 경우, 값은 비어 있습니다.

### SBLI.DataSourceService.Result

조회 또는 라인 아이템과 비즈니스 규칙 간의 **모든 매핑 정보를 담아 편집기로 반환**하는 객체입니다. 매핑 정보는 [`SBLI.DataSourceService.Action`](#sbli.datasourceservice.action) 객체에 저장한 뒤, `SBLI.DataSourceService.Result` 객체에 추가하여 반환합니다.

#### 예시 코드

<pre class="language-java" data-title="DataSourceInventory.cls" data-line-numbers><code class="lang-java"><strong>SBLI.DataSourceService.Result result = new SBLI.DataSourceService.Result();
</strong>for(String productCode : inventoryData.keySet()) {
    // SBLI.DataSourceService.Action 객체에 매핑 정보 저장
    SBLI.DataSourceService.Action action = new SBLI.DataSourceService.Action();
    action.setKeyValue(productCode);
    action.putSourceToTargetField(
        inventoryData.get(productCode),
        'Inventory__c'
    );
<strong>    result.addAction(action); // 매핑 정보가 담긴 Action을 Result에 추가
</strong>}
return result;
</code></pre>

#### Methods

**`addAction(SBLI.DataSourceService.Action action)`**

매핑 정보가 담긴 Action 객체를 Result 객체에 추가합니다.

<table><thead><tr><th width="118">매개변수</th><th>유형</th><th>값</th></tr></thead><tbody><tr><td><strong>action</strong></td><td><a href="#sbli.datasourceservice.action">SBLI.DataSourceService.Action</a></td><td>조회 또는 라인 아이템과 비즈니스 규칙 값을 매핑한 정보를 담은 객체입니다.</td></tr></tbody></table>

### SBLI.DataSourceService.Action

조회 또는 라인 아이템과 비즈니스 규칙 값을 **매핑한 정보를 담은 객체**입니다.

#### 예시 코드

<pre class="language-java" data-title="DataSourceInventory.cls" data-line-numbers><code class="lang-java">SBLI.DataSourceService.Result result = new SBLI.DataSourceService.Result();
// 비즈니스 규칙에서 각 제품코드와 재고 정보를 반복 처리
for(String productCode : inventoryData.keySet()) {
<strong>    SBLI.DataSourceService.Action action = new SBLI.DataSourceService.Action();
</strong><strong>    // 제품코드를 Key 값으로 설정하여 조회/라인 아이템과 매핑
</strong><strong>    action.setKeyValue(productCode);
</strong><strong>    
</strong><strong>    // 재고 정보를 조회/라인 아이템의 Inventory__c 필드에 매핑 
</strong><strong>    action.putSourceToTargetField(
</strong><strong>        inventoryData.get(productCode),    // 데이터소스 값: 재고
</strong><strong>        'Inventory__c'                                // 필드 API명
</strong><strong>    );
</strong>    result.addAction(action); // 매핑 정보 추가
}
return result; // 최종 결과 반환
</code></pre>

#### Methods

**`setKeyValue(Object keyValue)`**

조회 또는 라인 아이템의 Key와 일치하는 비즈니스 규칙의 Key 값을 설정합니다.

<table><thead><tr><th width="129">매개변수</th><th width="99">유형</th><th>값</th></tr></thead><tbody><tr><td><strong>keyValue</strong></td><td>Object</td><td>비즈니스 규칙의 Key 값입니다.</td></tr></tbody></table>

**`putSourceToTargetField(Object sourceValue, String targetFieldApiName)`**

**비즈니스 규칙 값**을 원하는 **조회 또는 라인 아이템 필드**에 할당합니다.

<table><thead><tr><th width="206">매개변수</th><th width="100">유형</th><th>값</th></tr></thead><tbody><tr><td><strong>sourceValue</strong></td><td>Object</td><td>비즈니스 규칙 값입니다.</td></tr><tr><td><strong>targetFieldApiName</strong></td><td>String</td><td>조회 또는 라인 아이템의 필드 API명입니다.</td></tr></tbody></table>

## STEP 2: 비즈니스 규칙 설정

**라인 아이템 편집기 설정** 단계에서 비즈니스 규칙의 ‘**Apex 클래스를 사용하여 데이터 가져오기**’ 레이아웃에서 ‘**비즈니스 규칙 추가**’를 클릭합니다.

Apex 클래스를 선택한 후, 클래스에서 부모와 조회 정보가 필요한 경우 파라미터로 전달할 필드들을 선택합니다.

{% hint style="warning" %}
데이터소스를 설정하기 전에 [Apex 클래스를 먼저 작성](#apex)하세요.
{% endhint %}

<figure><img src="https://3985481653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FA2fSsDo5KsIVkUoDIV1b%2Fuploads%2FnwaFfhXodIrUBHUgRYRw%2F%E1%84%87%E1%85%B5%E1%84%8C%E1%85%B3%E1%84%82%E1%85%B5%E1%84%89%E1%85%B3%E1%84%80%E1%85%B2%E1%84%8E%E1%85%B5%E1%86%A8_%E1%84%80%E1%85%A9%E1%84%80%E1%85%B3%E1%86%B8_%E1%84%89%E1%85%A5%E1%86%AF%E1%84%8C%E1%85%A5%E1%86%BC.png?alt=media&#x26;token=29900a88-a863-45d3-a50c-d70884b55a2f" alt=""><figcaption></figcaption></figure>

<table><thead><tr><th width="76.9921875">번호</th><th width="214">항목</th><th width="447">설명</th><th>필수</th></tr></thead><tbody><tr><td><strong>1</strong></td><td><strong>Apex Class</strong></td><td>비즈니스 규칙에 사용할 Apex 클래스를 선택합니다.</td><td><mark style="color:red;">✔</mark></td></tr><tr><td><strong>3</strong></td><td><strong>파라미터</strong> </td><td>비즈니스 규칙을 구현한 Apex 클래스에서 부모 또는 조회 개체의 필드 값이 필요한 경우, 해당 필드를 파라미터로 전달하기 위해 추가합니다.</td><td></td></tr><tr><td><strong>4</strong></td><td><strong>평가 이벤트</strong></td><td><p>비즈니스 규칙의 <strong>실행 시점</strong>을 설정합니다.</p><ul><li><strong>초기화 시(On Initialization):</strong> 라인 아이템 레코드가 새로 추가될 때 실행됩니다.</li><li><strong>로딩 시(On Loading):</strong> 라인 아이템 화면이 로드될 때마다 실행됩니다.</li><li><strong>변경 시(On Change):</strong> 라인 아이템의 특정 필드가 변경될 때마다 실행됩니다.</li><li><strong>저장 전(Before Save):</strong> 라인 아이템 레코드가 저장되기 전에 실행됩니다.</li></ul><p><span data-gb-custom-inline data-tag="emoji" data-code="2757">❗</span> <em><mark style="color:red;">라인 아이템에서만 제공되는 설정입니다.</mark></em></p></td><td><mark style="color:red;">✔</mark></td></tr><tr><td><strong>5</strong></td><td><strong>작업 키</strong></td><td><p>비즈니스 규칙을 통해 가져온 데이터를 조회 또는 라인 아이템 레코드에 매핑하기 위해 Key 필드를 설정합니다.</p><p>Key 필드는 <strong>조회 개체의 필드</strong>를 사용합니다.<br><br><span data-gb-custom-inline data-tag="emoji" data-code="1f481">💁</span> <mark style="color:orange;">라인 아이템에서 조회 개체의 필드를 Key로 사용하는 이유는, 라인 아이템이 저장되지 않은 레코드일 수도 있어 유일한 Key 값을 판단하기 어렵기 때문입니다.</mark></p></td><td><mark style="color:red;">✔</mark></td></tr></tbody></table>

## STEP 3: 비즈니스 규칙 활성화

비즈니스 규칙을 사용하려면 활성화가 필요합니다. 비즈니스 규칙이 비활성화되어 있는 경우, 설정된 규칙은 적용되지 않습니다.

{% hint style="info" %}
비즈니스 규칙은 최초 추가 시 자동으로 활성화됩니다.
{% endhint %}

<figure><img src="https://3985481653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FA2fSsDo5KsIVkUoDIV1b%2Fuploads%2Ft0PtPicy3OtActjzxrkg%2F%E1%84%87%E1%85%B5%E1%84%8C%E1%85%B3%E1%84%82%E1%85%B5%E1%84%89%E1%85%B3%E1%84%80%E1%85%B2%E1%84%8E%E1%85%B5%E1%86%A8_%E1%84%80%E1%85%A9%E1%84%80%E1%85%B3%E1%86%B8_%E1%84%92%E1%85%AA%E1%86%AF%E1%84%89%E1%85%A5%E1%86%BC%E1%84%92%E1%85%AA.png?alt=media&#x26;token=eb11ddd6-06b8-4cd9-ace5-30d4ac330cfb" alt=""><figcaption></figcaption></figure>
