# Business Logic — JKKStbUcwkEoTvKktkSvcKeiCC.stbUcwkEoTvKktkSvcKei() [481 LOC]

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

## 1. Role

### JKKStbUcwkEoTvKktkSvcKeiCC.stbUcwkEoTvKktkSvcKei()

This method orchestrates the complete STB (Set-Top Box) modification workflow for Fujitsu's NTT Easteo optical television service. It receives a batch of STB change requests packaged inside a `fixedText` key's HashMap and processes three types of device operations — addition (01), exchange (02), and removal (03) — for each STB entry in the list.

The method performs a two-phase data validation flow before any actual device changes. First, it calls the EKK0791A010 service component to validate course codes (pcrs_cd / tv_pcrs_cd) and cross-checks whether the main service course group matches each STB's TV course group; if any mismatch is detected, a `course_grp_unmatch_flg` is set to "1" as a flag for downstream error handling. Second, it retrieves all currently active device provisioning service contracts via EKK0341B017 and indexes them by service detail work number, creating lookup maps for V-ONU, STB, BCAS, and CCAS devices.

The method dispatches device processing into four categories: (1) STB additions are collected into a list and processed by `JKKKikiAddCC.addKikiInfo`; (2) STB exchanges are commented out in current production code (the block is entirely commented, noting that course changes do not accept exchanges for non-V-ONU devices); (3) device removals (partial disconnections) are collected into a list and processed by `JKKKojiKikiUpdCC.updKojiKiki`, including associated BCAS/CCAS smart card removals; and (4) if the construction scope includes V-ONU change (kojiScope 220 or 230), the method checks whether an active V-ONU exists and either routes it to the exchange list or adds a new V-ONU to the addition list.

After all device lists are assembled, the method delegates to three component classes in sequence — `JKKKikiAddCC`, `JKKKikiChgCC`, and `JKKKojiKikiUpdCC` — each with their own work maps and parameters. If a new STB is added, it also executes the `execWrisvcAutoAply` method to handle automatic discounts for eo HIKARI TV service contract registration. This method serves as the central coordination hub between the BPM operation layer (KKSV0311/KKSV0312 screens) and the device-level CRUD component classes.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["stbUcwkEoTvKktkSvcKei"])

    START --> GET_DATA["Get inMap from param.getData(fixedText)"]
    GET_DATA --> CHECK_NULL{"inMap == null?"}
    CHECK_NULL -->|Yes| RETURN_PARAM["Return param"]
    CHECK_NULL -->|No| INIT_WORK["Set course_grp_unmatch_flg = 0"]

    INIT_WORK --> GET_SVC_CD["Get svcCourceCd from inMap pcrs_cd"]
    GET_SVC_CD --> CALL_EKK0791["Call SC EKK0791A010"]

    CALL_EKK0791 --> GET_GROUP["Get TV_COURSE_GRP_CD"]
    GET_GROUP --> GET_KIKI_LIST["Get kikiList from inMap"]

    GET_KIKI_LIST --> LOOP1_START{"Loop i < kikiList.size?"}
    LOOP1_START -->|Yes| GET_STB_DATA["Get stbdata from kikiList[i]"]
    GET_STB_DATA --> CHECK_TV_PCRS{"tv_pcrs_cd != null?"}
    CHECK_TV_PCRS -->|Yes| CALL_EKK0791_STB["Call SC EKK0791A010 with tv_pcrs_cd"]
    CALL_EKK0791_STB --> CHECK_MATCH{"course groups match?"}
    CHECK_MATCH -->|No| SET_UNMATCH["Set course_grp_unmatch_flg = 1"]
    CHECK_MATCH -->|Yes| NEXT1["i++"]
    SET_UNMATCH --> NEXT1
    CHECK_TV_PCRS -->|No| NEXT1
    NEXT1 --> LOOP1_START

    LOOP1_START -->|No| CHECK_FUNC{"func_code == 2?"}
    CHECK_FUNC -->|Yes| RETURN_CHECK["Return param"]
    CHECK_FUNC -->|No| GET_WORK_MAP["Get workMap from param"]

    GET_WORK_MAP --> CHECK_WORK{"workMap == null?"}
    CHECK_WORK -->|Yes| RETURN_WORK["Return param"]
    CHECK_WORK -->|No| GET_MSKM["Get mskmDtlNo from workMap"]

    GET_MSKM --> GET_WORK_DATA["Get WORK data from param"]
    GET_WORK_DATA --> CALL_EKK0341B["Call SC EKK0341B017"]

    CALL_EKK0341B --> BUILD_MAP["Build kikiXucwkMap"]
    BUILD_MAP --> INIT_LISTS["Init kikiAdd/Chg/RmvchildLists"]

    INIT_LISTS --> LOOP2_START{"Loop i < kikiList.size?"}
    LOOP2_START -->|Yes| GET_STB_IDO["Get stbIdoDiv from stbdata"]
    GET_STB_IDO --> CHECK_ADDIDO{"stbIdoDiv == 01 (ADD)?"}
    CHECK_ADDIDO -->|Yes| DO_ADD["Add to kikiAddchildList"]
    CHECK_ADDIDO -->|No| CHECK_CHGIDO{"stbIdoDiv == 02 (CHG)?"}
    CHECK_CHGIDO -->|Yes| DO_CHG["Commented out - skip CHG processing"]
    DO_CHG --> NEXT2["i++"]
    CHECK_CHGIDO -->|No| CHECK_RMVIDO{"stbIdoDiv == 03 (RMV)?"}
    CHECK_RMVIDO -->|Yes| DO_RMV["Call EKK0341A010 + EKK0161A010, add to kikiRmvchildList"]
    DO_RMV --> CHECK_BCASCAS{"Has BCAS/CCAS in ucwkMap?"}
    CHECK_BCASCAS -->|Yes| DO_BCASCAS["Process BCAS/CCAS removal"]
    DO_BCASCAS --> NEXT2
    CHECK_BCASCAS -->|No| NEXT2
    CHECK_RMVIDO -->|No| NEXT2
    NEXT2 --> LOOP2_START

    LOOP2_START -->|No| CHECK_KOJISCOPE{"kojiScope == 220 or 230?"}
    CHECK_KOJISCOPE -->|Yes| CHECK_VONU{"vONUdata != null?"}
    CHECK_VONU -->|Yes| CALL_EKK0341A_VONU["Call EKK0341A010 for V-ONU"]
    CHECK_VONU -->|No| NO_VONU["No V-ONU, add to kikiAddchildList"]
    CALL_EKK0341A_VONU --> CHECK_STAT{"KKTK_SVC_KEI_STAT == 100?"}
    CHECK_STAT -->|Yes| ADD_TO_CHG["Add V-ONU to kikiChgchildList"]
    CHECK_STAT -->|No| NO_STAT_VONU["No active V-ONU, add to kikiAddchildList"]
    ADD_TO_CHG --> DONE_VONU["Done V-ONU handling"]
    NO_STAT_VONU --> DONE_VONU
    NO_VONU --> DONE_VONU
    CHECK_KOJISCOPE -->|No| DONE_VONU

    DONE_VONU --> CHECK_ADD_LIST{"kikiAddchildList.size > 0?"}
    CHECK_ADD_LIST -->|Yes| CALL_KIKIADD["JKKKikiAddCC.addKikiInfo"]
    CALL_KIKIADD --> CHECK_IS_STB{"Added device is STB?"}
    CHECK_IS_STB -->|Yes| CALL_WRI["execWrisvcAutoAply"]
    CHECK_IS_STB -->|No| SKIP_WRI["Skip WRI discount"]
    CHECK_ADD_LIST -->|No| SKIP_ADD["Skip device addition"]
    SKIP_WRI --> CALL_CHK_LIST
    SKIP_ADD --> CALL_CHK_LIST

    CALL_CHK_LIST --> CHECK_CHG_LIST{"kikiChgchildList.size > 0?"}
    CHECK_CHG_LIST -->|Yes| CALL_KIKICHG["JKKKikiChgCC.chgKikiInfo"]
    CHECK_CHG_LIST -->|No| SKIP_CHG["Skip device change"]
    SKIP_CHG --> CALL_RMV_LIST

    CALL_RMV_LIST --> CHECK_RMV_LIST{"kikiRmvchildList.size > 0?"}
    CHECK_RMV_LIST -->|Yes| CALL_RMV["JKKKojiKikiUpdCC.updKojiKiki"]
    CHECK_RMV_LIST -->|No| SKIP_RMV["Skip device removal"]
    SKIP_RMV --> FINAL_RETURN["Return param"]
    CALL_RMV --> FINAL_RETURN
