# Business Logic — JKKAdchgCheckerCC.kikiStateChecker() [72 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `com.fujitsu.futurity.bp.custom.common.JKKAdchgCheckerCC` |
| Layer | CC/Common Component (Package: `com.fujitsu.futurity.bp.custom.common`) |
| Module | `common` (Package: `com.fujitsu.futurity.bp.custom.common`) |

## 1. Role

### JKKAdchgCheckerCC.kikiStateChecker()

This method performs the **primary device status validation** for address-change registration (first pass). In Fujitsu's K-Opticom broadband customer core system, customers can transfer their registered address across multiple service contracts (Internet, telephone, and television). Before a new address can be registered, the system must verify that no associated device is currently in an active or pending state that would prevent the change.

The method follows a **branch-and-rout dispatch pattern**: it independently checks device status for each of the three service lines (Net, Tel, TV). Each service line number is extracted from the request parameter map, and if present, the method delegates to `getKikiInfo()` to fetch the associated device-contract information, then passes the result to `kikiStateCheck()` to validate the device state codes.

Its role in the larger system is a **gatekeeper validation component** invoked during the address-change confirmation screen workflow (screen KKSV0698). It runs before the actual address-change registration to prevent invalid state transitions. The method is invoked remotely via a `CCRequestBroker`, making it a shared validation endpoint consumed by the BPM-based operation layer.

If any service line's devices are found in an active state (010, 020, or 030), the method marks the overall check as failed, allowing the caller to display an appropriate error message to the user. The method also manages session handle lifecycle via `ThreadLocal` to ensure proper cleanup even if exceptions occur.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["kikiStateChecker start"])
    STORE_SESSION["keepSesHandle.set handle"]
    GET_DATA["paramMap = param.getData fixedText"]
    INIT_OK["paramMap.put check_result = CHECK_OK 1"]
    GET_NET["svcKeiNt = paramMap.get svcKeiNo_Net"]
    GET_TEL["svcKeiTl = paramMap.get svcKeiNo_Tel"]
    GET_TV["svcKeiTv = paramMap.get svcKeiNo_Tv"]
    SET_CHKFLG["chkflg = true"]

    BRANCH_NET{Is svcKeiNt non-empty?}
    BRANCH_TEL{Is svcKeiTl non-empty and chkflg?}
    BRANCH_TV{Is svcKeiTv non-empty and chkflg?}

    GET_NET_INFO["getKikiInfo param fixedText svcKeiNt funcCode6"]
    CHECK_NET_STATE["kikiStateCheck chkKikiListNet"]
    NET_FAIL["paramMap.put check_result = CHECK_ERR 0; chkflg = false"]

    GET_TEL_INFO["getKikiInfo param fixedText svcKeiTl funcCode6"]
    CHECK_TEL_STATE["kikiStateCheck chkKikiListTel"]
    TEL_FAIL["paramMap.put check_result = CHECK_ERR 0; chkflg = false"]

    GET_TV_INFO["getKikiInfo param fixedText svcKeiTv funcCode6"]
    CHECK_TV_STATE["kikiStateCheck chkKikiListTv"]
    TV_FAIL["paramMap.put check_result = CHECK_ERR 0; chkflg = false"]

    RETURN_PARAM["return param"]
    CLEANUP["keepSesHandle.remove"]
    END_NODE(["kikiStateChecker end"])

    START --> STORE_SESSION --> GET_DATA --> INIT_OK --> GET_NET --> GET_TEL --> GET_TV --> SET_CHKFLG --> BRANCH_NET
    BRANCH_NET --> GET_NET_INFO --> CHECK_NET_STATE
    CHECK_NET_STATE -->|false| NET_FAIL --> BRANCH_TEL
    CHECK_NET_STATE -->|true| BRANCH_TEL
    BRANCH_NET --> BRANCH_TEL

    BRANCH_TEL --> GET_TEL_INFO --> CHECK_TEL_STATE
    CHECK_TEL_STATE -->|false| TEL_FAIL --> BRANCH_TV
    CHECK_TEL_STATE -->|true| BRANCH_TV
    BRANCH_TEL --> BRANCH_TV

    BRANCH_TV --> GET_TV_INFO --> CHECK_TV_STATE
    CHECK_TV_STATE -->|false| TV_FAIL --> RETURN_PARAM
    CHECK_TV_STATE -->|true| RETURN_PARAM
    BRANCH_TV --> RETURN_PARAM

    RETURN_PARAM --> CLEANUP --> END_NODE
