# JFUOptPackAplyChkCC

## Purpose

`JFUOptPackAplyChkCC` is the core business component responsible for **option pack eligibility judgment** in the K-Opticom telecommunications customer system. It determines whether a subscriber qualifies for discount option packs based on their service configuration, pricing plan, and a scoring system computed from predefined base values. This appears to be the single most important class in the option pack evaluation domain — it orchestrates three distinct CBS (Central Business System) lookups and combines their results to produce a definitive eligibility decision.

## Design

`JFUOptPackAplyChkCC` follows the **service component** pattern. It extends `JFUBaseCC`, which provides base methods for session management, service invocation (`executeSC`), and parameter manipulation (`setFuncCode`, `initData`, `ignoreSearchError`). The class acts as an **orchestrator/facade** over three separate CBS message templates, each responsible for a different stage of the eligibility pipeline:

1. **EFU0331B010** — Opt Pack Calculation Base Value List Lookup: retrieves configurable scoring criteria per pricing plan/service combination.
2. **EFU0341B010** — Eligible Pack Judgment List Lookup: queries which discount packs match the computed eligibility score.
3. **EKK2871B501** — Discount Judgment Discount Service Configuration Detail List Lookup (conditional): resolves single option services when substitution-type discounts apply.

The class implements the `getInvokeCBS` method inherited from `JFUBaseCC` but returns `null` to indicate that its internal CBS checks are performed independently via its own `judgeOptPack` flow.

## Key Methods

### `judgeOptPack`

```java
public IRequestParameterReadWrite judgeOptPack(
    SessionHandle handle,
    IRequestParameterReadWrite param,
    String fixedText
) throws Throwable
```

**Purpose:** The main entry point for screen/UI calls. This public method coordinates the entire option pack eligibility evaluation pipeline.

**Parameters:**
- `handle` — The session handle for database/service operations.
- `param` — Request parameter object containing input data under the `fixedText` key.
- `fixedText` — A service message identifier/key used to locate data within the request.

**Return value:** The modified `param` object with results stored under the `fixedText` key.

**Flow:** Delegates to `judgeCommonOptPack` (private), then writes the result `HashMap` back into the request parameter. The caller is responsible for reading `resultMap` from `param.getData(fixedText)` after invocation.

### `judgeOptPackIf`

```java
protected HashMap judgeOptPackIf(
    SessionHandle handle,
    IRequestParameterReadWrite param,
    String fixedText
) throws Throwable
```

**Purpose:** API-oriented entry point. Returns the result map directly rather than modifying the request parameter. This is the method that the subclass `JFUOptPackAplyChkIfCC` inherits and likely calls in API/IF scenarios.

**Return value:** A `HashMap` containing all output fields.

### `judgeCommonOptPack`

```java
private HashMap judgeCommonOptPack(
    SessionHandle handle,
    IRequestParameterReadWrite param,
    String fixedText
) throws Throwable
```

**Purpose:** The **heart of the class**. This private method implements the full eligibility evaluation pipeline:

1. **IN value validation** — Calls `chkInItemsVal` to verify the `base_date` input is present. If invalid, returns immediately with return code `999` (other abnormal termination).

2. **Step 1: Opt Pack Base Value Lookup (EFU0331B010)**
   - Initializes data with the base date (`KEY_STDARDYMD`).
   - Invokes the CBS template to get a list of configurable scoring rules — each rule maps a pricing code (`pcrs_cd`), plan code (`pplan_cd`), or option service code to a numeric judgment base value (`RTWAJG_KSS_STV`).

3. **Compute the judgment base value** — Calls `getPackJudgeBaseVal`. This sums up numeric scoring values from the EFU0331B010 results by matching against the input service codes or pricing/plan codes. The result is zero-padded to 16 digits (e.g., `0000000000000005`).

4. **Step 2: Eligible Pack Judgment (EFU0341B010)**
   - Initializes data with the base date and the computed judgment base value.
   - Invokes the CBS template to find matching discount packs.
   - Calls `getOtokuPackWribSvcCd` to extract the discount service code from results. Expects exactly one result — zero or more than one triggers return code `999`.
   - Sets return code `000` (normal completion) if the judgment pair combination flag is valid (`0`), or `100` (option combination invalid) otherwise. Also populates customer/operational display messages.

5. **Step 3: Discount Service Configuration (EKK2871B501) — conditional**
   - Only invoked if a valid discount service code was found.
   - Queries configuration details for the discount service (with `WRIB_KOSE_SVC_SKCD` = `"TP01"`).

6. **Single option service extraction** — If substitution-type discount applies (i.e., `RTWAJG_PTN_DIV` is set and not empty or `"99"`), calls `getSingleOpSbopSvcCdList` to determine which option/sub-option services are eligible as standalone options, excluding those already in the matched pack.