```

### Constant Resolution for Key Branches

| Constant | Actual Value | Business Meaning |
|----------|-------------|------------------|
| `KKTK_SVC_CD_VONU` | `"C013"` | Device provisioning service code for V-ONU (Fiber terminal device) |
| `KKTK_SVC_CD_STB` | `"C009"` | Device provisioning service code for STB (Set-Top Box) |
| `KKTK_SVC_CD_BCAS` | `"C010"` | Device provisioning service code for BCAS (View control card) |
| `KKTK_SVC_CD_CCAS` | `"C011"` | Device provisioning service code for CCAS (Conditional Access card) |
| `STB_IDO_DIV_ADD` | `"01"` | STB movement classification - Addition |
| `STB_IDO_DIV_CHG` | `"02"` | STB movement classification - Exchange |
| `STB_IDO_DIV_RMV` | `"03"` | STB movement classification - Removal (Partial Disconnection) |

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `handle` | `SessionHandle` | Business session handle used for all service component invocations. Carries user authentication context, transaction boundary, and locale information required when calling SCs (EKK0791A010, EKK0341B017, EKK0341A010, EKK0161A010, EKKA0020003). |
| 2 | `param` | `IRequestParameterReadWrite` | Business data input/output interface. Contains multiple data maps keyed by string names: `fixedText`-keyed HashMap (main input with func_code, pcrs_cd, svc_kei_no, kikiList, etc.), `WORK` data map (work area for timestamps), and `mappingWorkArea` (work mapping area with mskm_dtl_no, mskm_no, KK_COM_SVC_UP_DTM). Used as both input carrier and output accumulator throughout processing. |
| 3 | `fixedText` | `String` | User-defined string key that identifies which data map within `param` contains the main processing input. Acts as the map key for `param.getData(fixedText)` to retrieve the `inMap` containing func_code, course codes, service contract number, construction info, and the kikiList of STB changes. Also used as a key for `kojifixtext` retrieval in `setKojiRenkeiKikiData`. |

### Instance Fields / External State Read

| Field | Source | Business Description |
|-------|--------|---------------------|
| `TEMPLATE_ID_EKK0791A010` | Constant | Template ID for EKK0791A010 CBS (Device Provisioning Service Agreement Consultation) |
| `TEMPLATE_ID_EKK0341B017` | Constant | Template ID for EKK0341B017 CBS (Device Provisioning Service Agreement Consultation - Batch) |
| `TEMPLATE_ID_EKK0341A010` | Constant | Template ID for EKK0341A010 CBS (Device Provisioning Service Agreement Consultation - Addition) |
| `TEMPLATE_ID_EKK0161A010` | Constant | Template ID for EKK0161A010 CBS (Service Contract Detail Consultation) |

## 4. CRUD Operations / Called Services

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

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `EKK0791A010CBS` (via `callSC`) | `EKK0791A010` | Service agreement consultation table | Consults device provisioning service agreement for course group validation. Called twice: once for the main pcrs_cd, once per STB entry with tv_pcrs_cd. Returns TV_COURSE_GRP_CD for cross-group matching. |
| R | `EKK0341B017CBS` (via `callSC`) | `EKK0341B017` | Device provisioning service contract master, current service contract tables | Retrieves all current device provisioning service contracts for the given svc_kei_no. Returns device list including V-ONU, STB, BCAS, CCAS with their contract status, service detail work numbers, and model codes. Used to build the kikiXucwkMap lookup index. |
| R | `EKK0341A010CBS` (via `callSC`) | `EKK0341A010` | Device provisioning service agreement detail tables | Consults device provisioning service agreement detail. Called in two contexts: (1) during removal processing with func_code "2" to retrieve current device contract detail for build; (2) during V-ONU scope check with func_code "1" to query by KKTK_SVC_KEI_NO and GENE_ADD_DTM. Used to determine device status (KKTK_SVC_KEI_STAT) and build removal data. |
| R | `EKK0161A010CBS` (via `callSC`) | `EKK0161A010` | Service contract detail tables | Consults service contract detail to retrieve the TV course code (pcrs_cd) before device removal. Called after EKK0341A010 to obtain the previous TV service course for the removal target's service contract detail. |
| R | `EKKA0020003CBS` (via `callSC` in `setKojiRenkeiKikiData`) | `EKKA0020003` | Indoor equipment model/serial number mapping table | Consults indoor equipment matching to retrieve the STB-ID by device model code and serial number. Called only when the device is STB (kktk_svc_cd == "C009"). Used to populate stb_id and old_stb_id in construction linkage data. |
| C | `JKKKikiAddCC.addKikiInfo` | - | Device provisioning service contract tables, device master tables | Adds new devices (STB additions, V-ONU additions). Invoked when kikiAddchildList is non-empty. Receives func_code, construction info, svc_kei_no, ido_div, kojiak_no, msKm_dtl_no, and the full device list. Sets KK_COM_SVC_UP_DTM timestamp. |
| U | `JKKKikiChgCC.chgKikiInfo` | - | Device provisioning service contract tables, device detail tables | Changes/exchanges existing devices. Invoked when kikiChgchildList is non-empty. Receives func_code, construction info, svc_kei_no, ido_div, and the change device list. Sets mskm_dtl_no and work_upd_dtm. |
| U | `JKKKojiKikiUpdCC.updKojiKiki` | - | Device provisioning service contract tables, removal history tables | Removes/disconnects devices (partial disconnection processing). Invoked when kikiRmvchildList is non-empty. Receives func_code, construction info, and the full removal device list including STB, BCAS, CCAS. Sets mskm_dtl_no and KK_COM_SVC_UP_DTM. |
| - | `JKKStbUcwkEoTvKktkSvcKeiCC.execWrisvcAutoAply` | - | Discount/agreement tables | Executes automatic discount application for eo HIKARI TV service contract registration. Called only when a newly added device is STB type. |
| - | `JKKStbUcwkEoTvKktkSvcKeiCC.setKojiRenkeiKikiData` | - | Construction linkage output data | Sets construction linkage equipment data. Called during removal processing for each STB/BCAS/CCAS device. Queries STB-ID from indoor equipment matching. |
| - | `JKKStbUcwkEoTvKktkSvcKeiCC.callSC` | - | Service component invocation framework | Internal private method that wraps SC calls: builds CAANMsg input from param control data, invokes ServiceComponentRequestInvoker, handles error editing, and throws SCCallException on non-zero return codes. |
| - | `JKKStbUcwkEoTvKktkSvcKeiCC.debugLog` | - | Debug logging | Internal private method for emitting debug log messages (e.g., "Device addition - start", "Active ONU exists, V-ONU device change", "No active ONU, adding V-ONU device"). |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Screen:KKSV0311 | `KKSV0311OPOperation.targetf` -> `CCRequestBroker.invoke` -> `JKKStbUcwkEoTvKktkSvcKeiCC.stbUcwkEoTvKktkSvcKei` -> `EKK0791A010CBS [R] EKK0791A010 course_agreement` | `EKK0791A010CBS [R] course_agreement`, `EKK0341B017CBS [R] current_service_contracts`, `EKK0341A010CBS [R] device_agreement_detail`, `EKK0161A010CBS [R] service_contract_detail`, `EKKA0020003CBS [R] indoor_equipment_model`, `JKKKikiAddCC.addKikiInfo [C] device_contract`, `JKKKojiKikiUpdCC.updKojiKiki [U] device_removal`, `JKKKikiChgCC.chgKikiInfo [U] device_exchange` |
| 2 | Screen:KKSV0312 | `KKSV0312OPOperation.target1c` -> `CCRequestBroker.invoke` -> `JKKStbUcwkEoTvKktkSvcKeiCC.stbUcwkEoTvKktkSvcKei` -> `EKK0791A010CBS [R] EKK0791A010 course_agreement` | `EKK0791A010CBS [R] course_agreement`, `EKK0341B017CBS [R] current_service_contracts`, `EKK0341A010CBS [R] device_agreement_detail`, `EKK0161A010CBS [R] service_contract_detail`, `EKKA0020003CBS [R] indoor_equipment_model`, `JKKKikiAddCC.addKikiInfo [C] device_contract`, `JKKKojiKikiUpdCC.updKojiKiki [U] device_removal`, `JKKKikiChgCC.chgKikiInfo [U] device_exchange` |

## 6. Per-Branch Detail Blocks

**Block 1** — [IF] `(inMap == null)` (L130)

Early exit when the input data map is not found. The method cannot proceed without valid input data.

| # | Type | Code |
|---|------|------|
| 1 | SET | `inMap = (HashMap)(param.getData(fixedText))` // Retrieve main input map using fixedText as key |
| 2 | IF | `if (inMap == null)` [-> `inMap` is null, data not found under fixedText key] (L130) |
| 3 | RETURN | `return param` // Return immediately, no processing |

---

**Block 2** — [SET] `course_grp_unmatch_flg` initialization (L136)

Initialize the course group mismatch flag to "0" (normal/clear). This flag accumulates course group mismatch results across all STB entries.

| # | Type | Code |
|---|------|------|
| 1 | SET | `inMap.put("course_grp_unmatch_flg", "0")` // Initialize mismatch flag to 0 (normal) |
| 2 | SET | `svcCourceCd = (String) inMap.get("pcrs_cd")` // Get main service course code for validation |

---

**Block 3** — [CALL] `EKK0791A010CBS` — Initial course group validation (L140–L144)

Call the device provisioning service agreement consultation (EKK0791A010) to retrieve the course group code for the main service course. This establishes the baseline course group against which each STB's TV course group is compared.

| # | Type | Code |
|---|------|------|
| 1 | SET | `ekk0791a010IN = new CAANMsg(EKK0791A010CBSMsg.class.getName())` // Create input message |
| 2 | SET | `ekk0791a010IN.set(EKK0791A010CBSMsg.TEMPLATEID, TEMPLATE_ID_EKK0791A010)` |
| 3 | SET | `ekk0791a010IN.set(EKK0791A010CBSMsg.FUNC_CODE, "2")` // func_code "2" = consultation mode |
| 4 | SET | `ekk0791a010IN.set(EKK0791A010CBSMsg.KEY_PCRS_CD, svcCourceCd)` // Main service course code |
| 5 | SET | `ekk0791a010IN.set(EKK0791A010CBSMsg.KEY_RSV_APLY_YMD, JPCBPCommon.getOpeDate(null))` // Operation date |
| 6 | CALL | `callSC(handle, scCall, param, fixedText, ekk0791a010IN)` // Invoke SC EKK0791A010 |
| 7 | SET | `ekk0791a010cbsMsg1list = response.getCAANMsgList(EKK0791A010CBSMsg.EKK0791A010CBSMSG1LIST)` |

---

**Block 4** — [IF-ELSE] Main course group comparison loop (L156–L169)

Iterate over each STB entry in the kikiList. For each entry that has a tv_pcrs_cd set, call EKK0791A010 again to retrieve that STB's course group. If it differs from the main course group, set the mismatch flag.

| # | Type | Code |
|---|------|------|
| 1 | SET | `kikiList = (ArrayList) inMap.get("kikiList")` // Get STB device change list |
| 2 | LOOP | `for (int i = 0; i < kikiList.size(); i++)` // Iterate all STB entries |
| 3 | SET | `stbdata = (HashMap) kikiList.get(i)` |
| 4 | SET | `tvPcrsCd = (String) stbdata.get("tv_pcrs_cd")` |
| 5 | IF | `if (tvPcrsCd != null && !"".equals(tvPcrsCd))` (L159) |
| 6 | SET | `ekk0791a010IN_STB = new CAANMsg(...)` // New input for STB course check |
| 7 | SET | `ekk0791a010IN_STB.set(EKK0791A010CBSMsg.KEY_PCRS_CD, tvPcrsCd)` |
| 8 | CALL | `callSC(handle, scCall, param, fixedText, ekk0791a010IN_STB)` // SC EKK0791A010 |
| 9 | IF | `if (!svcCourceGroupCd.equals(response_tv.course_group))` (L167) |
| 10 | SET | `inMap.put("course_grp_unmatch_flg", "1")` // Set mismatch flag to 1 (error) |

---

**Block 5** — [IF] `func_code == "2"` (check-only mode) (L176)

When func_code is "2", this is a check-only invocation (no actual device changes). The course group validation loop above already runs, and the method returns early after setting the mismatch flag.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if ("2".equals(inMap.get("func_code")))` (L176) [func_code = "2" (Check Only)] |
| 2 | RETURN | `return param` // Check-only mode: return with mismatch flag set if any |