```

### Flow Explanation

1. **Resource preservation**: The incoming `SessionHandle` is stored in a `ThreadLocal` variable (`keepSesHandle`) for downstream SC invocations.
2. **Preparation**: The parameter map is extracted using the `fixedText` key as a grouping identifier.
3. **Check result initialization**: The `check_result` key is set to `CHECK_OK` ("1") as the default.
4. **Service line extraction**: Three service contract numbers are extracted:
   - `svcKeiNo_Net` (Net service)
   - `svcKeiNo_Tel` (Tel service)
   - `svcKeiNo_Tv` (TV service)
5. **Device status check per service**: For each service line that has a non-empty value and where no prior failure has occurred (`chkflg == true`):
   - Fetch device-contract info via `getKikiInfo()` (with `funcCode="6"` per modification OM-2014-0001369)
   - Validate device states via `kikiStateCheck()`
   - If any device has an active state, mark the check as failed and short-circuit remaining branches.
6. **Cleanup**: The `ThreadLocal` session handle is removed in a `finally` block.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `handle` | `SessionHandle` | The database session handle representing the user's transaction context. Contains connection and session metadata required for SC (Service Component) calls downstream. Stored in `ThreadLocal` for scoped access by called methods. |
| 2 | `param` | `IRequestParameterReadWrite` | The request parameter object carrying model groups and a control map. It encapsulates the address-change registration data submitted by the user screen, including service contract numbers for Net, Tel, and TV lines, and holds the `check_result` output field. |
| 3 | `fixedText` | `String` | A user-defined text string used as a parameter map key identifier. It determines which group of parameters is extracted from `param` via `param.getData(fixedText)`. Enables grouping of related fields (e.g., different screen views or steps). |

### Instance Fields / External State

| Field | Type | Business Description |
|-------|------|---------------------|
| `keepSesHandle` | `ThreadLocal<SessionHandle>` | Thread-local session handle storage. Persists the session across the call chain so downstream SC invocations (`getKikiInfo`, etc.) can access the same database context. Automatically cleaned up in `finally`. |

## 4. CRUD Operations / Called Services

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `JBSbatDKNyukaFinAdd.getData` | JBSbatDKNyukaFinAdd | - | Calls `getData` in `JBSbatDKNyukaFinAdd` |
| R | `JFUeoTelOpTransferCC.getData` | JFUeoTelOpTransferCC | - | Calls `getData` in `JFUeoTelOpTransferCC` |
| R | `JFUTransferCC.getData` | JFUTransferCC | - | Calls `getData` in `JFUTransferCC` |
| R | `JFUTransferListToListCC.getData` | JFUTransferListToListCC | - | Calls `getData` in `JFUTransferListToListCC` |
| R | `JKKAdchgCheckerCC.getKikiInfo` | JKKAdchgCheckerCC | - | Calls `getKikiInfo` in `JKKAdchgCheckerCC` |
| R | `JKKAdchgCheckerCC.kikiStateCheck` | JKKAdchgCheckerCC | - | Calls `kikiStateCheck` in `JKKAdchgCheckerCC` |
| R | `KKW12701SFLogic.getData` | KKW12701SFLogic | - | Calls `getData` in `KKW12701SFLogic` |

### Detailed SC Code / Entity Analysis

The method calls two internal helper methods (`getKikiInfo` and `kikiStateCheck`), which themselves invoke Service Components:

**`getKikiInfo`** (internal, lines 571-624 of JKKAdchgCheckerCC.java):
- Uses `JKKAdchgMapperCC` as the mapping cursor instance
- Uses `ServiceComponentRequestInvoker` for SC invocation
- Calls `mapper.setEKK0341B002(param, fixedText, condMap, funcCode)` with `funcCode="6"` → builds the SC request for **Device-contract list inquiry (by service contract number)**
- Calls `scCall.run(reqMap, keepSesHandle.get())` → executes SC `EKK0341B002`
- Calls `mapper.getEKK0341B002(param, fixedText, resMap)` → retrieves device-contract list
- Calls `mapper.scResultCheck(param)` → validates SC result
- Iterates through results and for each device:
  - Calls `mapper.setEKK0341A010(param, fixedText, condMap)` → builds SC request for **Device-contract agreement inquiry**
  - Calls `scCall.run(reqMap, keepSesHandle.get())` → executes SC `EKK0341A010`
  - Calls `mapper.getEKK0341A010(param, fixedText, resMap)` → retrieves single agreement record
  - Calls `mapper.scResultCheck(param)` → validates SC result

**`kikiStateCheck`** (internal, lines 827-843 of JKKAdchgCheckerCC.java):
- Pure validation logic, no external DB calls
- Iterates over the device list and checks each device's state code (`KKTK_SVC_KEI_STAT`)
- Returns `false` (check fails) if any device state is `"010"`, `"020"`, or `"030"`

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `mapper.setEKK0341B002` / `scCall.run` | EKK0341B002 | KK_T_EKKTK_D (device-contract table) | Fetch device-contract list filtered by service contract number (`COND_KEY_SVC_KEI_NO`) |
| R | `mapper.setEKK0341A010` / `scCall.run` | EKK0341A010 | KK_T_EKKTK_D (device-contract agreement table) | Fetch device-contract agreement details (single record by service contract number + operation date) |

**Classified call graph for this method:**

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `JKKAdchgCheckerCC.getKikiInfo` (EKK0341B002) | EKK0341B002 | KK_T_EKKTK_D | Read device-contract list for a given service contract number |
| R | `JKKAdchgCheckerCC.getKikiInfo` (EKK0341A010) | EKK0341A010 | KK_T_EKKTK_D | Read device-contract agreement details per device |
| R | `JKKAdchgCheckerCC.kikiStateCheck` | N/A (in-memory) | N/A | Validate device states in memory — no DB call |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Screen:KKSV0698 | `KKSV0698OPOperation.target1d` (CCRequestBroker) → `CCRequestBroker.invoke` → `JKKAdchgCheckerCC.kikiStateChecker` | `getKikiInfo [R] KK_T_EKKTK_D`, `kikiStateCheck [R] in-memory` |

**Caller details:**
- `KKSV0698OPOperation` (at lines 541-542) creates a `CCRequestBroker` named `target1d` that targets `JKKAdchgCheckerCC.kikiStateChecker` with CC class name `KKSV069806CC`. This is a BPM-based remote invocation mechanism where the screen operation class delegates to the CC method via `CCRequestBroker`.

## 6. Per-Branch Detail Blocks

**Block 1** — [SET/STORE] Session handle preservation (L748)

> Preserves the session handle in a ThreadLocal for downstream SC invocations. This is the resource preservation block added via OM-2013-0004303.

| # | Type | Code |
|---|------|------|
| 1 | SET | `keepSesHandle.set(handle)` // Store session handle in ThreadLocal [-> keepSesHandle] |

**Block 2** — [SET/INIT] Parameter map extraction and check initialization (L752-758)

> Extracts the relevant parameter group from the request, then initializes the check result to OK and extracts the three service contract numbers.

| # | Type | Code |
|---|------|------|
| 1 | SET | `paramMap = (HashMap) param.getData(fixedText)` // Extract parameter map by key [-> fixedText param] |
| 2 | SET | `paramMap.put("check_result", CHECK_OK)` // Initialize check result to OK [-> CHECK_OK = "1" (JKKAdchgCheckerCC.java:73)] |
| 3 | SET | `svcKeiNt = (String) paramMap.get("svcKeiNo_Net")` // Extract Net service contract number |
| 4 | SET | `svcKeiTl = (String) paramMap.get("svcKeiNo_Tel")` // Extract Tel service contract number |
| 5 | SET | `svcKeiTv = (String) paramMap.get("svcKeiNo_Tv")` // Extract TV service contract number |
| 6 | SET | `chkflg = true` // Check flag — false means a prior service line failed |

**Block 3** — [IF] Net service line device status check (L762-776)

> Conditionally checks Net service line devices if a Net contract number exists. Per OM-2014-0001369, `funcCode="6"` is passed to `getKikiInfo` (changed from the previous overloaded version without funcCode).

| # | Type | Code |
|---|------|------|
| 1 | IF | `!StringUtils.isEmpty(svcKeiNt)` [-> StringUtils.isEmpty check on svcKeiNt] (L762) |
| 1.1 | CALL | `chkKikiList_Net = getKikiInfo(param, fixedText, svcKeiNt, "6")` [-> funcCode="6" per OM-2014-0001369 modification] (L769) |
| 1.2 | IF | `!kikiStateCheck(chkKikiList_Net)` [-> returns false if any device state is 010/020/030] (L773) |
| 1.2.1 | SET | `paramMap.put("check_result", CHECK_ERR)` [-> CHECK_ERR = "0" (JKKAdchgCheckerCC.java:75)] |
| 1.2.2 | SET | `chkflg = false` [-> short-circuit remaining branches] |

**Block 4** — [IF] Tel service line device status check (L779-793)

> Conditionally checks Tel service line devices only if a Tel contract number exists AND no prior failure occurred (`chkflg == true`). Same `funcCode="6"` modification from OM-2014-0001369.

| # | Type | Code |
|---|------|------|
| 1 | IF | `!StringUtils.isEmpty(svcKeiTl) && chkflg` [-> AND with chkflg for short-circuit] (L779) |
| 1.1 | CALL | `chkKikiList_Tel = getKikiInfo(param, fixedText, svcKeiTl, "6")` [-> funcCode="6"] (L786) |
| 1.2 | IF | `!kikiStateCheck(chkKikiList_Tel)` (L788) |
| 1.2.1 | SET | `paramMap.put("check_result", CHECK_ERR)` [-> CHECK_ERR = "0" (JKKAdchgCheckerCC.java:75)] |
| 1.2.2 | SET | `chkflg = false` [-> short-circuit remaining branches] |

**Block 5** — [IF] TV service line device status check (L796-810)

> Conditionally checks TV service line devices only if a TV contract number exists AND no prior failure occurred. Same `funcCode="6"` modification from OM-2014-0001369.

| # | Type | Code |
|---|------|------|
| 1 | IF | `!StringUtils.isEmpty(svcKeiTv) && chkflg` [-> AND with chkflg for short-circuit] (L796) |
| 1.1 | CALL | `chkKikiList_Tv = getKikiInfo(param, fixedText, svcKeiTv, "6")` [-> funcCode="6"] (L803) |
| 1.2 | IF | `!kikiStateCheck(chkKikiList_Tv)` (L805) |
| 1.2.1 | SET | `paramMap.put("check_result", CHECK_ERR)` [-> CHECK_ERR = "0" (JKKAdchgCheckerCC.java:75)] |
| 1.2.2 | SET | `chkflg = false` [-> short-circuit remaining branches] |

**Block 6** — [RETURN] Return parameter (L813)

> Returns the modified `param` object with `check_result` set to either `CHECK_OK` ("1") or `CHECK_ERR` ("0") depending on validation outcome.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return param` |