**Return value:** A `HashMap` containing output keys like `return_cd`, `wrib_svc_cd`, `rtwajg_ptn_div`, `csm_yo_dsp_mngn`, `oprt_yo_dsp_mngn`, `single_option_service_list`, and `op_sbop_svc_cd`.

### `chkInItemsVal`

```java
private boolean chkInItemsVal(
    IRequestParameterReadWrite param,
    String fixedText,
    HashMap resultMap
) throws Exception
```

**Purpose:** Validates input parameter values. The only required input is `base_date` (reference year/month/day). If missing or null, the method returns `false`, causing the entire evaluation to abort with return code `999`.

**Side effects:** Populates `resultMap` with extracted input values (`base_date`, `judge_pcrs_cd_list`, `judge_op_svc_cd_list`) when validation passes.

### `getPackJudgeBaseVal`

```java
private String getPackJudgeBaseVal(
    IRequestParameterReadWrite param,
    String fixedText,
    ArrayList opSbopSvcCdList
) throws Exception
```

**Purpose:** Computes the aggregate eligibility score. This is a critical method with complex matching logic:

- **Two matching modes:**
  1. **By pricing/plan codes:** If `judge_pcrs_cd_list` is provided, matches input `(pcrs_cd, pplan_cd)` pairs against the base value list and sums the `RTWAJG_KSS_STV` values of matching rows.
  2. **By option service codes:** If `judge_op_svc_cd_list` is provided instead, matches input `op_sbop_svc_cd` against either `OP_SVC_CD` or `SBOP_SVC_CD` fields in the base value list and sums matching scores.

- **Side effect on `opSbopSvcCdList`:** Collects all matched option/sub-option service codes into the passed list for later single-option filtering.

- Returns a 16-digit zero-padded string representation of the sum, or empty string if no base value list was returned.

### `getOtokuPackWribSvcCd`

```java
private String getOtokuPackWribSvcCd(
    IRequestParameterReadWrite param,
    String fixedText,
    HashMap resultMap
) throws Exception
```

**Purpose:** Extracts results from the EFU0341B010 eligible pack judgment. The key contract: **exactly one result row is expected**. If there are zero or more than one rows, the method sets return code `999` and returns `null`.

When exactly one row is found, it extracts and populates:
- `wrib_svc_cd` — The discount service code.
- `rtwajg_ptn_div` — Substitution-type discount pattern classification.
- `csm_yo_dsp_mngn` — Customer-facing display message (with carriage returns stripped).
- `oprt_yo_dsp_mngn` — Operator-facing display message.
- `return_cd` — `000` if the judgment pair combination flag (`JDG_JKN_VALUE_PAIR_MK_FLG`) equals `"0"` (valid), or `100` if invalid.

**Return value:** The `wrib_svc_cd` string, or `null` if evaluation failed.

### `setEFU0331B010`, `setEFU0341B010`, `setEKK2871B501`

**Purpose:** These three private methods are **parameter builders** that prepare request data maps before invoking CBS service templates. Each sets:
- The function code to `FUNC_CD_1` via `setFuncCode`.
- The relevant input keys (base date, judgment base value, or discount service code).

`setEKK2871B501` additionally sets `WRIB_KOSE_SVC_SKCD` to `"TP01"`.

### `getSingleOpSbopSvcCdList`

```java
private void getSingleOpSbopSvcCdList(
    IRequestParameterReadWrite param,
    String fixedText,
    HashMap resultMap,
    ArrayList inOpSbopSvcCdList
) throws Exception
```

**Purpose:** Determines which option/sub-option services can be applied as **standalone (single) options**. It takes the list of all matched services and removes those already included in the option pack configuration returned by EKK2871B01. The remaining services — those not part of the pack — become eligible as individual add-on options.

**Return value:** Populates `resultMap` with `OUT_SINGLE_OPTION_SERVICE_LIST` containing a list of single-option service entries, or `null` if none remain.

### `delReturnCdCr`

```java
private static String delReturnCdCr(Object val)
```

**Purpose:** Utility to strip carriage return characters (`\r`) from text values returned from the CBS system. Converts any remaining line separators to spaces (by replacing with empty string). Returns empty string for null inputs.

### `getInvokeCBS`

```java
@Override
public HashMap<String, Object> getInvokeCBS(
    SessionHandle handle,
    IRequestParameterReadWrite param,
    String fixedText
) throws Exception
```

**Purpose:** Overrides the parent's CBS invocation check method. Returns `null` to indicate that the main CBS checks are handled independently by the `judgeOptPack` flow. The comment explicitly states "check processing without" — meaning this class does not use the standard invocation check mechanism.

### `outDebugLog`

```java
private void outDebugLog(Object obj)
```

