# Business Logic — JKKAdchgHakkoSODCC.courseChgeOdrCtrl() [706 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `com.fujitsu.futurity.bp.custom.common.JKKAdchgHakkoSODCC` |
| Layer | CC/Common Component — SOD (Service Order Data) issuance controller |
| Module | `common` (Package: `com.fujitsu.futurity.bp.custom.common`) |

## 1. Role

### JKKAdchgHakkoSODCC.courseChgeOdrCtrl()

This method performs **Course Change (Service Plan Change) Order Control Processing** for existing FTTH (Fiber To The Home) subscribers whose internet service plan is being modified. It is the core entry point for generating the sequence of Service Order Data (SOD) documents required to execute a course change — typically a bundle of registration, cancellation, and deletion orders for both FTTH authentication and optional equipment (BBR broadband router).

The method branches by **service state** into two distinct business scenarios:

- **Pre-Start Processing (svc_kei_stat = 010/020/030)**: The service has not yet started (received, confirmed, or contract-complete but not yet live). The method issues FTTH registration SOD (ODR_NAIYO_CD_101), followed by FTTH cancellation (ODR_NAIYO_CD_103) and FTTH deletion (ODR_NAIYO_CD_104) SODs. If equipment information is available, it handles BBR equipment return orders.

- **During Provision Processing (svc_kei_stat = 100)**: The service is already live and providing. The method similarly issues FTTH registration SOD, but additionally queries the operations agreement via `callEKK0351A010SC` to determine whether additional operation services (Multise dynamic, Multise static, Fixed Global IP Address) need to be registered or modified. Each operation service code triggers its own SOD issuance path.

The method implements the **routing/dispatch pattern**: it extracts data from the `sodMap`, validates the PC rate code against a whitelist of supported internet speeds (100M through 10G, including Netflix bundles and Mezon variants), and dispatches to the appropriate processing branch. It also maintains a **same transaction number (same_trn_no)** to prevent duplicate orders when multiple course changes reference the same service contract line.

## 2. Processing Pattern (Detailed Business Logic)

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

    START --> EXTRACT["Extract Maps from sodMap"]
    EXTRACT --> SANITIZE["Sanitize maps via shkkaMap"]
    SANITIZE --> EXTRACT_PARAMS["Extract service and equipment parameters"]

    EXTRACT_PARAMS --> CHK_PCRS{"PCRS code valid"}
    CHK_PCRS -- NO --> RETURN_PARAM["Return param as-is"]
    CHK_PCRS -- YES --> CHK_STAT{"svc_kei_stat"}

    CHK_STAT -- "Pre-Start" --> PRE_START["Before Start Processing"]
    CHK_STAT -- "During Provision" --> DURING_PROV["During Provision Processing"]

    PRE_START --> PRE_CHGJdg{"svc_kei_no changed"}
    PRE_CHGJdg -- YES --> PRE_SAME["getSame_trn_no"]
    PRE_CHGJdg -- NO --> POST_PROCESS

    PRE_SAME --> PRE_COND{"svc_kei_ucwk_no not blank"}
    PRE_COND -- YES --> PRE_FTTH_REG["FTTH Registration SOD ODR 101"]
    PRE_COND -- NO --> PRE_REG

    PRE_FTTH_REG --> PRE_CAN["FTTH Cancellation SOD ODR 103"]
    PRE_REG --> PRE_CAN

    PRE_CAN --> PRE_DEL["FTTH Deletion SOD ODR 104"]
    PRE_DEL --> PRE_EQUIP{"chaf_kktsvkei_no available"}

    PRE_EQUIP -- YES --> PRE_EQUIP_SET["Set kktk parameters jdgOdr163"]
    PRE_EQUIP -- NO --> POST_PROCESS

    PRE_EQUIP_SET --> PRE_EQUIP_CHG{"Equipment changed"}
    PRE_EQUIP_CHG -- YES --> PRE_RETURN_SOD["BBR Return SOD"]
    PRE_EQUIP_CHG -- NO --> POST_PROCESS

    DURING_PROV --> DURING_CHGJdg{"svc_kei_no changed"}
    DURING_CHGJdg -- YES --> DURING_SAME["getSame_trn_no"]
    DURING_CHGJdg -- NO --> POST_PROCESS

    DURING_SAME --> DURING_COND{"svc_kei_ucwk_no not blank"}
    DURING_COND -- YES --> DURING_FTTH_REG["FTTH Registration SOD ODR 101"]
    DURING_COND -- NO --> DURING_REG

    DURING_FTTH_REG --> DURING_OP{"chaf_opsvkei_no available"}
    DURING_REG --> DURING_OP

    DURING_OP -- YES --> DURING_OP_EXEC["callEKK0351A010SC"]
    DURING_OP -- NO --> DURING_EQUIP

    DURING_OP_EXEC --> DURING_OP_TYPE{"opSvcCd"}
    DURING_OP_TYPE -- "B015 Multise" --> DURING_MULTISE["Multise SODs ODR 142/144/162"]
    DURING_OP_TYPE -- "B004 FixIPAD" --> DURING_FIXIPAD["Fixed IP Add SOD ODR 152"]
    DURING_OP_TYPE -- Other --> DURING_EQUIP

    DURING_MULTISE --> DURING_EQUIP
    DURING_FIXIPAD --> DURING_EQUIP

    DURING_EQUIP -- YES --> DURING_EQUIP_SET["Set kktk parameters jdgOdr163"]
    DURING_EQUIP -- NO --> POST_PROCESS

    DURING_EQUIP_SET --> DURING_EQUIP_CHG{"Equipment changed"}
    DURING_EQUIP_CHG -- YES --> DURING_RETURN_SOD["BBR Return SOD"]
    DURING_EQUIP_CHG -- NO --> POST_PROCESS

    POST_PROCESS --> NET_ONLY{"chgSvcKeiJdg and ucwk blank"}
    NET_ONLY -- YES --> NET_SOD["hakkoCourseChgSOD Net-only Order"]
    NET_ONLY -- NO --> CHK_SAME
    NET_SOD --> CHK_SAME

    CHK_SAME{"same_trn_no blank"}
    CHK_SAME -- NO --> SET_MAE["Set mae_recode_ch_svc_kei_no"]
    CHK_SAME -- YES --> RETURN_PARAM

    SET_MAE --> RETURN_PARAM

    style START fill:#e1f5e1
    style RETURN_PARAM fill:#f5e1e1