**Block 7** — [TRY-FINALLY] Session handle cleanup (L815-822)

> Added via OM-2013-0004303. Ensures the ThreadLocal session handle is removed even if an exception occurs during processing.

| # | Type | Code |
|---|------|------|
| 1 | FINALLY | try block wraps the entire method body (L747-L814) |
| 2 | IF | `keepSesHandle.get() != null` (L818) |
| 2.1 | EXEC | `keepSesHandle.remove()` // Cleanup ThreadLocal session handle (L819) |

### Nested Method: getKikiInfo — Device-contract info retrieval

**Block G1** — [SET] Setup mappers and SC invoker (L579-590)

| # | Type | Code |
|---|------|------|
| 1 | SET | `condMap = new HashMap<String, String>()` |
| 2 | SET | `mapper = JKKAdchgMapperCC.getInstance()` // Obtain address-change CC mapping cursor instance |
| 3 | SET | `scCall = new ServiceComponentRequestInvoker()` // Obtain SC request invoker |
| 4 | SET | `kikiInfoList = new ArrayList()` // Initialize device info list |
| 5 | SET | `condMap.put(JKKAdchgMapperCC.COND_KEY_SVC_KEI_NO, svcKeiNo)` // Set service contract number as condition key |
| 6 | CALL | `reqMap = mapper.setEKK0341B002(param, fixedText, condMap, funcCode)` [-> funcCode="6" per modification] (L598) |
| 7 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` // Execute SC EKK0341B002 (device-contract list) |
| 8 | CALL | `kk0341_b002_map_list = mapper.getEKK0341B002(param, fixedText, resMap)` // Get result list |
| 9 | CALL | `mapper.scResultCheck(param)` // Validate SC result |

**Block G2** — [FOR/IF] Iterate device-contract results and fetch agreement details (L602-620)

| # | Type | Code |
|---|------|------|
| 1 | IF | `kk0341_b002_map_list != null` (L601) |
| 1.1 | FOR | `for (HashMap kk0341_b002_map : kk0341_b002_map_list)` |
| 1.1.1 | SET | `condMap.put(JKKAdchgMapperCC.COND_KEY_KKTK_SVC_KEI_NO, getMapString(kk0341_b002_map, EKK0341A010CBSMsg1List.KKTK_SVC_KEI_NO))` // Extract and set service contract number from each device record |
| 1.1.2 | SET | `condMap.put(JKKAdchgMapperCC.COND_KEY_OPEDATE, JCCBPCommon.getOpeDate(null))` // Set operation date |
| 1.1.3 | CALL | `reqMap = mapper.setEKK0341A010(param, fixedText, condMap)` // Build SC EKK0341A010 request |
| 1.1.4 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` // Execute SC EKK0341A010 (device-contract agreement) |
| 1.1.5 | CALL | `kk0341_a010_map = mapper.getEKK0341A010(param, fixedText, resMap)` // Get single agreement record |
| 1.1.6 | CALL | `mapper.scResultCheck(param)` // Validate SC result |
| 1.1.7 | SET | `kikiInfoList.add(kk0341_a010_map)` // Add agreement detail to result list |
| 1.2 | RETURN | `return kikiInfoList` // Return populated device info list |