**Purpose:** Debug logging utility. Writes to the bus log at DEBUG level using `JSYejbLog.println`. Used throughout the class to log intermediate results of each CBS lookup and computation step.

## Return Codes

| Code | Meaning |
|------|---------|
| `000` | Normal completion — option pack eligible |
| `100` | Option combination invalid — judgment condition value pair is not valid |
| `999` | Other abnormal termination — missing data, wrong number of results, or invalid input |

## Relationships

```mermaid
flowchart TD
    A["JFUOptPackAplyChkIfCC<br/>Subclass (API/IF Layer)"] --> B["JFUOptPackAplyChkCC<br/>Option Pack Eligibility Checker"]
    B --> C["JFUBaseCC<br/>Base Component"]
    B --> D["EFU0331B010<br/>Base Value Lookup<br/>CBS Template"]
    B --> E["EFU0341B010<br/>Eligible Pack Lookup<br/>CBS Template"]
    B --> F["EKK2871B501<br/>Discount Config Lookup<br/>CBS Template"]
```

- **Inbound:** `JFUOptPackAplyChkIfCC` extends this class, adding phone number history verification, service contract consent checks, and option service contract lookups. It invokes inherited methods like `judgeOptPackIf` to perform the core eligibility logic after its own pre-checks.
- **Outbound:** Extends `JFUBaseCC` for base service component behavior (session handling, CBS invocation, function code management).

## Usage Example

A typical call sequence looks like this:

```java
// Screen/UI path
IRequestParameterReadWrite param = ...;  // populate with base_date, judge_pcrs_cd_list, etc.
JFUOptPackAplyChkCC checker = new JFUOptPackAplyChkCC();
param = checker.judgeOptPack(sessionHandle, param, "myServiceKey");

// After invocation, extract results:
HashMap resultMap = (HashMap) param.getData("myServiceKey");
String returnCd  = (String) resultMap.get("return_cd");
String wribSvcCd = (String) resultMap.get("wrib_svc_cd");
String csmMsg    = (String) resultMap.get("csm_yo_dsp_mngn");
```

For API paths (used by `JFUOptPackAplyChkIfCC`):

```java
JFUOptPackAplyChkIfCC ifChecker = new JFUOptPackAplyChkIfCC();
HashMap resultMap = ifChecker.judgeOptPackIf(sessionHandle, param, "myServiceKey");
```

The `param` object must contain:
- `base_date` — String in year/month/day format (required, triggers `999` if missing)
- `judge_pcrs_cd_list` — List of `{pcrs_cd, pplan_cd}` maps for pricing/plan matching mode
- `judge_op_svc_cd_list` — List of `{op_sbop_svc_cd}` maps for option service matching mode

## Notes for Developers

- **Thread safety:** This class is **not thread-safe**. It relies on mutable `HashMap` objects in the request parameter and does not use synchronization. Each request should use its own instance or ensure serialized access.

- **No validation on CBS result count:** The EFU0341B010 eligible pack lookup explicitly checks that exactly one result row is returned. Zero or multiple rows both result in return code `999`. This means the business logic assumes the CBS will always return at most one eligible pack — this is an invariant of the CBS template configuration.

- **Score computation uses `long`:** `getPackJudgeBaseVal` accumulates judgment values as `long`, then formats to a 16-digit zero-padded string. Be aware that the sum could overflow if many high-value matching rules exist — though this is unlikely in practice given telecom pricing configurations.

- **Two mutually exclusive matching modes:** The method uses `judge_pcrs_cd_list` (pricing/plan-based) OR `judge_op_svc_cd_list` (option service-based), not both simultaneously. If `judge_pcrs_cd_list` is non-empty, it takes priority and the option service list path is skipped.

- **Conditional third lookup:** The EKK2871B501 CBS template is only invoked when `wribSvcCd` is non-null. If the eligible pack judgment finds no valid discount service, steps involving single option service resolution are entirely skipped.

- **Display message sanitization:** Carriage returns are stripped from display messages (`delReturnCdCr`) because they may contain raw line feed characters (`
`) that remain. Display consumers should handle this appropriately.

- **The `RTWAJG_PTN_DIV` gate:** Single option service resolution only occurs when the substitution-type pattern classification is set and is neither empty nor `"99"`. This is a business rule that determines whether a pack uses substitution-based discount logic.

- **Subclass usage:** `JFUOptPackAplyChkIfCC` adds additional pre-checks (service contract, phone number history) before delegating to the parent's judgment methods. The parent class methods are the authoritative eligibility engine — the subclass is a specialized wrapper with additional data validation.

- **All CBS errors are swallowed:** Calls to `ignoreSearchError` prevent search errors from propagating, so the class gracefully handles missing CBS data by returning empty result lists. This means CBS misconfiguration will silently produce `999` results rather than throwing exceptions.