```

**CRITICAL — Constant Resolution:**

| Constant | Actual Value | Business Meaning |
|----------|-------------|-----------------|
| `ODR_NAIYO_CD_101` | `"101"` | FTTH Authentication Registration |
| `ODR_NAIYO_CD_103` | `"103"` | FTTH Authentication Cancellation |
| `ODR_NAIYO_CD_104` | `"104"` | FTTH Authentication Deletion |
| `ODR_NAIYO_CD_142` | `"142"` | Multise (Dynamic) Registration |
| `ODR_NAIYO_CD_144` | `"144"` | Multise (Static) Registration |
| `ODR_NAIYO_CD_152` | `"152"` | Fixed Global IP Address Registration |
| `OP_SVC_CD_MLTISE` | `"B015"` | Operations Service Code: Multise |
| `OP_SVC_CD_FIXIPAD` | `"B004"` | Operations Service Code: Fixed Global IP Address |
| `SVC_KEI_STAT_010` | `"010"` | Service Contract Status: Received |
| `SVC_KEI_STAT_020` | `"020"` | Service Contract Status: Confirmed |
| `SVC_KEI_STAT_030` | `"030"` | Service Contract Status: Contract Complete |
| `SVC_KEI_STAT_100` | `"100"` | Service Contract Status: During Provision |

**PCRS Codes validated (whitelist — if none match, method returns early):**
100M, 100M_PRM, 1G, 1G_NETFLIX, 10G, 5G, SIMPLE_10G, SIMPLE_10G_NETFLIX, MEZON_100M, MEZON_100M_PRM, MEZON_1G, MEZON_1G_NETFLIX, MEZON_200M, MEZON_10G, MEZON_5G, MEZON_5G_NETFLIX, MEZON_10G_NETFLIX, MANS_GLB_MHIKARI, MANS_GLB_GHIKARI, MANS_GLB_10GHIKARI, 5G_NETFLIX, 10G_NETFLIX

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `handle` | `SessionHandle` | Session management handle carrying context such as user session, transaction state, and infrastructure connectivity. Used when delegating to called service methods. |
| 2 | `param` | `IRequestParameterReadWrite` | Request/response parameter object containing model groups and control maps. Acts as the carrier for work data (HAKKOSODCCWORKMAP), tracking information (same_trn_no), and returns modified service order data after each SOD issuance. |
| 3 | `fixedText` | `String` | User-defined arbitrary string passed through to the final course change SOD issuance (`hakkoCourseChgSOD`). Typically carries human-readable reference text for the order. |
| 4 | `sodMap` | `HashMap<String, Object>` | Central container holding all service order data sub-maps: service contract info (`SVC_KEI_INFO`), service contract detail info (`SVC_KEI_UCWK_INFO`), operations service contract info (`OPSVKEI_INFO`), and equipment-provided service contract info (`KKTSVKEI_INFO`). |

**Instance fields read by the method:**

| Field | Type | Business Description |
|-------|------|---------------------|
| `pcrs_cd` | `String` | PC rate code — identifies the internet service speed tier (100M, 1G, 10G, etc.). If not in the allowed list, processing aborts early. |
| `svc_kei_stat` | `String` | Service contract status code — determines whether the service is pre-start (010/020/030) or during provision (100), routing to distinct processing branches. |
| `same_trn_no` | `String` | Same transaction number — shared across related orders to prevent duplicate processing. If not blank, `mae_recode_ch_svc_kei_no` is set. |
| `svc_kei_ucwk_no` | `String[]` | Service contract detail number (instance field version). |
| `svc_kei_ucwk_gadtm` | `String[]` | Service contract detail registration timestamp (instance field version). |
| `kktk_svc_kei_no` | `String[]` | Equipment-provided service contract number. |
| `kktk_svc_kei_gadtm` | `String[]` | Equipment-provided service contract registration timestamp. |
| `old_vrsb_jdg_svc_dtl_cd` | `String` | Old VR (Version) identification judgment service detail code — used for tariff plan discrimination. |
| `op_svc_kei_no_mltise` | `String` | Operations service contract number (Multise). |
| `op_gadtm_mltise` | `String` | Operations service registration timestamp (Multise). |
| `op_svc_kei_no_fixipad` | `String` | Operations service contract number (Fixed Global IP Address). |
| `op_gadtm_fixipad` | `String` | Operations service registration timestamp (Fixed Global IP Address). |
| `mae_recode_ch_svc_kei_no` | `String[]` | Previous contract number record for service change — set when `same_trn_no` is not blank. |
| `pplan_cd` | `String` | Plan code — the current pricing/tariff plan associated with the service. |

## 4. CRUD Operations / Called Services

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| C | `JKKAdchgHakkoSODCC.addSOD` | - | SOD (Service Order Data) | Issues an FTTH authentication registration SOD (ODR 101), FTTH cancellation SOD (ODR 103), or FTTH deletion SOD (ODR 104). Called multiple times in the pre-start and during-provision branches. |
| R | `JKKAdchgHakkoSODCC.callEKK0351A010SC` | EKK0351A010SC | Operations Service Agreement Inquiry (EKK0351A010CBS) | Queries the operations service agreement details to determine the operations service code (opSvcCd) — identifies whether the customer has Multise (B015) or Fixed IP Address (B004) as an operation service. |
| R | `JKKAdchgHakkoSODCC.callEKK0351B002SC` | EKK0351B002SC | Operations Service Contract List Inquiry (EKK0351B002CBS) | Retrieves the list of operations service contracts linked to the service contract number to determine the operations service status (OP_SVC_KEI_STAT: 030 or 100). |
| R | `JKKAdchgHakkoSODCC.getNewPplanCd` | - | Pricing Plan Data | During-provision branch: retrieves the new tariff plan code for the service (used for old VR identification discrimination). |
| R | `JKKAdchgHakkoSODCC.getOldVrsbIdgSvcDtlCd` | - | Version Discrimination Data | During-provision operations service branch: retrieves the old version identification service detail code for tariff plan discrimination. |
| R | `JKKAdchgHakkoSODCC.getSame_trn_no` | - | Transaction Number Data | Retrieves a shared transaction number to prevent duplicate order processing across related course change orders. |
| - | `JKKAdchgHakkoSODCC.chgSvcKeiJdg` | - | Service Change Judgment | Determines whether the service contract number has changed compared to the previous order record. Gatekeeper for all order issuance. |
| C | `JKKAdchgHakkoSODCC.hakkoCourseChgSOD` | - | SOD (Service Order Data) | Final SOD issuance for net-only (subnet/sub-network) service plan changes when no service contract detail number exists. |
| - | `JKKAdchgHakkoSODCC.jdgOdr163` | - | Router Connection Information | Handles router (BBR) connection information change processing for FTTH equipment. |
| - | `JKKAdchgHakkoSODCC.shkkaMap` | - | Map Sanitization | Sanitizes/validates maps extracted from sodMap (null-check and type-safe transformation). |
| - | `JKKAdchgHakkoSODCC.isBlank` | - | Blank/null check utility | Checks whether a string value is null or empty. Used in the final net-only branch and same_trn_no check. |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | CBS: `JKKHakkoSODCC` | `JKKHakkoSODCC.hakkoOdrCtrl` -> (route by IDO_DIV_COURSECHG) -> `JKKAdchgHakkoSODCC.courseChgeOdrCtrl` | `addSOD [C] SOD`, `callEKK0351A010SC [R] EKK0351A010CBS`, `callEKK0351B002SC [R] EKK0351B002CBS`, `getSame_trn_no [R]`, `hakkoCourseChgSOD [C] SOD` |
| 2 | CBS: `JKKHakkoSODCC` | `JKKHakkoSODCC` (late call chain at L17030) -> prepares chgSodMap -> `courseChgeOdrCtrl(handle, param, fixedText, chgSodMap)` | `addSOD [C] SOD`, `callEKK0351A010SC [R] EKK0351A010CBS`, `callEKK0351B002SC [R] EKK0351B002CBS`, `getOldVrsbIdgSvcDtlCd [R]` |
| 3 | Internal: `JKKAdchgHakkoSODCC` | `JKKAdchgHakkoSODCC` (L23649) -> `keepSesHandle.get()` -> `courseChgeOdrCtrl(keepSesHandle.get(), param, fixedText, sodMap)` | Same as above — full SOD issuance chain |

**Notes:** The primary entry point is `JKKHakkoSODCC.hakkoOdrCtrl`, which acts as a central dispatcher routing by `ido_div` (action division code). When `ido_div` equals `IDO_DIV_COURSECHG`, the call is delegated to `courseChgeOdrCtrl` in this subclass. This method is a **subclass override** of the same-named method in the parent class `JKKHakkoSODCC`. The other caller (`JKKAdchgHakkoSODCC` at L23649) appears to be an internal retry/keep-session pattern.

## 6. Per-Branch Detail Blocks

### Block 1 — INIT (L8643)

Initialize service data extraction and sanitization.

| # | Type | Code |
|---|------|------|
| 1 | SET | `statusCode = 0` // Service interval execution status |
| 2 | SET | `chafEKK0351A010SCHash = null` // Post-change operations service contract agreement result hash |
| 3 | SET | `svc_kei_info_Map = (HashMap)sodMap.get(JKKHakkoSODConstCC.SVC_KEI_INFO)` // Service contract info |
| 4 | SET | `svc_kei_ucwk_info_Map = (HashMap)sodMap.get(JKKHakkoSODConstCC.SVC_KEI_UCWK_INFO)` // Service contract detail info |
| 5 | SET | `opsvkei_info_Map = (HashMap)sodMap.get(JKKHakkoSODConstCC.OPSVKEI_INFO)` // Operations service contract info |
| 6 | SET | `kktsvkei_info_Map = (HashMap)sodMap.get(JKKHakkoSODConstCC.KKTSVKEI_INFO)` // Equipment-provided service contract info |
| 7 | EXEC | `svc_kei_info_Map = shkkaMap(svc_kei_info_Map)` // Sanitize map |
| 8 | EXEC | `svc_kei_ucwk_info_Map = shkkaMap(svc_kei_ucwk_info_Map)` // Sanitize map |
| 9 | EXEC | `opsvkei_info_Map = shkkaMap(opsvkei_info_Map)` // Sanitize map |
| 10 | EXEC | `kktsvkei_info_Map = shkkaMap(kktsvkei_info_Map)` // Sanitize map |

### Block 2 — PARAM_EXTRACTION (L8664)

Extract course change required parameters from the sanitized maps.

| # | Type | Code |
|---|------|------|
| 1 | SET | `svc_kei_no = (String)svc_kei_info_Map.get(JKKHakkoSODConstCC.INFO_SVC_KEI_NO)` // Service contract number |
| 2 | SET | `svc_kei_ucwk_no = (String)svc_kei_ucwk_info_Map.get(JKKHakkoSODConstCC.INFO_SVC_KEI_UCWK_NO)` // Post-change service contract detail number |
| 3 | SET | `chbf_svc_kei_ucwk_gene_add_dtm = (String)svc_kei_ucwk_info_Map.get(JKKHakkoSODConstCC.INFO_CHBF_SVC_KEI_UCWK_GENE_ADD_DTM)` // Pre-change service contract detail registration datetime |
| 4 | SET | `chaf_svc_kei_ucwk_gene_add_dtm = (String)svc_kei_ucwk_info_Map.get(JKKHakkoSODConstCC.INFO_CHAF_SVC_KEI_UCWK_GENE_ADD_DTM)` // Post-change service contract detail registration datetime |
| 5 | SET | `chaf_opsvkei_no = (String)opsvkei_info_Map.get(JKKHakkoSODConstCC.INFO_CHAF_OPSVKEI_NO)` // Post-change operations service contract number |
| 6 | SET | `chaf_opsvkei_gene_add_dtm = (String)opsvkei_info_Map.get(JKKHakkoSODConstCC.INFO_CHAF_OPSVKEI_GENE_ADD_DTM)` // Post-change operations service contract registration datetime |
| 7 | SET | `chbf_kktsvkei_no = (String)kktsvkei_info_Map.get(JKKHakkoSODConstCC.INFO_CHBF_KKTSVKEI_NO)` // Pre-change equipment-provided service contract number |
| 8 | SET | `chbf_kktsvkei_gene_add_dtm = (String)kktsvkei_info_Map.get(JKKHakkoSODConstCC.INFO_CHBF_KKTSVKEI_GENE_ADD_DTM)` // Pre-change equipment-provided service contract registration datetime |
| 9 | SET | `chaf_kktsvkei_no = (String)kktsvkei_info_Map.get(JKKHakkoSODConstCC.INFO_CHAF_KKTSVKEI_NO)` // Post-change equipment-provided service contract number |
| 10 | SET | `chaf_kktsvkei_gene_add_dtm = (String)kktsvkei_info_Map.get(JKKHakkoSODConstCC.INFO_CHAF_KKTSVKEI_GENE_ADD_DTM)` // Post-change equipment-provided service contract registration datetime |

### Block 3 — IF [PCRS Code Whitelist Check] (L8687)

[PCRS_CD_X] Gate: verify the internet speed tier is a supported course change target. If the PCRS code does not match any whitelisted value, the method returns `param` as-is (no processing).

| # | Type | Code |
|---|------|------|
| 1 | IF | `!JKKHakkoSODConstCC.PCRS_CD_100M.equals(pcrs_cd)` |
| 2 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_100M_PRM.equals(pcrs_cd)` |
| 3 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_1G.equals(pcrs_cd)` |
| 4 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_100M_VPN.equals(pcrs_cd)` |
| 5 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_200M.equals(pcrs_cd)` |
| 6 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_10G.equals(pcrs_cd)` // IT2-2016-0000004 ADD |
| 7 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_5G.equals(pcrs_cd)` // ANK-3412-00-00 ADD |
| 8 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_SIMPLE_10G.equals(pcrs_cd)` // ANK-4468-00-00 ADD |
| 9 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_SIMPLE_10G_NETFLIX.equals(pcrs_cd)` // ANK-4468-00-00 ADD |
| 10 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_MEZON_100M.equals(pcrs_cd)` |
| 11 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_MEZON_100M_PRM.equals(pcrs_cd)` |
| 12 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_MEZON_1G.equals(pcrs_cd)` |
| 13 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_MEZON_200M.equals(pcrs_cd)` |
| 14 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_MEZON_10G.equals(pcrs_cd)` // IT2-2016-0000004 ADD |
| 15 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_MEZON_5G.equals(pcrs_cd)` // ANK-3412-00-00 ADD |
| 16 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_MANS_GLB_MHIKARI.equals(pcrs_cd)` // ST2-2012-0000981 |
| 17 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_MANS_GLB_GHIKARI.equals(pcrs_cd)` // ANK-3949-00-00 MOD |
| 18 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_MANS_GLB_10GHIKARI.equals(pcrs_cd)` // ANK-4493-00-00 ADD |
| 19 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_1G_NETFLIX.equals(pcrs_cd)` |
| 20 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_MEZON_1G_NETFLIX.equals(pcrs_cd)` |
| 21 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_5G_NETFLIX.equals(pcrs_cd)` |
| 22 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_MEZON_5G_NETFLIX.equals(pcrs_cd)` |
| 23 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_10G_NETFLIX.equals(pcrs_cd)` |
| 24 | IF | `&&!JKKHakkoSODConstCC.PCRS_CD_MEZON_10G_NETFLIX.equals(pcrs_cd)` |
| 25 | RETURN | `return param;` // Course change target outside scope, terminate |

### Block 4 — IF [svc_kei_stat = Pre-Start: 010/020/030] (L8696)

[svc_kei_stat = SVC_KEI_STAT_010/020/030] Before Start Processing: service not yet live. Issues FTTH registration, cancellation, and deletion SODs.

#### Block 4.1 — IF [chgSvcKeiJdg: service number changed] (L8700)

| # | Type | Code |
|---|------|------|
| 1 | IF | `chgSvcKeiJdg(svc_kei_no)` // Previous record and current record service numbers differ |
| 2 | SET | `sameTrnNo = new String[1]` |
| 3 | CALL | `getSame_trn_no(param, handle, null, sameTrnNo)` // Obtain same transaction number |
| 4 | SET | `this.same_trn_no = sameTrnNo[0]` |
| 5 | SET | `this.svc_kei_ucwk_no = new String[1]` |
| 6 | SET | `this.svc_kei_ucwk_gadtm = new String[1]` |

##### Block 4.1.1 — IF [svc_kei_ucwk_no not blank] (L8707)

FTTH Authentication Registration SOD for pre-start.

| # | Type | Code |
|---|------|------|
| 1 | IF | `null != svc_kei_ucwk_no && 0 < svc_kei_ucwk_no.length() && null != chaf_svc_kei_ucwk_gene_add_dtm && 0 < chaf_svc_kei_ucwk_gene_add_dtm.length()` |
| 2 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no` // Service contract detail number |
| 3 | SET | `this.svc_kei_ucwk_gadtm[0] = chaf_svc_kei_ucwk_gene_add_dtm` // Service contract detail registration datetime |
| 4 | SET | `this.old_vrsb_jdg_svc_dtl_cd = this.pplan_cd` // ANK-2765: Old VR identification — new tariff plan code (pre-start) |
| 5 | CALL | `addSOD(handle, param, ODR_NAIYO_CD_101="101")` // FTTH Authentication Registration SOD |