---

**Block 6** — [IF] `workMap == null` (L182)

Guard clause: the work mapping area must exist for the method to proceed with device change processing.

| # | Type | Code |
|---|------|------|
| 1 | SET | `workMap = (Map) param.getMappingWorkArea()` |
| 2 | IF | `if (workMap == null)` (L182) |
| 3 | RETURN | `return param` |

---

**Block 7** — [SET] `mskmDtlNo` and `WORK` data retrieval (L185–L187)

Extract the application detail number and work area data map. The mskmDtlNo is passed to device CRUD component classes for linkage.

| # | Type | Code |
|---|------|------|
| 1 | SET | `mskmDtlNo = (String) workMap.get("mskm_dtl_no")` // Application detail number |
| 2 | SET | `tmpWorkMap = (HashMap) param.getData("WORK")` // Work area for timestamp tracking |

---

**Block 8** — [CALL] `EKK0341B017CBS` — Retrieve current service contracts (L195–L201)

Call the device provisioning service agreement consultation (batch version) to get all currently active device service contracts. This is the foundational data for determining what devices exist and need to be added/exchanged/removed.

| # | Type | Code |
|---|------|------|
| 1 | SET | `ekk0341b017IN = new CAANMsg(EKK0341B017CBSMsg.class.getName())` |
| 2 | SET | `ekk0341b017IN.set(EKK0341B017CBSMsg.FUNC_CODE, inMap.get("func_code"))` // Pass through func_code |
| 3 | SET | `ekk0341b017IN.set(EKK0341B017CBSMsg.KEY_SVC_KEI_NO, inMap.get("svc_kei_no"))` // Service contract number |
| 4 | CALL | `callSC(handle, scCall, param, fixedText, ekk0341b017IN)` // SC EKK0341B017 |
| 5 | SET | `ekk0341b017cbsMsg1list = response.getCAANMsgList(EKK0341B017CBSMsg.EKK0341B017CBSMSG1LIST)` |

