# Business Logic — JKKKikiDslAddCC.judgeSodHakko() [75 LOC]

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

## 1. Role

### JKKKikiDslAddCC.judgeSodHakko()

This method determines whether a Service Order Data (SOD) can be issued (SOD hakko) for a multi-function router service contract. It performs an eligibility check by querying an external CBS (EKK1041B001) that retrieves order configuration data, then evaluates whether the latest registered SOD has been successfully sent while no deletion SOD remains outstanding. Only when this condition is met does the method return true, indicating that a new SOD issuance is permissible for multi-function router scenarios.

The method implements the delegation design pattern — it delegates the data retrieval to the CBS `EKK1041B001` via the internal `callSC` mechanism, and then performs in-memory sorting and evaluation of the returned data. It acts as a shared guard/utility method called from `addKikiDsl()`, which is invoked during the DSL (data service line) equipment addition workflow. The method ensures that SOD issuance is only attempted when the order state is consistent: the prior registered SOD was sent, and no deletion SOD has been sent yet (or at all).

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["judgeSodHakko(params)"])
    START --> EXTRACT["Extract kktkSvckeiNo, taknkikiModelCd, kikiSeizoNo from inMap"]
    EXTRACT --> BUILD["Build ekk1041b001InMsg with TEMPLATE_ID and FUNC_CODE"]
    BUILD --> CALLSC["callSC: invoke EKK1041B001 CBS (order config list inquiry)"]
    CALLSC --> CHECK_RESULT{"EKK1041B001 outMsgList
!= null and
not empty?"}
    CHECK_RESULT -->|No| RETURN_FALSE["resultFlg = false"]
    CHECK_RESULT -->|Yes| CREATE_LIST["Create ordSetNoList (ArrayList<String>)"]
    CREATE_LIST --> FOR_LOOP["For each msg: extract ODR_SET_NO into ordSetNoList"]
    FOR_LOOP --> SORT["Collections.sort(ordSetNoList)"]
    SORT --> REVERSE["Collections.reverse(ordSetNoList)"]
    REVERSE --> MAX_ORD["maxOrdSetNo = ordSetNoList.get(0)"]
    MAX_ORD --> SECOND_LOOP["For each msg: find first with ODR_SET_NO = maxOrdSetNo"]
    SECOND_LOOP --> CHECK_MAX{"ordSetNo
equals maxOrdSetNo?"}
    CHECK_MAX -->|No| SECOND_LOOP_CONTINUE{More items?}
    CHECK_MAX -->|Yes| GET_ADD_SOD["get ADD_SOD_SEND_YMD"]
    GET_ADD_SOD --> GET_DEL_SOD["get DEL_SOD_SEND_YMD"]
    GET_DEL_SOD --> CHECK_SOD_SENT{"addSodSendYmd
not empty AND
delSodSendYmd
empty?"}
    CHECK_SOD_SENT -->|Yes| SET_TRUE["resultFlg = true
(multi-function router eligible)"]
    SET_TRUE --> BREAK["break"]
    CHECK_SOD_SENT -->|No| BREAK
    BREAK --> RETURN_RESULT["Return resultFlg"]
    SECOND_LOOP_CONTINUE -->|Yes| SECOND_LOOP
    SECOND_LOOP_CONTINUE -->|No| RETURN_FALSE
    RETURN_FALSE --> RETURN_RESULT
    RETURN_RESULT --> END(["End"])
    START --> EXTRACT
    EXTRACT --> BUILD
    BUILD --> CALLSC
    CALLSC --> CHECK_RESULT
    CHECK_RESULT -->|No| RETURN_FALSE
    CHECK_RESULT -->|Yes| CREATE_LIST
    CREATE_LIST --> FOR_LOOP
    FOR_LOOP --> SORT
    SORT --> REVERSE
    REVERSE --> MAX_ORD
    MAX_ORD --> SECOND_LOOP
    SECOND_LOOP --> CHECK_MAX
    CHECK_MAX -->|No| SECOND_LOOP_CONTINUE
    CHECK_MAX -->|Yes| GET_ADD_SOD
    GET_ADD_SOD --> GET_DEL_SOD
    GET_DEL_SOD --> CHECK_SOD_SENT
    CHECK_SOD_SENT -->|Yes| SET_TRUE
    SET_TRUE --> BREAK
    CHECK_SOD_SENT -->|No| BREAK
    BREAK --> RETURN_RESULT
    SECOND_LOOP_CONTINUE -->|Yes| SECOND_LOOP
    SECOND_LOOP_CONTINUE -->|No| RETURN_FALSE
    RETURN_FALSE --> RETURN_RESULT
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `handle` | `SessionHandle` | Database/transaction session handle providing the context for CBS calls. Carries the current session's connection and transaction state. |
| 2 | `param` | `IRequestParameterReadWrite` | Interface for business data acquisition and writing. Used as a parameter passed through to the `callSC` method during CBS invocation. |
| 3 | `fixedText` | `String` | Fixed text data used for CBS invocation. Likely contains template or configuration data passed through to the called service component. |
| 4 | `scCall` | `ServiceComponentRequestInvoker` | Service Component invocation mechanism. Provides the infrastructure to call the external CBS (EKK1041B001) and receive response messages. |
| 5 | `inMap` | `HashMap<String, Object>` | Input data map carrying key business identifiers extracted before calling this method. Contains: `kktk_svc_kei_no` (equipment-provided service contract number), `taknkiki_model_cd` (indoor equipment type code), and `kiki_seizo_no` (equipment serial number). |

## 4. CRUD Operations / Called Services

### Pre-computed evidence from code analysis graph:

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `callSC` (internal) | EKK1041B001 | KK_T_ODR_SET (KK1041) | Invokes CBS EKK1041B001 to query order configuration list data for the given service contract and equipment identifiers. Returns `CAANMsg[]` containing `ODR_SET_NO`, `ADD_SOD_SEND_YMD`, and `DEL_SOD_SEND_YMD` fields. |

### Method-level breakdown:

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `callSC` -> `EKK1041B001` CBS | EKK1041B001 | KK_T_ODR_SET (KK1041 table alias) | Reads order configuration records filtered by equipment-provided service contract number (`KEY_KKTK_SVC_KEI_NO`), indoor equipment type code (`KEY_TAKNKIKI_MODEL_CD`), and equipment serial number (`KEY_KIKI_SEIZO_NO`). FUNC_CODE="1" indicates the order config list inquiry function. Returns a list of order setup records. |

**How the CBS operates (inferred from `JSYejbEKK1041B001TPDA`):**
- The CBS reads from the `KK1041` table (alias for `KK_T_ODR_SET` or similar order setup table).
- It joins with `ZM0171_01` (master table for order type classification codes).
- The query returns `ODR_SET_NO` (order setup number), `ORDER_SBT_CD` (order type code), and `ADD_SOD_SEND_YMD` / `DEL_SOD_SEND_YMD` (SOD transmission dates).

## 5. Dependency Trace

### Pre-computed evidence from code analysis graph:

No screen/batch entry points found within 8 hops. Direct callers found: 1 methods.
Terminal operations from this method: `getString` [R], `getString` [R], `getString` [R], `getString` [R], `sort` [-], `sort` [-], `sort` [-], `sort` [-], `sort` [-], `getString` [R], `getString` [R], `getString` [R], `getString` [R], `getString` [R], `callSC` [R], `getString` [R], `getString` [R], `getString` [R], `getString` [R], `getString` [R]

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | CBS:JKKKikiDslAddCC.addKikiDsl() | `addKikiDsl()` -> `judgeSodHakko(handle, param, fixedText, scCall, inMap)` | `callSC [R] EKK1041B001 CBS` -> `KK_T_ODR_SET (KK1041)` |

**Terminal operations reached from this method:**
- `getString [R]` — Extracts `ODR_SET_NO`, `ADD_SOD_SEND_YMD`, `DEL_SOD_SEND_YMD` from `CAANMsg` response objects.
- `callSC [R]` — Invokes CBS `EKK1041B001` (order configuration list inquiry) against database table `KK_T_ODR_SET`.
- `sort [-]` — Sorts the order setup number list in ascending order (via `Collections.sort`), then reverses for descending order to get the maximum/latest order setup number.

## 6. Per-Branch Detail Blocks

**Block 1** — VARIABLE EXTRACTION (lines L2257–L2264)

> Extracts three business identifiers from the input map `inMap`. These identify the service contract and equipment for the order configuration inquiry.

| # | Type | Code |
|---|------|------|
| 1 | SET | `kktkSvckeiNo = (String) inMap.get("kktk_svc_kei_no")` // Equipment-provided service contract number [-> "kktk_svc_kei_no" maps to `KKTK_SVC_KEI_NO`] |
| 2 | SET | `taknkikiModelCd = (String) inMap.get("taknkiki_model_cd")` // Indoor equipment type code [-> "taknkiki_model_cd" maps to `TAKNKIKI_MODEL_CD`] |
| 3 | SET | `kikiSeizoNo = (String) inMap.get("kiki_seizo_no")` // Equipment serial number [-> "kiki_seizo_no" maps to `KIKI_SEIZO_NO`] |

**Block 2** — INPUT MESSAGE CONSTRUCTION (lines L2266–L2274)

> Builds the input message array for the CBS call. The template ID is resolved from constant `JKKHakkoSODConstCC.TEMPLATE_ID_EKK1041B001 = "EKK1041B001"`. FUNC_CODE is hardcoded to `"1"` (order configuration list inquiry function).

| # | Type | Code |
|---|------|------|
| 1 | SET | `ekk1041b001InMsg[][]` |
| 2 | SET | `{EKK1041B001CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK1041B001}` [-> `TEMPLATE_ID_EKK1041B001 = "EKK1041B001"`] |
| 3 | SET | `{EKK1041B001CBSMsg.FUNC_CODE, "1"}` // FUNC_CODE="1" = order config list inquiry |
| 4 | SET | `{EKK1041B001CBSMsg.KEY_KKTK_SVC_KEI_NO, kktkSvckeiNo}` |
| 5 | SET | `{EKK1041B001CBSMsg.KEY_TAKNKIKI_MODEL_CD, taknkikiModelCd}` |
| 6 | SET | `{EKK1041B001CBSMsg.KEY_KIKI_SEIZO_NO, kikiSeizoNo}` |

**Block 3** — SERVICE COMPONENT INVOCATION (lines L2276–L2277)

> Invokes the EKK1041B001 CBS via `callSC()`. This triggers a database query to retrieve order configuration records for the specified service contract and equipment. The result is a `CAANMsg[]` array of `EKK1041B001CBSMsg1List` records.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `ekk1041b001outMsgList = callSC(handle, scCall, param, fixedText, ekk1041b001InMsg).getCAANMsgList(EKK1041B001CBSMsg.EKK1041B001CBSMSG1LIST)` // Calls EKK1041B001 CBS |

**Block 4** — NULL/EMPTY CHECK (lines L2279–L2317) [Condition: `ekk1041b001outMsgList != null && ekk1041b001outMsgList.length != 0`]

> Checks whether the CBS returned at least one order configuration record. If no records are returned, the method returns `false` (SOD issuance not permitted).

**Block 4.1** — ELSE BRANCH (CBS returned no data, lines L2319)

> No explicit else branch — if the condition fails, execution falls through to `return resultFlg` which remains `false` (initialized at L2255).

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return resultFlg` [resultFlg = false, SOD issuance not permitted due to no order config data] |

**Block 4.2** — YES BRANCH (CBS returned data, lines L2281–L2317)

> CBS returned valid order configuration records. Proceed to extract and evaluate order setup numbers.

| # | Type | Code |
|---|------|------|
| 1 | SET | `ordSetNoList = new ArrayList<String>()` // Create list to hold order setup numbers |

**Block 4.2.1** — FOR LOOP: Extract ODR_SET_NO (lines L2283–L2286)

> Iterates over all returned CBS messages, extracting the `ODR_SET_NO` (order setup number) from each record into the `ordSetNoList`.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `for(int i = 0; i < ekk1041b001outMsgList.length; i++)` // Loop over CBS results |
| 2 | CALL | `ekk1041b001outMsgList[i].getString(EKK1041B001CBSMsg1List.ODR_SET_NO)` [-> field: `ODR_SET_NO` = "odr_set_no" = Order Setup Number] |
| 3 | EXEC | `ordSetNoList.add(...)` // Add extracted order setup number |

**Block 4.2.2** — SORT AND REVERSE (lines L2288–L2289)

> Sorts the order setup numbers in ascending order, then reverses to descending order. This places the latest (maximum) order setup number at index 0.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `Collections.sort(ordSetNoList)` // Ascending sort |
| 2 | EXEC | `Collections.reverse(ordSetNoList)` // Reverse to descending order (latest first) |

**Block 4.2.3** — EXTRACT MAX ORDER SETUP NUMBER (line L2291)

> Retrieves the first (maximum) order setup number from the sorted and reversed list.

| # | Type | Code |
|---|------|------|
| 1 | SET | `maxOrdSetNo = ordSetNoList.get(0)` // Latest order setup number (descending order = max first) |
| 2 | SET | `ordSetNo = ""` // Initialize for loop iteration |

**Block 4.2.4** — FOR LOOP: Find matching record and extract SOD dates (lines L2293–L2316)

> Iterates through the CBS messages again to find the record whose `ODR_SET_NO` matches the maximum order setup number. For that record, extracts the registration SOD and deletion SOD send dates.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `for(int i = 0; i < ekk1041b001outMsgList.length; i++)` // Loop over CBS results |
| 2 | SET | `ordSetNo = ekk1041b001outMsgList[i].getString(EKK1041B001CBSMsg1List.ODR_SET_NO)` |

**Block 4.2.4.1** — IF (lines L2295–L2316) [Condition: `ordSetNo.equals(maxOrdSetNo)`]

> Checks if the current record's order setup number matches the maximum. When found, extracts the SOD transmission dates.

| # | Type | Code |
|---|------|------|
| 1 | SET | `addSodSendYmd = ekk1041b001outMsgList[i].getString(EKK1041B001CBSMsg1List.ADD_SOD_SEND_YMD)` // Registered SOD send date [-> field: `ADD_SOD_SEND_YMD` = "add_sod_send_ymd" = Registration SOD transmission year/month/day] |
| 2 | SET | `delSodSendYmd = ekk1041b001outMsgList[i].getString(EKK1041B001CBSMsg1List.DEL_SOD_SEND_YMD)` // Deletion SOD send date [-> field: `DEL_SOD_SEND_YMD` = "del_sod_send_ymd" = Deletion SOD transmission year/month/day] |

**Block 4.2.4.1.1** — IF (lines L2304–L2307) [Condition: `!"\".equals(addSodSendYmd) && (delSodSendYmd == null || "".equals(delSodSendYmd))`]

> This is the core eligibility judgment. The condition checks:
> - `addSodSendYmd` is NOT empty (the registration SOD has been sent), AND
> - `delSodSendYmd` is NULL OR empty (the deletion SOD has NOT been sent)
>
> When both conditions hold, it means the registered SOD was transmitted but no deletion SOD was transmitted yet — indicating a valid state where a new SOD can be issued for multi-function router scenarios. The method sets `resultFlg = true` and breaks out of the loop.

| # | Type | Code |
|---|------|------|
| 1 | SET | `resultFlg = true` // Multi-function router eligible for SOD issuance |
| 2 | EXEC | `break` // Exit loop — found the matching latest record |

**Block 4.2.4.1.2** — ELSE BRANCH (lines L2315–L2316)

> The registration SOD was not sent or the deletion SOD was already sent. No eligibility change — `resultFlg` remains `false`.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `break` // Exit loop — found the record but SOD is not eligible |

**Block 5** — RETURN (line L2319)

> Returns the eligibility flag. `true` indicates that SOD issuance is permitted (registration SOD sent, deletion SOD not sent). `false` indicates SOD issuance is not permitted.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return resultFlg` // true = multi-function router eligible for new SOD; false = not eligible |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `kktk_svc_kei_no` | Field | Equipment-provided service contract number — the service contract identifier associated with equipment-provided (leased) service lines. |
| `taknkiki_model_cd` | Field | Indoor equipment type code — classification code for indoor/customer premises equipment model types. |
| `kiki_seizo_no` | Field | Equipment serial number — unique manufacturing serial number of the indoor equipment. |
| `odr_set_no` | Field | Order setup number — unique identifier for an order configuration record. Used to track the chronological sequence of order setup changes. |
| `add_sod_send_ymd` | Field | Registration SOD transmission date — the date (year/month/day) when the registration Service Order Data was transmitted. Empty/null means not yet sent. |
| `del_sod_send_ymd` | Field | Deletion SOD transmission date — the date (year/month/day) when the deletion Service Order Data was transmitted. Empty/null means not yet sent. |
| SOD | Acronym | Service Order Data — telecom order fulfillment document that records service activation/deactivation/changes. Used in NTT-East service provisioning workflows. |
| SOD hakko | Business term | SOD issuance — the process of generating and transmitting a Service Order Data document. "Hakko" (発行) means issuance/generation. |
| EKK1041B001 | CBS Code | Order configuration list inquiry CBS (Customer Business System). Retrieves order setup records for the specified service contract and equipment identifiers. FUNC_CODE="1" triggers the list inquiry function. |
| KKTK | Abbreviation | Equipment-provided (Kiki Teikyo) — refers to leased equipment provided by the service provider to the customer. |
| Multi-function router | Business term | A broadband router device supporting multiple functions (e.g., ADSL/FTTH modem, Wi-Fi router, IP phone). Eligible for special SOD issuance handling when the registration SOD was sent but no deletion SOD was sent. |
| `kk1041` | DB Table Alias | Table alias used in SQL for the order setup table (likely `KK_T_ODR_SET` or similar), containing order configuration records with SOD transmission status. |
| FUNC_CODE = "1" | Constant | Function code value indicating the "order configuration list inquiry" operation for EKK1041B001 CBS. |
| TEMPLATE_ID_EKK1041B001 | Constant | Template identifier "EKK1041B001" used for CBS message construction, defined in `JKKHakkoSODConstCC`. |
| CAANMsg | Technical | Fujitsu's message container class used for CBS input/output data exchange. Supports typed accessors like `getString()`. |
| `CALLSC` | Technical | Internal helper method in `JKKKikiDslAddCC` that invokes a CBS via `ServiceComponentRequestInvoker` and returns the response `CAANMsg[]`. |