### Nested Method: kikiStateCheck — Device state validation

**Block K1** — [FOR/IF] Check device states in the list (L829-839)

| # | Type | Code |
|---|------|------|
| 1 | FOR | `for (int i = 0; i < chkKikiList.size(); i++)` // Iterate each device record |
| 1.1 | SET | `chkKikiMap = chkKikiList.get(i)` // Get device record at index i |
| 1.2 | SET | `kikiState = (String) chkKikiMap.get(EKK0341A010CBSMsg1List.KKTK_SVC_KEI_STAT)` // Get device state code |
| 1.3 | IF | `"010".equals(kikiState) \|\| "020".equals(kikiState) \|\| "030".equals(kikiState)` [-> Active/Pending states that block address change] (L833) |
| 1.3.1 | RETURN | `return false` // Device in active state — check fails |
| 1.4 | RETURN | `return true` // All devices in allowed states (not 010/020/030) |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `svcKeiNo_Net` | Field | Internet service contract number — the service line identifier for broadband (Net) service associated with a customer |
| `svcKeiNo_Tel` | Field | Telephone service contract number — the service line identifier for voice/telephone service |
| `svcKeiNo_Tv` | Field | Television service contract number — the service line identifier for TV/broadcast service |
| `kikiState` | Field | Device state code — indicates the current operational state of a device/contract (010, 020, 030 = active/pending states that block address change) |
| `KKTK_SVC_KEI_STAT` | Field | Device service contract status — the database field in EKK0341A010CBSMsg1List containing the device state code |
| `KKTK_SVC_KEI_NO` | Field | Device service contract number — the service contract number stored in device-contract agreement records |
| `check_result` | Field | Check result indicator — set to "1" (CHECK_OK) if all device checks pass, or "0" (CHECK_ERR) if any fail |
| `chkflg` | Field | Check flag — internal boolean used for short-circuit evaluation; once set to false by a failed branch, remaining service lines are skipped |
| `funcCode` | Field | Function code parameter — passed as `"6"` to `getKikiInfo` since OM-2014-0001369 to specify the query mode for device-contract info retrieval |
| CHECK_OK | Constant | Check OK value: `"1"` (defined in JKKAdchgCheckerCC.java:73) |
| CHECK_ERR | Constant | Check Error value: `"0"` (defined in JKKAdchgCheckerCC.java:75) |
| `keepSesHandle` | Field | Thread-local session handle storage — preserves the database session context across the call chain for SC invocations |
| EKK0341B002 | SC Code | Device-contract list inquiry by service contract number — fetches all devices associated with a given service contract |
| EKK0341A010 | SC Code | Device-contract agreement inquiry — fetches detailed agreement record for a specific device/service contract |
| KK_T_EKKTK_D | Entity/DB | Device-contract master table — stores device-to-service-contract relationships in the K-Opticom database |
| KKSV0698 | Screen | Address-change confirmation screen — the BPM-based operation screen that invokes this method for pre-registration validation |
| KKSV069806CC | CC Class | Screen-specific CC (Common Component) class that delegates to `kikiStateChecker` via CCRequestBroker |
| CCRequestBroker | Pattern | Request dispatch mechanism — allows remote invocation of CC methods with configurable target class, method name, and exception judgment |
| SC (Service Component) | Acronym | Service Component — the architectural layer that handles data access and business logic execution between CC and the database |
| CC (Common Component) | Acronym | Common Component — reusable business logic components in the K-Opticom architecture that screens invoke |
| OPEDATE | Field | Operation date — the business date used as a query condition for fetching contract records |
| OpeDate | Field | Operation date utility — obtained via `JCCBPCommon.getOpeDate(null)` as the current business processing date |
| ThreadLocal | Pattern | Java thread-scope variable — ensures the session handle is accessible only within the same thread, preventing cross-thread contamination |