---

**Block 9** — [FOR] Build kikiXucwkMap — Current device index (L204–L220)

Iterate over the current device contracts from EKK0341B017 and categorize them: V-ONU devices go to vONUdata; STB/BCAS/CCAS devices are grouped by svcKeiUcwkNo into kikiXucwkMap for later matching during removal processing.

| # | Type | Code |
|---|------|------|
| 1 | SET | `vONUdata = null` // Current V-ONU device data |
| 2 | SET | `kikiXucwkMap = new HashMap<String, HashMap<String, CAANMsg>>()` // Device index |
| 3 | LOOP | `for (int i = 0; i < ekk0341b017cbsMsg1list.length; i++)` |
| 4 | SET | `kktkSbtCd = ekk0341b017cbsMsg1list[i].getString(CUR_KKTK_SVC_CD)` |
| 5 | IF | `if (KKTK_SVC_CD_VONU.equals(kktkSbtCd))` [C013 = V-ONU] (L211) |
| 6 | SET | `vONUdata = ekk0341b017cbsMsg1list[i]` // Hold V-ONU for V-ONU scope processing |
| 7 | SET | `continue` |
| 8 | ELSE-IF | `else if (KKTK_SVC_CD_STB || KKTK_SVC_CD_BCAS || KKTK_SVC_CD_CCAS)` [C009=C011] (L215) |
| 9 | SET | `svcKeiUcwkNo = ...getString(CUR_SVC_KEI_UCWK_NO)` |
| 10 | IF | `if (!kikiXucwkMap.containsKey(svcKeiUcwkNo))` |
| 11 | SET | `kikiXucwkMap.put(svcKeiUcwkNo, new HashMap<String, CAANMsg>())` |
| 12 | SET | `kikiXucwkMap.get(svcKeiUcwkNo).put(kktkSbtCd, ekk0341b017cbsMsg1list[i])` |