#### Block 4.2 — FTTH Cancellation and Deletion (L8723)

| # | Type | Code |
|---|------|------|
| 1 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no` |
| 2 | SET | `this.svc_kei_ucwk_gadtm[0] = chbf_svc_kei_ucwk_gene_add_dtm` |
| 3 | CALL | `addSOD(handle, param, ODR_NAIYO_CD_103="103")` // FTTH Authentication Cancellation SOD |
| 4 | CALL | `addSOD(handle, param, ODR_NAIYO_CD_104="104")` // FTTH Authentication Deletion SOD |

#### Block 4.3 — IF [chaf_kktsvkei_no available] (L8730)

[Equipment-provided service contract info available] BBR equipment handling.

| # | Type | Code |
|---|------|------|
| 1 | IF | `chaf_kktsvkei_no != null && chaf_kktsvkei_gene_add_dtm != null` |
| 2 | SET | `this.kktk_svc_kei_no[0] = chaf_kktsvkei_no` // Post-change equipment-provided service contract number |
| 3 | SET | `this.kktk_svc_kei_gadtm[0] = chaf_kktsvkei_gene_add_dtm` // Post-change equipment-provided service contract registration datetime |
| 4 | CALL | `jdgOdr163(handle, param, sodMap)` // ANK-77: Router connection information/change processing |

##### Block 4.3.1 — IF [Equipment changed] (L8745)

[Pre-change equipment number differs from post-change] BBR Return SOD.

| # | Type | Code |
|---|------|------|
| 1 | IF | `chbf_kktsvkei_no != null && !chbf_kktsvkei_no.equals(chaf_kktsvkei_no)` |
| 2 | SET | `this.kktk_svc_kei_no[0] = chbf_kktsvkei_no` // Pre-change equipment-provided service contract number |
| 3 | SET | `this.kktk_svc_kei_gadtm[0] = chbf_kktsvkei_gene_add_dtm` // Pre-change equipment-provided service contract registration datetime |
| 4 | // BBR Return SOD (commented out — `addSODBBRHmpin` was removed) | |

### Block 5 — ELSE IF [svc_kei_stat = During Provision: 100] (L8879)

[svc_kei_stat = SVC_KEI_STAT_100] During Provision Processing: service is already live. Issues FTTH registration SOD and additionally processes operations service agreements (Multise, Fixed IP Address).

#### Block 5.1 — IF [chgSvcKeiJdg: service number changed] (L8883)

| # | Type | Code |
|---|------|------|
| 1 | IF | `chgSvcKeiJdg(svc_kei_no)` |
| 2 | SET | `sameTrnNo = new String[1]` |
| 3 | CALL | `getSame_trn_no(param, handle, null, sameTrnNo)` // Obtain same transaction number |
| 4 | SET | `this.same_trn_no = sameTrnNo[0]` |
| 5 | SET | `this.svc_kei_ucwk_no = new String[1]` |
| 6 | SET | `this.svc_kei_ucwk_gadtm = new String[1]` |

##### Block 5.1.1 — IF [svc_kei_ucwk_no not blank] (L8890)

FTTH Authentication Registration SOD for during-provision (with new tariff plan lookup).

| # | Type | Code |
|---|------|------|
| 1 | IF | `null != svc_kei_ucwk_no && 0 < svc_kei_ucwk_no.length() && null != chaf_svc_kei_ucwk_gene_add_dtm && 0 < chaf_svc_kei_ucwk_gene_add_dtm.length()` |
| 2 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no` |
| 3 | SET | `this.svc_kei_ucwk_gadtm[0] = chaf_svc_kei_ucwk_gene_add_dtm` |
| 4 | SET | `this.old_vrsb_jdg_svc_dtl_cd = getNewPplanCd(handle, param, svc_kei_no)` // ANK-2765: Old VR identification — new tariff plan code (during provision, via service call) |
| 5 | CALL | `addSOD(handle, param, ODR_NAIYO_CD_101="101")` // FTTH Authentication Registration SOD |

#### Block 5.2 — FTTH Cancellation and Deletion (L8908)

| # | Type | Code |
|---|------|------|
| 1 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no` |
| 2 | SET | `this.svc_kei_ucwk_gadtm[0] = chbf_svc_kei_ucwk_gene_add_dtm` |
| 3 | CALL | `addSOD(handle, param, ODR_NAIYO_CD_103="103")` // FTTH Authentication Cancellation SOD |
| 4 | CALL | `addSOD(handle, param, ODR_NAIYO_CD_104="104")` // FTTH Authentication Deletion SOD |

#### Block 5.3 — IF [chaf_kktsvkei_no available] (L8915)

BBR equipment handling during provision.

| # | Type | Code |
|---|------|------|
| 1 | IF | `chaf_kktsvkei_no != null && chaf_kktsvkei_gene_add_dtm != null` |
| 2 | SET | `this.kktk_svc_kei_no[0] = chaf_kktsvkei_no` // Post-change equipment-provided service contract number |
| 3 | SET | `this.kktk_svc_kei_gadtm[0] = chaf_kktsvkei_gene_add_dtm` // Post-change equipment-provided service contract registration datetime |
| 4 | CALL | `jdgOdr163(handle, param, sodMap)` // ANK-77: Router connection information/change processing |

##### Block 5.3.1 — IF [Equipment changed] (L8930)

| # | Type | Code |
|---|------|------|
| 1 | IF | `chbf_kktsvkei_no != null &&!chbf_kktsvkei_no.equals(chaf_kktsvkei_no)` |
| 2 | SET | `this.kktk_svc_kei_no[0] = chbf_kktsvkei_no` // Pre-change equipment number |
| 3 | SET | `this.kktk_svc_kei_gadtm[0] = chbf_kktsvkei_gene_add_dtm` // Pre-change equipment registration datetime |
| 4 | // BBR Return SOD (commented out — `addSODBBRHmpin` was removed) | |

#### Block 5.4 — IF [chaf_opsvkei_no available] (L9002)

[Post-change operations service contract number present] Process operations service agreement.

| # | Type | Code |
|---|------|------|
| 1 | IF | `null != svc_kei_ucwk_no && 0 < svc_kei_ucwk_no.length() && null != chaf_svc_kei_ucwk_gene_add_dtm && 0 < chaf_svc_kei_ucwk_gene_add_dtm.length() && chaf_opsvkei_no != null && !"".equals(chaf_opsvkei_no)` |
| 2 | SET | `chafInHash = new HashMap<String, Object>()` |
| 3 | SET | `chafResultHash = new HashMap<String, Object>()` |
| 4 | SET | `chafInHash.put(JKKHakkoSODConstCC.OP_SVC_KEI_NO, chaf_opsvkei_no)` // Post-change operations service contract number |
| 5 | SET | `chafInHash.put(JKKHakkoSODConstCC.GENE_ADD_DTM, chaf_opsvkei_gene_add_dtm)` |
| 6 | CALL | `statusCode = callEKK0351A010SC(param, handle, chafInHash, chafResultHash, JKKHakkoSODConstCC.FUNC_CODE_1)` // Operations service agreement inquiry |
| 7 | IF | `0 != statusCode` |
| 8 | THROW | `throw new CCException(...)` // Error on non-zero status |
| 9 | SET | `chafEKK0351A010SCHash = (HashMap)chafResultHash.get(JKKHakkoSODConstCC.TEMPLATE_ID_EKK0351A010)` |
| 10 | SET | `opSvcCd = (String)chafEKK0351A010SCHash.get(EKK0351A010CBSMsg1List.OP_SVC_CD)` |

##### Block 5.4.1 — IF [opSvcCd = B015 Multise] (L9021)

[OP_SVC_CD_MLTISE="B015"] Operations service code is Multise — register dynamic Multise SODs.

| # | Type | Code |
|---|------|------|
| 1 | IF | `JKKHakkoSODConstCC.OP_SVC_CD_MLTISE.equals(opSvcCd)` |
| 2 | SET | `this.op_svc_kei_no_mltise = chaf_opsvkei_no` // Multise operations service contract number |
| 3 | SET | `this.op_gadtm_mltise = chaf_opsvkei_gene_add_dtm` // Multise registration datetime |
| 4 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no` |
| 5 | SET | `this.svc_kei_ucwk_gadtm[0] = chaf_svc_kei_ucwk_gene_add_dtm` |
| 6 | SET | `this.old_vrsb_jdg_svc_dtl_cd = getOldVrsbIdgSvcDtlCd(handle, param, svc_kei_no, this.svc_kei_ucwk_no[0], this.pplan_cd)` // ANK-2765 |
| 7 | SET | `inHashMltise = new HashMap<String, Object>()` // Upper mapping |
| 8 | SET | `resultHashMltise = new HashMap<String, Object>()` |
| 9 | SET | `inHashMltise.put(JKKHakkoSODConstCC.SVC_KEI_NO, svc_kei_no)` |
| 10 | SET | `inHashMltise.put(JKKHakkoSODConstCC.OP_SVC_CD, JKKHakkoSODConstCC.OP_SVC_CD_FIXIPAD)` // Query Fixed IP Address |
| 11 | CALL | `statusCode = callEKK0351B002SC(param, handle, inHashMltise, resultHashMltise, JKKHakkoSODConstCC.FUNC_CODE_1)` // Operations service contract list inquiry |
| 12 | SET | `msgList = (CAANMsg[])resultHashMltise.get(JKKHakkoSODConstCC.TEMPLATE_ID_EKK0351B002)` |
| 13 | LOOP | `for(int i = 0 ; i < msgList.length ; i++)` // Iterate operations service contracts |
| 14 | SET | `op_svc_kei_stat = retHash.get(EKK0351B002CBSMsg1List.OP_SVC_KEI_STAT).toString()` // Operations service contract status |
| 15 | IF | `op_svc_kei_stat != null && !"".equals(op_svc_kei_stat)` |
| 16 | IF | `SVC_KEI_STAT_030.equals(op_svc_kei_stat) || SVC_KEI_STAT_100.equals(op_svc_kei_stat)` |
| 17 | CALL | `addSOD(handle, param, ODR_NAIYO_CD_144="144")` // Multise (Static) Registration SOD (with OM-2015-0001144 MOD: replaced 162) |
| 18 | ELSE | `addSOD(handle, param, ODR_NAIYO_CD_142="142")` // Multise (Dynamic) Registration SOD |