---

**Block 10** — [FOR] Device change processing loop (L223–L327)

Main processing loop: iterate over each STB entry in kikiList and categorize into addition, exchange (commented out), or removal child lists based on stbIdoDiv.

| # | Type | Code |
|---|------|------|
| 1 | SET | `kikiAddchildList = new ArrayList<>()` // For STB additions |
| 2 | SET | `kikiChgchildList = new ArrayList<>()` // For device exchanges (currently empty) |
| 3 | SET | `kikiRmvchildList = new ArrayList<>()` // For device removals |
| 4 | LOOP | `for (int i = 0; i < kikiList.size(); i++)` |
| 5 | SET | `stbdata = (HashMap) kikiList.get(i)` |
| 6 | SET | `stbIdoDiv = (String) stbdata.get("stb_ido_div")` |

**Block 10.1** — [IF] `stbIdoDiv == "01"` (ADD) (L248)

Process STB addition. Build a HashMap with STB device details including model code, sales subtype, HDD capacity, TV course code, and set haiso_way_cd to "2" (delivery method). Set taknkiki_ido_cd to the addition movement code.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if (STB_IDO_DIV_ADD.equals(stbIdoDiv))` [-> "01"] (L248) |
| 2 | SET | `mp = new HashMap<>()` |
| 3 | SET | `mp.put("kktk_svc_cd", KKTK_SVC_CD_STB)` [-> "C009"] |
| 4 | SET | `mp.put("haiso_way_cd", "2")` // Delivery method code |
| 5 | SET | `mp.put("sechi_ruta_cd", "")` // Empty since STB-only, no installation route |
| 6 | SET | `mp.put("taknkiki_ido_cd", stbIdoDiv)` |
| 7 | SET | `mp.put("taknkiki_model_cd", stbdata.get("taknkiki_model_cd"))` |
| 8 | SET | `mp.put("hambai_sbt_cd", stbdata.get("hambai_sbt_cd"))` |
| 9 | SET | `mp.put("stb_sbt_cd", stbdata.get("stb_sbt_cd"))` |
| 10 | SET | `mp.put("hdd_capa_cd", stbdata.get("hdd_capa_cd"))` |
| 11 | SET | `mp.put("tv_pcrs_cd", stbdata.get("tv_pcrs_cd"))` |
| 12 | SET | `kikiAddchildList.add(mp)` |

**Block 10.2** — [ELSE-IF] `stbIdoDiv == "02"` (CHG) (L258)

Device exchange processing. **Entirely commented out in current code.** A comment states: "Course changes do not accept exchanges for non-V-ONU devices." The commented code block contains a full implementation calling EKK0341A010, EKK0161A010, building exchange data, and invoking setKojiRenkeiKikiData for BCAS/CCAS linkage.

| # | Type | Code |
|---|------|------|
| 1 | ELSE-IF | `else if (STB_IDO_DIV_CHG.equals(stbIdoDiv))` [-> "02"] (L258) |
| 2 | COMMENT | "// Course changes do not accept exchanges for non-V-ONU devices" |
| 3–45 | COMMENT | Entire exchange implementation commented out (EKK0341A010, EKK0161A010, setKojiRenkeiKikiData calls, BCAS/CCAS handling) |

**Block 10.3** — [ELSE-IF] `stbIdoDiv == "03"` (RMV) (L306)

Partial disconnection / device removal. Calls EKK0341A010 (func_code "2") to get current device contract detail, then EKK0161A010 to get the pre-removal TV course code. Builds comprehensive removal data map with 25+ fields including service contract numbers, device serial numbers, model codes, operator dates, and penalty information.

| # | Type | Code |
|---|------|------|
| 1 | ELSE-IF | `else if (STB_IDO_DIV_RMV.equals(stbdata.get("stb_ido_div")))` [-> "03"] (L306) |
| 2 | SET | `ekk0341a010IN = new CAANMsg(...)` // func_code "2" |
| 3 | SET | `ekk0341a010IN.set(KEY_KKTK_SVC_KEI_NO, stbdata.get("kktk_svc_kei_no"))` |
| 4 | CALL | `callSC(..., ekk0341a010IN)` // SC EKK0341A010 |
| 5 | SET | `ekk0161a010IN = new CAANMsg(...)` |
| 6 | SET | `ekk0161a010IN.set(KEY_SVC_KEI_UCWK_NO, ekk0341a010cbsMsg1list[0].getString(SVC_KEI_UCWK_NO))` |
| 7 | CALL | `callSC(..., ekk0161a010IN)` // SC EKK0161A010 |
| 8 | SET | `tvCourceCd = ekk0161a010cbsMsg1list[0].getString(PCRS_CD)` |
| 9–30 | SET | Build `mp` with removal data: kktk_svc_cd, newTaknkikiIdo, oldTaknkikiIdo, svc_endymd, pnlty_hassei_cd, ido_div, hmpin_uk_ymd, add_optnty_kei_ido_div, add_optnty_kei_ido_dtm, load_oya_svkei_no, svc_chrg_endymd, kaihk_ymd, rsv_aply_ymd, svc_kei_ucwk_no, kktk_svc_kei_no, kktk_sbt_cd, kiki_seizo_no, taknkiki_model, taknkiki_sbt_cd, kktk_upd_dtm, svc_kei_ucwk_upd_dtm, gene_add_dtm, stb_id, bcas_id, ccas_id |
| 31 | SET | `kikiRmvchildList.add(mp)` |
| 32 | CALL | `setKojiRenkeiKikiData(handle, param, fixedText, scCall, ekk0341a010cbsMsg1list[0], stbIdoDiv, tvCourceCd)` |

**Block 10.3.1** — [IF] BCAS/CCAS associated device removal (L342–L400)

After the STB removal, iterate through associated BCAS/CCAS devices in the ucwkKikiList. For each, call EKK0341A010 (func_code "1") to retrieve current contract detail, build BCAS/CCAS removal data, add to kikiRmvchildList, and set construction linkage data.

| # | Type | Code |
|---|------|------|
| 1 | SET | `ucwkKikiList = kikiXucwkMap.get(ekk0341a010cbsMsg1list[0].getString(SVC_KEI_UCWK_NO))` |
| 2 | IF | `if (ucwkKikiList != null)` (L344) |
| 3 | LOOP | `Iterator<String> it = ucwkKikiList.keySet().iterator()` |
| 4 | SET | `key = it.next()` |
| 5 | SET | `kktkSbtCd = ucwkKikiList.get(key).getString(CUR_KKTK_SVC_CD)` |
| 6 | IF | `if (KKTK_SVC_CD_BCAS.equals(kktkSbtCd) || KKTK_SVC_CD_CCAS.equals(kktkSbtCd))` [C010 or C011] (L349) |
| 7 | CALL | `callSC(...)` // SC EKK0341A010 with func_code "1" |
| 8–24 | SET | Build `casCardMp` with BCAS/CCAS removal data (same fields as STB removal) |
| 25 | SET | `kikiRmvchildList.add(casCardMp)` |
| 26 | CALL | `setKojiRenkeiKikiData(handle, param, fixedText, scCall, ekk0341a010cbsMsg1list_cas[0], stbIdoDiv, "")` |

---

**Block 11** — [IF] V-ONU scope check (kojiScope 220 or 230) (L405–L441)

When the construction scope includes V-ONU change (220 = V-ONU change, 230 = V-ONU change with additional scope), check if an active V-ONU exists in the current contracts. If the V-ONU is in service (status 100), route it to the exchange list; otherwise add a new V-ONU to the addition list.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if ("220".equals(inMap.get("kojiScope")) || "230".equals(inMap.get("kojiScope")))` (L405) |
| 2 | IF | `if (vONUdata != null)` (L411) |
| 3 | SET | `ekk0341a010IN.set(FUNC_CODE, "1")` // func_code "1" = query mode for V-ONU |
| 4 | SET | `ekk0341a010IN.set(KEY_KKTK_SVC_KEI_NO, vONUdata.getString(CUR_KKTK_SVC_KEI_NO))` |
| 5 | SET | `ekk0341a010IN.set(KEY_GENE_ADD_DTM, vONUdata.getString(CUR_KK0341_GENE_ADD_DTM))` |
| 6 | CALL | `callSC(...)` // SC EKK0341A010 for V-ONU |
| 7 | IF | `if (vONUdata != null && "100".equals(ekk0341a010cbsMsg1list[0].getString(KKTK_SVC_KEI_STAT)))` (L418) [100 = Service Provision in Progress] |
| 8 | CALL | `debugLog("Active ONU exists, V-ONU device change")` |
| 9 | SET | Build `mp` with: kktk_svc_kei_no, kktk_gene_add_dtm, kktk_sbt_cd, course_changed = "1" |
| 10 | SET | `kikiChgchildList.add(mp)` |
| 11 | ELSE | `else` (No active V-ONU exists) |
| 12 | CALL | `debugLog("No active ONU, adding V-ONU device")` |
| 13 | SET | `mp.put("haiso_way_cd", "2")` |
| 14 | SET | `mp.put("kktk_svc_cd", KKTK_SVC_CD_VONU)` [-> "C013"] |
| 15 | SET | `kikiAddchildList.add(mp)` |

---

**Block 12** — [IF] `kikiAddchildList.size > 0` — Device Addition (L443–L477)

When STB or V-ONU additions exist, invoke `JKKKikiAddCC.addKikiInfo` to perform the actual device addition. Before calling, set the work update timestamp in the mapping work area. After the addition, if the added device is an STB, execute `execWrisvcAutoAply` to handle automatic discount registration for eo HIKARI TV service contract.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if (kikiAddchildList.size() > 0)` (L443) |
| 2 | CALL | `debugLog("Device addition - start")` |
| 3 | SET | `param.getMappingWorkArea().put("KK_COM_SVC_UP_DTM", tmpWorkMap.get("work_upd_dtm"))` |
| 4 | SET | `kikiAddCC = new JKKKikiAddCC()` |
| 5 | SET | `kikiAddCCMap.put("func_code", inMap.get("func_code"))` |
| 6 | SET | `kikiAddCCMap.put("kojifixtext", inMap.get("kojifixtext"))` |
| 7 | SET | `kikiAddCCMap.put("svc_kei_no", inMap.get("svc_kei_no"))` |
| 8 | SET | `kikiAddCCMap.put("stdardymd", JPCBPCommon.getOpeDate(null))` |
| 9 | SET | `kikiAddCCMap.put("ido_div", inMap.get("ido_div"))` |
| 10 | SET | `kikiAddCCMap.put("kojiAkNo", inMap.get("kojiak_no"))` |
| 11 | SET | `kikiAddCCMap.put("kiki_list", kikiAddchildList)` |
| 12 | SET | `kikiAddCCMap.put("mskm_dtl_no", mskmDtlNo)` |
| 13 | CALL | `kikiAddCC.addKikiInfo(handle, param, "kikiAddCC")` |
| 14 | IF | `if (KKTK_SVC_CD_STB.equals((String) kikimap.get("kktk_svc_cd")))` [C009 = STB] (L467) |
| 15 | CALL | `execWrisvcAutoAply(handle, param, inMap, (String) workMap.get("mskm_no"))` // Automatic discount |
| 16 | SET | `param.removeData("kikiAddCC")` |
| 17 | CALL | `debugLog("Device addition - complete")` |
| 18 | SET | `tmpWorkMap.put("work_upd_dtm", param.getMappingWorkArea().get("KK_COM_SVC_UP_DTM"))` |

---

**Block 13** — [IF] `kikiChgchildList.size > 0` — Device Change (L479–L497)

When device changes exist, invoke `JKKKikiChgCC.chgKikiInfo`. Sets mskm_dtl_no, construction info, update timestamp, and device change list. Note: in current code, kikiChgchildList is only populated from V-ONU scope processing, not from STB exchange processing (which is commented out).

| # | Type | Code |
|---|------|------|
| 1 | IF | `if (kikiChgchildList.size() > 0)` (L479) |
| 2 | SET | `param.getMappingWorkArea().put("mskm_dtl_no", mskmDtlNo)` |
| 3 | CALL | `debugLog("Device change - start")` |
| 4 | SET | `kikiChgCC = new JKKKikiChgCC()` |
| 5 | SET | `kikiChgCCMap.put("kojifixtext", inMap.get("kojifixtext"))` |
| 6 | SET | `kikiChgCCMap.put("upd_dtm", tmpWorkMap.get("work_upd_dtm"))` |
| 7 | SET | `kikiChgCCMap.put("key_svc_kei_no", inMap.get("svc_kei_no"))` |
| 8 | SET | `kikiChgCCMap.put("func_code", inMap.get("func_code"))` |
| 9 | SET | `kikiChgCCMap.put("ido_div", inMap.get("ido_div"))` |
| 10 | SET | `kikiChgCCMap.put("chg_kiki_list", kikiChgchildList)` |
| 11 | CALL | `kikiChgCC.chgKikiInfo(handle, param, "kikiChgCC")` |
| 12 | SET | `param.removeData("kikiChgCC")` |
| 13 | CALL | `debugLog("Device change - complete")` |
| 14 | SET | `tmpWorkMap.put("work_upd_dtm", param.getMappingWorkArea().get("KK_COM_SVC_UP_DTM"))` |

---

**Block 14** — [IF] `kikiRmvchildList.size > 0` — Device Removal (L499–L523)

When device removals exist, invoke `JKKKojiKikiUpdCC.updKojiKiki`. Sets mskm_dtl_no, update timestamp, func_code, construction info, and the full removal device list (STB + BCAS + CCAS). Includes a comment noting that `sendWctrTekkyoOrder` for view control removal orders is commented out because the WC service IF does not support multiple documents. Also notes that `addIchijikin` (one-time fee registration) was removed in v6.00.00.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if (kikiRmvchildList.size() > 0)` (L499) |
| 2 | SET | `param.getMappingWorkArea().put("mskm_dtl_no", mskmDtlNo)` |
| 3 | SET | `param.getMappingWorkArea().put("KK_COM_SVC_UP_DTM", tmpWorkMap.get("work_upd_dtm"))` |
| 4 | CALL | `debugLog("Device removal - start")` |
| 5 | SET | `kojiKikiUpdCC = new JKKKojiKikiUpdCC()` |
| 6 | SET | `kikiRmvCCMap.put("func_code", inMap.get("func_code"))` |
| 7 | SET | `kikiRmvCCMap.put("kojifixtext", inMap.get("kojifixtext"))` |
| 8 | SET | `kikiRmvCCMap.put("kktkSvcList", kikiRmvchildList)` |
| 9 | CALL | `kojiKikiUpdCC.updKojiKiki(handle, param, "kikiRmvCC")` |
| 10 | SET | `param.removeData("kikiRmvCC")` |
| 11 | CALL | `debugLog("Device removal - complete")` |
| 12 | SET | `tmpWorkMap.put("work_upd_dtm", param.getMappingWorkArea().get("KK_COM_SVC_UP_DTM"))` |