##### Block 5.4.2 — IF [opSvcCd = B004 FixIPAD] (L9094)

[OP_SVC_CD_FIXIPAD="B004"] Operations service code is Fixed Global IP Address — register Fixed IP Add SOD.

| # | Type | Code |
|---|------|------|
| 1 | IF | `JKKHakkoSODConstCC.OP_SVC_CD_FIXIPAD.equals(opSvcCd)` |
| 2 | SET | `this.svc_kei_ucwk_no = new String[1]` |
| 3 | SET | `this.svc_kei_ucwk_gadtm = new String[1]` |
| 4 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no` |
| 5 | SET | `this.svc_kei_ucwk_gadtm[0] = chaf_svc_kei_ucwk_gene_add_dtm` |
| 6 | SET | `this.op_svc_kei_no_fixipad = chaf_opsvkei_no` // Fixed Global IP Address operations service contract number |
| 7 | SET | `this.op_gadtm_fixipad = chaf_opsvkei_gene_add_dtm` // Fixed Global IP registration datetime |
| 8 | SET | `this.old_vrsb_jdg_svc_dtl_cd = getOldVrsbIdgSvcDtlCd(handle, param, svc_kei_no, this.svc_kei_ucwk_no[0], this.pplan_cd)` // ANK-2765 |
| 9 | SET | `inHashKoteiIp = new HashMap<String, Object>()` // Upper mapping |
| 10 | SET | `resultHashKoteiIp = new HashMap<String, Object>()` |
| 11 | SET | `inHashKoteiIp.put(JKKHakkoSODConstCC.SVC_KEI_NO, svc_kei_no)` |
| 12 | SET | `inHashKoteiIp.put(JKKHakkoSODConstCC.OP_SVC_CD, JKKHakkoSODConstCC.OP_SVC_CD_FIXIPAD)` // Fixed Global IP Address |
| 13 | CALL | `statusCode = callEKK0351B002SC(param, handle, inHashKoteiIp, resultHashKoteiIp, JKKHakkoSODConstCC.FUNC_CODE_1)` // Operations service contract list inquiry |
| 14 | SET | `msgList = (CAANMsg[])resultHashKoteiIp.get(JKKHakkoSODConstCC.TEMPLATE_ID_EKK0351B002)` |
| 15 | LOOP | `for(int i = 0 ; i < msgList.length ; i++)` |
| 16 | IF | `chaf_opsvkei_no.equals(retHash.get(EKK0351B002CBSMsg1List.OP_SVC_KEI_NO).toString())` // ANK-2015-0001144: match by OP_SVC_KEI_NO |
| 17 | SET | `op_svc_kei_stat = retHash.get(EKK0351B002CBSMsg1List.OP_SVC_KEI_STAT).toString()` |
| 18 | IF | `SVC_KEI_STAT_030.equals(op_svc_kei_stat) || SVC_KEI_STAT_100.equals(op_svc_kei_stat)` |
| 19 | CALL | `addSOD(handle, param, ODR_NAIYO_CD_152="152")` // Fixed IP Address Registration SOD |

### Block 6 — ELSE IF [Net-only course change, no svc_kei_ucwk_no] (L9167)

[ANK-2765-00-00 ADD] Authentication ID unchanged scenario — issues net-only service orders when no service contract detail number exists.

| # | Type | Code |
|---|------|------|
| 1 | IF | `chgSvcKeiJdg(svc_kei_no) && isBlank(svc_kei_ucwk_no) && isBlank(chaf_svc_kei_ucwk_gene_add_dtm)` |
| 2 | CALL | `hakkoCourseChgSOD(handle, param, fixedText)` // Issue service order for net plan change |
| 3 | SET | `workMap = (HashMap)param.getData(JKKHakkoSODConstCC.HAKKOSODCCWORKMAP)` |
| 4 | SET | `this.same_trn_no = (String)workMap.get("same_trn_no")` |

### Block 7 — FINAL [Set mae_recode_ch_svc_kei_no and return] (L9179)

| # | Type | Code |
|---|------|------|
| 1 | IF | `!isBlank(this.same_trn_no)` |
| 2 | SET | `this.mae_recode_ch_svc_kei_no = new String(svc_kei_no)` // Record previous contract number |
| 3 | RETURN | `return param;` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `pcrs_cd` | Field | PC rate code — identifies the internet service speed tier (e.g., 100M, 1G, 10G, 5G, SIMPLE, MEZON variants). Used to validate whether the course change applies to a supported plan. |
| `svc_kei_no` | Field | Service contract number — unique identifier for the FTTH service contract line item. |
| `svc_kei_ucwk_no` | Field | Service contract detail number — internal tracking identifier for service contract sub-items. Blank for net-only changes. |
| `svc_kei_stat` | Field | Service contract status — lifecycle state of the service (010: Received, 020: Confirmed, 030: Contract Complete, 100: During Provision). |
| `chbf_*` | Field | Pre-change timestamp/number fields. `chbf` = "before" (変更前). |
| `chaf_*` | Field | Post-change timestamp/number fields. `chaf` = "after" (変更後). |
| `chbf_svc_kei_ucwk_gene_add_dtm` | Field | Pre-change service contract detail registration datetime (YYYYMMDDHHmmss format). |
| `chaf_svc_kei_ucwk_gene_add_dtm` | Field | Post-change service contract detail registration datetime. |
| `chaf_opsvkei_no` | Field | Post-change operations service contract number — identifies optional add-on services. |
| `chaf_kktsvkei_no` | Field | Post-change equipment-provided service contract number — identifies the broadband router (BBR) equipment contract. |
| `same_trn_no` | Field | Same transaction number — shared reference to prevent duplicate order processing across related course changes. |
| `old_vrsb_jdg_svc_dtl_cd` | Field | Old version identification judgment service detail code — tariff plan discrimination code for ANK-2765 (authentication ID unification). |
| `pplan_cd` | Field | Pricing plan code — current tariff/plan code associated with the service. |
| `kktk_svc_kei_no` | Field | Equipment-provided service contract number (kktk = 機器提供). |
| `mae_recode_ch_svc_kei_no` | Field | Previous contract number record for service change. |
| `ido_div` | Field | Action division code — routing key in the parent `JKKHakkoSODCC` to determine operation type (COURSECHG, CANCEL, OPSETTE, etc.). |
| `sodMap` | Field | SOD (Service Order Data) map — central container for all service data sub-maps passed into the method. |
| SOD | Acronym | Service Order Data — the order document/entity in the e-Komi system representing a service change request. |
| FTTH | Business term | Fiber To The Home — fiber-optic broadband internet service offered by K-Opticom. |
| BBR | Business term | Broadband Router — customer premise equipment (CPE) provided by the operator for FTTH connections. |
| Multise | Business term | Multise (マルチセッション) — an optional operations service enabling multiple simultaneous sessions. Available in dynamic (動的) and static (静的) variants. |
| Fixed Global IP Address | Business term | Fixed Global IP Address (固定グローバルIPアドレス) — optional operations service providing a static public IP address. |
| ODR_NAIYO_CD | Field | Order content code — classifies the type of SOD to be issued. |
| `ODR_NAIYO_CD_101` | Constant | FTTH Authentication Registration — creates new FTTH authentication for the changed plan. |
| `ODR_NAIYO_CD_103` | Constant | FTTH Authentication Cancellation — cancels existing FTTH authentication. |
| `ODR_NAIYO_CD_104` | Constant | FTTH Authentication Deletion — fully removes FTTH authentication records. |
| `ODR_NAIYO_CD_142` | Constant | Multise (Dynamic) Registration — registers dynamic Multise service. |
| `ODR_NAIYO_CD_144` | Constant | Multise (Static) Registration — registers static Multise service. |
| `ODR_NAIYO_CD_152` | Constant | Fixed Global IP Address Registration — registers Fixed IP Address service. |
| EKK0351A010SC | SC Code | Operations Service Agreement Inquiry Service Component — queries the operations service agreement details. |
| EKK0351B002SC | SC Code | Operations Service Contract List Inquiry Service Component — lists operations service contracts linked to a service contract. |
| OP_SVC_CD_MLTISE | Constant | Operations service code `"B015"` — Multise service. |
| OP_SVC_CD_FIXIPAD | Constant | Operations service code `"B004"` — Fixed Global IP Address service. |
| shkkaMap | Method | Map sanitization method — validates and transforms maps extracted from `sodMap`. |
| jdgOdr163 | Method | Router connection information change judgment — handles BBR router reconnection data for equipment changes. |
| chgSvcKeiJdg | Method | Service change judgment — determines whether the service contract number has changed from the previous record. |
| hakkoCourseChgSOD | Method | Course change SOD issuance — final SOD generation for net-only (subnet) plan changes. |
| HAKKOSODCCWORKMAP | Constant | Work data map key stored in `param` — carries intermediate processing data including `same_trn_no`. |
| NET | Business term | Net (net) — the internet service layer (as opposed to telephony/PSTN). Net-only course changes modify the internet plan without changing FTTH authentication. |
| Mezon | Business term | e-hikari Mezon (eo光ネオん) — K-Opticom's fiber optic internet plan family. |
| SIMPLE | Business term | e-hikari Simple Plan (eo光ネット「シンプルプラン」) — entry-level FTTH plan. |
| MANS_GLB | Business term | Manshin Global (まんしん全球) — regional FTTH plan variant. |