---

**Block 15** — [RETURN] Final return (L525)

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return param` // Return the parameter object with all modifications applied |

---

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `func_code` | Field | Function code — classifies the operation type. "2" means check-only consultation mode (no device changes performed); other values trigger full processing. |
| `pcrs_cd` | Field | Service course code — the main optical television service plan/course code for the customer's service contract. |
| `tv_pcrs_cd` | Field | Post-change TV service course code — the TV course code after an STB change. Used to validate course group compatibility. |
| `svc_kei_no` | Field | Service contract number — unique identifier for the customer's service contract line. |
| `ido_div` | Field | Movement classification — the type of service change (e.g., new subscription, modification, disconnection). |
| `kojiScope` | Field | Construction scope code — defines what hardware changes are included in the work order. "220" = V-ONU change; "230" = V-ONU change with additional scope. |
| `kojiak_no` | Field | Construction case number — unique identifier for the construction/work order case. |
| `kikiList` | Field | Device list — ArrayList of STB change requests, each containing device-specific fields (hambai_sbt_cd, hdd_capa_cd, kktk_sbt_cd, stb_ido_div, taknkiki_model_cd, etc.). |
| `stb_ido_div` | Field | STB movement classification — "01" = Add, "02" = Exchange, "03" = Removal (Partial Disconnection). |
| `mskm_dtl_no` | Field | Application detail number — unique identifier for the specific application/detail record within a construction order. |
| `mskm_no` | Field | Application number — parent application identifier used for discount processing linkage. |
| `course_grp_unmatch_flg` | Field | Course group mismatch flag — "0" = all course groups match (normal); "1" = at least one STB's course group does not match the main course group (error condition). |
| `KKTK_SVC_CD_STB` | Constant | Device provisioning service code C009 — Set-Top Box. |
| `KKTK_SVC_CD_BCAS` | Constant | Device provisioning service code C010 — BCAS (Broadcast Content Access System) conditional access smart card. |
| `KKTK_SVC_CD_CCAS` | Constant | Device provisioning service code C011 — CCAS (Common Conditional Access System) conditional access smart card. |
| `KKTK_SVC_CD_VONU` | Constant | Device provisioning service code C013 — V-ONU (VDSL Optical Network Unit) — fiber termination device for the home. |
| `KKTK_SVC_KEI_STAT_100` | Constant | Device service contract status 100 — Service Provision in Progress. Indicates the device is actively providing service. |
| EKK0791A010 | SC Code | Device Provisioning Service Agreement Consultation — validates service course codes against device provisioning agreements, returns TV course group codes for cross-group matching. |
| EKK0341B017 | SC Code | Device Provisioning Service Agreement Consultation (Batch) — retrieves all currently active device service contracts for a given service contract number, including V-ONU, STB, BCAS, and CCAS devices. |
| EKK0341A010 | SC Code | Device Provisioning Service Agreement Consultation (Addition) — consults device service agreement detail. Used with func_code "1" to query by device contract number, or "2" to get current device contract info for removal/exchange. |
| EKK0161A010 | SC Code | Service Contract Detail Consultation — retrieves service contract detail including the TV course code (pcrs_cd) for a given service detail work number. Used to determine the pre-removal TV course. |
| EKKA0020003 | SC Code | Indoor Equipment Matching Consultation — matches indoor equipment model codes and serial numbers to retrieve STB IDs. |
| `haiso_way_cd` | Field | Delivery method code — "2" indicates delivery-based equipment provisioning (vs. on-site handover). |
| `sechi_ruta_cd` | Field | Installation route code — route identifier for equipment installation location. Empty for STB-only changes. |
| `taknkiki_ido_cd` | Field | Indoor equipment movement code — classifies how indoor equipment is being moved/changed. "09" = No movement change (used for BCAS during exchanges). |
| `taknkiki_model_cd` | Field | Indoor equipment model code — identifies the hardware model of the STB or other indoor device. |
| `kktk_sbt_cd` | Field | Device provision subtype code — classification of the type of device being provided. |
| `hambai_sbt_cd` | Field | Sales subtype code — classification of the sales channel/type for the device. |
| `stb_sbt_cd` | Field | STB subtype code — specific STB model variant code. |
| `hdd_capa_cd` | Field | HDD capacity code — hard drive capacity classification for STB models with storage. |
| `vONUdata` | Field | V-ONU device data — holds the current V-ONU contract record retrieved from EKK0341B017 for scope-based V-ONU processing. |
| `kikiXucwkMap` | Field | Device work area map — HashMap indexed by service detail work number (svcKeiUcwkNo), containing grouped STB/BCAS/CCAS device records for matching during removal processing. |
| V-ONU | Business term | VDSL Optical Network Unit — the fiber-to-the-home terminal device that converts optical signals to electrical signals for in-home network devices. |
| STB | Business term | Set-Top Box — customer premises equipment for decoding and displaying optical television broadcast signals. |
| BCAS | Business term | Broadcast Content Access System — Japan's proprietary conditional access smart card for TV broadcast content decryption and subscription management. |
| CCAS | Business term | Common Conditional Access System — standardized conditional access smart card for IPTV/Digital TV service content decryption. |
| eo HIKARI TV | Business term | NTT Easteo's fiber-optic broadband television service offering. |
| KK_COM_SVC_UP_DTM | Field | Key communication service update timestamp — shared work area field storing the latest operation timestamp across device CRUD component invocations. |
| JKKKikiAddCC | Class | Device Addition Component Class — handles creation of new device provisioning service contracts for STB and V-ONU additions. |
| JKKKikiChgCC | Class | Device Change Component Class — handles exchange/modification of existing device provisioning service contracts. |
| JKKKojiKikiUpdCC | Class | Construction Device Update Component Class — handles partial disconnection/removal of devices from service contracts. |
| execWrisvcAutoAply | Method | Executes automatic discount application for eo HIKARI TV service contract registration. Called when a new STB is added to apply eligible service discounts. |
| setKojiRenkeiKikiData | Method | Sets construction linkage equipment data for BCAS/CCAS devices during removal processing. Queries STB-ID from indoor equipment matching for linkage data. |
