# Business Logic — JKKHakkoSODCC.courseChgeOdrCtrl() [792 LOC]

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

## 1. Role

### JKKHakkoSODCC.courseChgeOdrCtrl()

This method is the central controller for **course change order processing** within the K-Opticom customer base system (eo customer base system). Its Javadoc reads "Course Change Order Control Processing" (コース変更オーダ制御処理). The method's primary business responsibility is to determine, based on a customer's contracted pricing plan (pcrs_cd) and service contract status (svc_kei_stat), whether a course change request requires Service Order Data (SOD) generation — and if so, which specific SOD types to emit.

The method handles **two distinct business phases**: (1) **pre-service course changes** (svc_kei_stat = 010/020/030 — received, reviewed, or contracted but not yet active) where FTTH authentication registration and cancellation/deletion SODs are emitted along with equipment (BBR = Broadband Router) delivery SODs; and (2) **post-service course changes** (svc_kei_stat = 100 — service provision in progress) where FTTH authentication registration SODs and, when applicable, equipment delivery SODs are emitted.

In both phases, the method implements a **dispatching/routing design pattern**: it branches on multiple dimensions — pcrs_cd (pricing code), svc_kei_stat (service status), op_svc_cd (option service code), and equipment contract state — to produce the correct set of SODs for downstream processing. It also handles the **fallback SOD emission** via `hakkoCourseChgSOD` when the authentication ID (svc_kei_ucwk_no) has not changed but the pricing plan code has.

This method is a **shared utility component** called by `adchgFixOdrCtrl` (address change fixed order control) and `hakkoSOD` (SOD issuance), making it a critical node in the order fulfillment pipeline. It serves as the bridge between contract data and the SOD issuance subsystem, ensuring that the correct SODs are registered for downstream CBS (Common Business Service) consumption.

The method explicitly **excludes non-FTTH pricing codes** from its processing. If the pricing plan code (pcrs_cd) is not in the defined exclusion list (which includes 100M/200M/1G/5G/10G FTTH plans, Mezon plans, Type-N plans, and Manshon plans), the method returns immediately without emitting any SODs. This filtering ensures that non-eligible service types (e.g., mobile, ADSL, plain telephones) do not trigger unnecessary SOD processing.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["courseChgeOdrCtrl(params)"])
    
    START --> EXTRACT["Extract Maps from sodMap"]
    EXTRACT --> FILTER["Filter by pcrs_cd exclusion list"]
    
    FILTER --> IS_EXCLUDED{pcrs_cd in exclusion<br/>list?}
    
    IS_EXCLUDED -->|Yes| RETURN1["Return param unchanged"]
    
    IS_EXCLUDED -->|No| SVC_STAT{svc_kei_stat check}
    
    SVC_STAT -->|010 020 030| BEFORE_BLOCK["Before-Service Block"]
    SVC_STAT -->|100| AFTER_BLOCK["After-Service Block"]
    
    BEFORE_BLOCK --> BDG1{svc_kei_no changed?}
    
    BDG1 -->|No| BEFORE_END["End Before-Service"]
    
    BDG1 -->|Yes| BEFORE_PROCESS["Before-Service SOD Processing"]
    
    BEFORE_PROCESS --> B_SETKEY["Set service key fields"]
    B_SETKEY --> B_FTTH_REG["addSOD FTTH Auth Registration 101"]
    B_FTTH_REG --> B_LOOKUP["callEKK0161B004SC lookup"]
    B_LOOKUP --> B_VERFY{UCWK match?}
    B_VERFY -->|Match| B_CONT["Continue loop"]
    B_VERFY -->|No Match| B_UPDKEY["Update key latest version"]
    B_CONT --> B_CHK{"More UCWK?"}
    B_UPDKEY --> B_CHK
    B_CHK -->|Yes| B_LOOP
    B_CHK -->|No| B_FTTH_TERM["addSOD FTTH Auth Cancellation 103"]
    B_FTTH_TERM --> B_FTTH_DEL["addSOD FTTH Auth Deletion 104"]
    B_FTTH_DEL --> B_BBRCHK{chaf_kktsvkei<br/>valid?}
    B_BBRCHK -->|No| B_JDGEND
    B_BBRCHK -->|Yes| B_BBRSET["Set equipment key"]
    B_BBRSET --> B_JDGEND("jdgOdr163")
    
    AFTER_BLOCK --> ADG1{svc_kei_no changed?}
    ADG1 -->|No| AFTER_END["End After-Service"]
    ADG1 -->|Yes| AFTER_PROCESS["After-Service SOD Processing"]
    
    AFTER_PROCESS --> A_SETKEY["Set service key fields"]
    A_SETKEY --> A_FTTH_REG["addSOD FTTH Auth Registration 101"]
    A_FTTH_REG --> A_END("jdgOdr163")
    
    A_END --> CHGAF_OPSV{chaf_opsvkei<br/>valid?}
    
    CHGAF_OPSV -->|Yes| CHGAF_PROC["Post-Change SOD Processing"]
    CHGAF_PROC --> C_OPSVQ["callEKK0351A010SC"]
    C_OPSVQ --> C_TYPE{opSvcCd?}
    
    C_TYPE -->|B015| C_MLTISE["Multi-Session SOD"]
    C_TYPE -->|B004| C_FIXIP["Fixed IP SOD"]
    C_TYPE -->|Other| C_SKIP
    
    C_MLTISE --> C_STATCHK{op_svc_kei_stat?}
    C_STATCHK -->|030 100| C_MLTISE_S["Multi-Session Static 144"]
    C_STATCHK -->|Other| C_MLTISE_D["Multi-Session Dynamic 142"]
    
    C_FIXIP --> C_FIXIP_CHK{op_svc_kei_stat?}
    C_FIXIP_CHK -->|030 100| C_FIXIP_R["addSOD FixIP Registration 152"]
    C_FIXIP_CHK -->|Other| C_FIXIP_SKIP
    
    C_SKIP --> FINAL_CHECK{no svc_kei_ucwk<br/>and svc_kei_no changed?}
    
    C_MLTISE_S --> FINAL_CHECK
    C_MLTISE_D --> FINAL_CHECK
    C_FIXIP_R --> FINAL_CHECK
    
    FINAL_CHECK -->|Yes| FINAL_SOD["hakkoCourseChgSOD"]
    FINAL_CHECK -->|No| FINAL_RET["Final Return"]
    
    FINAL_SOD --> FINAL_RET
    
    BEFORE_END --> FINAL_CHECK
    AFTER_END --> FINAL_CHECK
    RETURN1 --> FINAL_RET
    
    FINAL_RET --> END_NODE(["Return param"])
```

**CRITICAL — Constant Resolution:**

| Constant | Resolved Value | Business Meaning |
|----------|---------------|-----------------|
| `PCRS_CD_100M` | `"A03"` | FTTH 100M Plan |
| `PCRS_CD_100M_PRM` | `"A04"` | FTTH 100M Premium Plan |
| `PCRS_CD_1G` | `"A05"` | FTTH 1G Plan |
| `PCRS_CD_100M_VPN` | `"A06"` | FTTH 100M VPN Plan |
| `PCRS_CD_200M` | `"A07"` | FTTH 200M Plan |
| `PCRS_CD_5G` | `"A54"` | FTTH 5G Plan (from regex `^A5[45]`) |
| `PCRS_CD_10G` | `"A55"` / `"A74"` | FTTH 10G Plan |
| `PCRS_CD_SIMPLE_10G` | — | eo Light Net Simple Plan 10G |
| `PCRS_CD_SIMPLE_10G_NETFLIX` | — | eo Light Net Simple Plan 10G Netflix |
| `PCRS_CD_TYPE_N_1G` | `"A72"` | Type-N 1G Plan |
| `PCRS_CD_MEZON_100M` | `"A08"` | Mezon 100M Plan |
| `PCRS_CD_MEZON_1G` | `"A10"` | Mezon 1G Plan |
| `PCRS_CD_MANS_GLB_MHIKARI` | `"A56"` | Manshon Global Mega Hikari |
| `PCRS_CD_MANS_GLB_GHIKARI` | `"A57"` | Manshon Global Hikari |
| `PCRS_CD_MANS_GLB_10GHIKARI` | `"A74"` | Manshon Global 10G Hikari |
| `SVC_KEI_STAT_010` | `"010"` | Received Status |
| `SVC_KEI_STAT_020` | `"020"` | Under Review Status |
| `SVC_KEI_STAT_030` | `"030"` | Contracted Status |
| `SVC_KEI_STAT_100` | `"100"` | Service Provision in Progress |
| `SVC_KEI_STAT_910` | `"910"` | Course Change Status |
| `SVC_KEI_STAT_920` | `"920"` | Change Pending Status |
| `ODR_NAIYO_CD_101` | `"101"` | FTTH Auth Registration |
| `ODR_NAIYO_CD_103` | `"103"` | FTTH Auth Cancellation |
| `ODR_NAIYO_CD_104` | `"104"` | FTTH Auth Deletion |
| `ODR_NAIYO_CD_142` | `"142"` | Multi-Session Dynamic Registration |
| `ODR_NAIYO_CD_144` | `"144"` | Multi-Session Static Registration |
| `ODR_NAIYO_CD_145` | `"145"` | Fixed IP Address Cancellation |
| `ODR_NAIYO_CD_146` | `"146"` | Fixed IP Address Deletion |
| `ODR_NAIYO_CD_152` | `"152"` | Fixed IP Address Registration |
| `OP_SVC_CD_B004` | `"B004"` | Fixed IP Address Service |
| `OP_SVC_CD_B015` | `"B015"` | Multi-Session Service |
| `IDO_DIV_COURSECHG` | `"01"` | Course Change Division Code |
| `FUNC_CODE_1` | `"1"` | Function Code for CBS Calls |

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `handle` | `SessionHandle` | Database/session handle carrying connection context and transaction scope for executing CBS service calls. It provides the persistence context for all read/write operations. |
| 2 | `param` | `IRequestParameterReadWrite` | Request/response parameter object that carries the model group, control map, and processed data between the CC method and called CBS/SC components. It accumulates SOD registration data throughout processing. |
| 3 | `fixedText` | `String` | User-defined arbitrary string field (as per Javadoc: ユーザ任意文字列). Passed through to `hakkoCourseChgSOD` when a fallback course change SOD must be issued for pricing plan code changes where the authentication ID did not change. |
| 4 | `sodMap` | `HashMap<String, Object>` | The SOD (Service Order Data) map containing all service contract data organized by category keys. It includes sub-maps for service contract info (SVC_KEI_INFO), service contract details (SVC_KEI_UCWK_INFO), option service contract info (OPSVKEI_INFO), and equipment provision service contract info (KKTSVKEI_INFO). This map is the primary data source for the method's decision logic. |

**Instance fields read by this method:**

| Field | Type | Business Meaning |
|-------|------|-----------------|
| `pcrs_cd` | String | Pricing course code — determines which pricing plan the customer is on; primary filter for course change eligibility |
| `svc_kei_stat` | String | Service contract status — determines whether the customer is in pre-service or post-service phase |
| `same_trn_no` | String | Same processing number — shared transaction tracking ID across related course change operations |
| `old_vrsb_jdg_svc_dtl_cd` | String | Old version identification judgment service detail code — used for authentication ID unification (ANK-2765), derived from the previous pricing plan code |
| `svc_kei_ucwk_no` | String[] | Service contract detail number array — identifies the specific service contract line item |
| `svc_kei_ucwk_gadtm` | String[] | Service contract detail registration date-time |
| `kktk_svc_kei_no` | String[] | Equipment provision service contract number (for BBR/router) |
| `kktk_svc_kei_gadtm` | String[] | Equipment provision service contract registration date-time |

## 4. CRUD Operations / Called Services

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `callEKK0161B004SC` | EKK0161B004SC | KK_T_SVC_KEI_UCWK | Service contract detail list inquiry (by service contract number) — queries pre-service UCWK records to find matching or changed contract detail versions |
| R | `callEKK0351A010SC` | EKK0351A010SC | KK_T_OP_SVC_KEI_ISP | Option service contract agreement inquiry — queries the option service contract agreement table using option service contract number and registration date-time |
| R | `callEKK0351B002SC` | EKK0351B002SC | KK_T_OP_SVC_KEI_ISP | Option service contract list inquiry (by service contract number) — queries option service contract records to determine the current status of multi-session or fixed IP agreements |
| C | `addSOD` | (internal) | KK_T_SOD (SOD issuance) | Registers a Service Order Data record. Called with various ODR_NAIYO_CD values to emit FTTH auth registration (101), FTTH auth cancellation (103), FTTH auth deletion (104), multi-session dynamic registration (142), multi-session static registration (144), and fixed IP registration (152) SODs |
| - | `chgSvcKeiJdg` | (internal) | — | Judgment method that compares the current service contract number against the previous record's contract number to determine if a course change is occurring |
| R | `getNewPplanCd` | (internal) | KK_T_PRCRS (pricing plan) | Retrieves the new pricing plan code for the given service contract number (used in post-service phase to determine the old version judgment code) |
| R | `getOldVrsbIdgSvcDtlCd` | (internal) | Multiple tables | Retrieves the old version identification service detail code based on the service contract number, service contract detail number, and pricing plan code (used for authentication ID unification) |
| R | `getSame_trn_no` | (internal) | KK_T_TRN_NO or similar | Acquires a shared processing number (same_trn_no) used to correlate related course change transactions |
| C | `hakkoCourseChgSOD` | (internal) | KK_T_SOD | Issues the fallback course change SOD when the authentication ID has not changed but the pricing plan code has been modified |
| - | `shkkaMap` | (internal) | — | Map filtering/revision method that retrieves and validates sub-maps from sodMap (Japanese: 検索 — "search/filter") |
| - | `isBlank` | (internal) | — | Utility method that checks whether a string value is null, empty, or blank |
| - | `jdgOdr163` | (internal) | — | Judgment method for order 163 (IT1-2013-0001691 related) — handles equipment provision service contract judgment for course change orders |
| R | `getOldVrsbIdgSvcDtlCd` | (internal) | Multiple tables | Called twice in the post-change block: once for multi-session (B015) and once for fixed IP (B004) branches to determine the old pricing plan code for version identification |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | `JKKHakkoSODCC.adchgFixOdrCtrl` | `adchgFixOdrCtrl` → `courseChgeOdrCtrl` | `addSOD [C] KK_T_SOD`, `callEKK0351B002SC [R] KK_T_OP_SVC_KEI_ISP`, `getOldVrsbIdgSvcDtlCd [R] KK_T_PRCRS`, `callEKK0351A010SC [R] KK_T_OP_SVC_KEI_ISP`, `getNewPplanCd [R] KK_T_PRCRS`, `getSame_trn_no [R] KK_T_TRN_NO`, `chgSvcKeiJdg [-]`, `jdgOdr163 [-]`, `hakkoCourseChgSOD [C] KK_T_SOD` |
| 2 | `JKKHakkoSODCC.hakkoSOD` | `hakkoSOD` → `courseChgeOdrCtrl` | Same terminals as caller 1 |

## 6. Per-Branch Detail Blocks

### Block 1 — INIT (L10674)

> Initialize local variables and extract service contract maps from the sodMap.

| # | Type | Code |
|---|------|------|
| 1 | SET | `statusCode = 0;` // Service interface execution status |
| 2 | SET | `chafEKK0351A010SCHash = null;` // Post-change option service contract agreement result hash |
| 3 | SET | `svc_kei_info_Map = (HashMap)sodMap.get(SVC_KEI_INFO);` // Service contract info |
| 4 | SET | `svc_kei_ucwk_info_Map = (HashMap)sodMap.get(SVC_KEI_UCWK_INFO);` // Service contract detail info |
| 5 | SET | `opsvkei_info_Map = (HashMap)sodMap.get(OPSVKEI_INFO);` // Option service contract info |
| 6 | SET | `kktsvkei_info_Map = (HashMap)sodMap.get(KKTSVKEI_INFO);` // Equipment provision service contract info |
| 7 | EXEC | `svc_kei_info_Map = shkkaMap(svc_kei_info_Map);` // Filter service contract info |
| 8 | EXEC | `svc_kei_ucwk_info_Map = shkkaMap(svc_kei_ucwk_info_Map);` // Filter service contract detail info |
| 9 | EXEC | `opsvkei_info_Map = shkkaMap(opsvkei_info_Map);` // Filter option service contract info |
| 10 | EXEC | `kktsvkei_info_Map = shkkaMap(kktsvkei_info_Map);` // Filter equipment provision service contract info |

### Block 2 — EXTRACT COURSE CHANGE PARAMETERS (L10697-L10713)

> Extract service contract number, detail numbers, and registration date-times from the sub-maps.

| # | Type | Code |
|---|------|------|
| 1 | SET | `svc_kei_no = (String)svc_kei_info_Map.get(INFO_SVC_KEI_NO);` // Service contract number |
| 2 | SET | `svc_kei_ucwk_no = (String)svc_kei_ucwk_info_Map.get(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(INFO_CHBF_SVC_KEI_UCWK_GENE_ADD_DTM);` // Pre-change contract detail reg datetime |
| 4 | SET | `chaf_svc_kei_ucwk_gene_add_dtm = (String)svc_kei_ucwk_info_Map.get(INFO_CHAF_SVC_KEI_UCWK_GENE_ADD_DTM);` // Post-change contract detail reg datetime |
| 5 | SET | `chaf_opsvkei_no = (String)opsvkei_info_Map.get(INFO_CHAF_OPSVKEI_NO);` // Post-change option service contract number |
| 6 | SET | `chaf_opsvkei_gene_add_dtm = (String)opsvkei_info_Map.get(INFO_CHAF_OPSVKEI_GENE_ADD_DTM);` // Post-change option service reg datetime |
| 7 | SET | `chaf_kktsvkei_no = (String)kktsvkei_info_Map.get(INFO_CHAF_KKTSVKEI_NO);` // Post-change equipment provision service contract number |
| 8 | SET | `chaf_kktsvkei_gene_add_dtm = (String)kktsvkei_info_Map.get(INFO_CHAF_KKTSVKEI_GENE_ADD_DTM);` // Post-change equipment provision service reg datetime |

### Block 3 — PCRS_CD EXCLUSION FILTER (L10716-L10791)

> If pcrs_cd is NOT in the exclusion list of eligible FTTH/Type-N/Mezon/Manshon pricing plans, return immediately. This is a large negated condition with approximately 35+ pricing plan codes.

| # | Type | Code |
|---|------|------|
| 1 | IF | `!pcrs_cd.equals(PCRS_CD_100M)` [A03 = FTTH 100M] |
| 2 | AND | `!pcrs_cd.equals(PCRS_CD_100M_PRM)` [A04 = FTTH 100M Premium] |
| 3 | AND | `!pcrs_cd.equals(PCRS_CD_1G)` [A05 = FTTH 1G] |
| 4 | AND | `!pcrs_cd.equals(PCRS_CD_100M_VPN)` [A06 = FTTH 100M VPN] |
| 5 | AND | `!pcrs_cd.equals(PCRS_CD_200M)` [A07 = FTTH 200M] |
| 6 | AND | `!pcrs_cd.equals(PCRS_CD_5G)` [A54 = FTTH 5G, added in IT1-2018-0000222] |
| 7 | AND | `!pcrs_cd.equals(PCRS_CD_10G)` [A55/A74 = FTTH 10G, added in IT2-2016-0000004] |
| 8 | AND | `!pcrs_cd.equals(PCRS_CD_SIMPLE_10G)` [eo Light Net Simple Plan 10G, ANK-4468] |
| 9 | AND | `!pcrs_cd.equals(PCRS_CD_SIMPLE_10G_NETFLIX)` [Simple Plan 10G Netflix, ANK-4468] |
| 10 | AND | `!pcrs_cd.equals(PCRS_CD_TYPE_N_1G)` [Type-N 1G, ANK-4427] |
| 11 | AND | `!pcrs_cd.equals(PCRS_CD_TYPE_N_10G)` [Type-N 10G, ANK-4427] |
| 12 | AND | `!pcrs_cd.equals(PCRS_CD_TYPE_N_MANS_100M)` [Type-N Manshon 100M, ANK-4427] |
| 13 | AND | `!pcrs_cd.equals(PCRS_CD_TYPE_N_MANS_1G)` [Type-N Manshon 1G, ANK-4427] |
| 14 | AND | `!pcrs_cd.equals(PCRS_CD_TYPE_N_MANS_10G)` [Type-N Manshon 10G, ANK-4427] |
| 15 | AND | `!pcrs_cd.equals(PCRS_CD_TYPE_N_1G_NETFLIX)` [Type-N Manshon 1G Netflix, ANK-4427] |
| 16 | AND | `!pcrs_cd.equals(PCRS_CD_TYPE_N_10G_NETFLIX)` [Type-N Manshon 10G Netflix, ANK-4427] |
| 17 | AND | `!pcrs_cd.equals(PCRS_CD_TYPE_N_MANS_100M_NETFLIX)` [Type-N Manshon 100M Netflix, ANK-4427] |
| 18 | AND | `!pcrs_cd.equals(PCRS_CD_TYPE_N_MANS_1G_NETFLIX)` [Type-N Manshon 1G Netflix, ANK-4427] |
| 19 | AND | `!pcrs_cd.equals(PCRS_CD_TYPE_N_MANS_10G_NETFLIX)` [Type-N Manshon 10G Netflix, ANK-4427] |
| 20 | AND | `!pcrs_cd.equals(PCRS_CD_MEZON_100M)` [A08 = Mezon 100M, ANK-4427] |
| 21 | AND | `!pcrs_cd.equals(PCRS_CD_MEZON_100M_PRM)` [A09 = Mezon 100M Premium] |
| 22 | AND | `!pcrs_cd.equals(PCRS_CD_MEZON_1G)` [A10 = Mezon 1G] |
| 23 | AND | `!pcrs_cd.equals(PCRS_CD_MEZON_200M)` [A11 = Mezon 200M] |
| 24 | AND | `!pcrs_cd.equals(PCRS_CD_MEZON_5G)` [Mezon 5G, IT1-2018-0000222] |
| 25 | AND | `!pcrs_cd.equals(PCRS_CD_MEZON_10G)` [Mezon 10G, IT2-2016-0000004] |
| 26 | AND | `!pcrs_cd.matches("^A5[45]")` // Manshon Global Ethernet VDSL — regex filter, ST1-2012-0000862 |
| 27 | AND | `!pcrs_cd.equals(CD00134_A50)` // Manshon Global VDSL2, IT2-2016-0000043 |
| 28 | AND | `!pcrs_cd.equals(CD00134_A51)` // Manshon Global VDSL3, IT2-2016-0000043 |
| 29 | AND | `!pcrs_cd.equals(CD00134_A52)` // Manshon Global VDSL4, IT2-2016-0000043 |
| 30 | AND | `!pcrs_cd.equals(CD00134_A53)` // Manshon Global VDSL5, IT2-2016-0000043 |
| 31 | AND | `!pcrs_cd.equals(CD00134_GLB100M_PREMIUM_VDSL)` // Manshon Global 100M Premium VDSL, IT2-2016-0000043 |
| 32 | AND | `!pcrs_cd.equals(CD00134_GLB100M_PREMIUM_ETHER)` // Manshon Global 100M Premium Ethernet, IT2-2016-0000043 |
| 33 | AND | `!pcrs_cd.equals(PCRS_CD_MANS_GLB_MHIKARI)` [A56 = Manshon Global Mega Hikari] |
| 34 | AND | `!pcrs_cd.equals(PCRS_CD_1G_NETFLIX)` [FTTH 1G Netflix, ANK-3949] |
| 35 | AND | `!pcrs_cd.equals(PCRS_CD_MEZON_1G_NETFLIX)` [Mezon 1G Netflix, ANK-3949] |
| 36 | AND | `!pcrs_cd.equals(PCRS_CD_5G_NETFLIX)` [FTTH 5G Netflix, ANK-3949] |
| 37 | AND | `!pcrs_cd.equals(PCRS_CD_MEZON_5G_NETFLIX)` [Mezon 5G Netflix, ANK-3949] |
| 38 | AND | `!pcrs_cd.equals(PCRS_CD_10G_NETFLIX)` [FTTH 10G Netflix, ANK-3949] |
| 39 | AND | `!pcrs_cd.equals(PCRS_CD_MEZON_10G_NETFLIX)` [Mezon 10G Netflix, ANK-3949] |

**Block 3.1 — ELSE branch (L10793)**

> Course change processing target — NOT an excluded pricing code. Proceed with course change SOD emission logic.

| # | Type | Code |
|---|------|------|
| 1 | — | Fall through to svc_kei_stat branching |

### Block 4 — PRE-SERVICE COURSE CHANGE (svc_kei_stat = 010/020/030) (L10796)

> Condition: `SVC_KEI_STAT_010.equals(svc_kei_stat) OR SVC_KEI_STAT_020.equals(svc_kei_stat) OR SVC_KEI_STAT_030.equals(svc_kei_stat)`
> Business meaning: Before Service — the customer's contract has been received (010), is under review (020), or is contracted (030) but service has not yet begun.

**Block 4.1 — Inner check: svc_kei_no changed (L10802)**

> `chgSvcKeiJdg(svc_kei_no)` — returns true if the current service contract number differs from the previous record's number.

| # | Type | Code |
|---|------|------|
| 1 | SET | `sameTrnNo = new String[1];` // Array to hold returned value |
| 2 | CALL | `getSame_trn_no(param, handle, null, sameTrnNo);` // Acquire shared processing number |
| 3 | SET | `this.same_trn_no = sameTrnNo[0];` // Store in instance field |
| 4 | SET | `this.svc_kei_ucwk_no = new String[1];` // Initialize service contract detail array |
| 5 | SET | `this.svc_kei_ucwk_gadtm = new String[1];` // Initialize registration datetime array |

**Block 4.1.1 — Inner check: svc_kei_ucwk_no and reg datetime valid (L10810)**

> Condition: `svc_kei_ucwk_no != null && svc_kei_ucwk_no.length() > 0 && chaf_svc_kei_ucwk_gene_add_dtm != null && chaf_svc_kei_ucwk_gene_add_dtm.length() > 0`

| # | Type | Code |
|---|------|------|
| 1 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no;` // Service contract detail number |
| 2 | SET | `this.svc_kei_ucwk_gadtm[0] = chaf_svc_kei_ucwk_gene_add_dtm;` // Service contract detail reg datetime |
| 3 | SET | `this.old_vrsb_jdg_svc_dtl_cd = this.pplan_cd;` // Old version judgment code = current pricing plan code (ANK-2765-00-00) |
| 4 | CALL | `param = addSOD(handle, param, ODR_NAIYO_CD_101);` // FTTH Auth Registration SOD (101) |

**Block 4.1.2 — Service contract detail lookup (L10821-L10851)**

> Query service contract detail list (EKK0161B004) by service contract number to find matching or changed contract detail versions. This handles the case where the authentication ID changed.

| # | Type | Code |
|---|------|------|
| 1 | SET | `inHashUcwk = new HashMap<String, Object>();` // Input hash for UCWK lookup |
| 2 | SET | `resultHashUcwk = new HashMap<String, Object>();` // Result hash for UCWK lookup |
| 3 | SET | `chbf_svc_kei_ucwk_no = null;` // Previous service contract detail number |
| 4 | SET | `inHashUcwk.put(SVC_KEI_NO, svc_kei_no);` // Set service contract number as key |
| 5 | CALL | `callEKK0161B004SC(param, handle, inHashUcwk, resultHashUcwk, FUNC_CODE_1);` // Service contract detail list inquiry |
| 6 | SET | `msgListUcwk = (CAANMsg[])resultHashUcwk.get(TEMPLATE_ID_EKK0161B004);` // Extract message list |

**Block 4.1.2.1 — Loop: iterate UCWK records (L10827-L10851)**

> Loop through all returned UCWK records to find a matching or changed contract detail version.

| # | Type | Code |
|---|------|------|
| 1 | SET | `retHash = msgListUcwk[i].getMsgData();` // Get record data |
| 2 | IF | `retHash[UCWK_NO].equals(svc_kei_ucwk_no)` [Match check] |
| 3 | — | Continue to next record (match found — no action needed) |
| 4 | ELSE-IF | `retHash[UCWK_STAT] = SVC_KEI_STAT_910 OR SVC_KEI_STAT_920` [Course change or change pending status] |
| 5 | IF | `retHash[IDO_DIV] = IDO_DIV_COURSECHG AND retHash[GENE_ADD_DTM] > chaf_svc_kei_ucwk_gene_add_dtm` [It is a course change with newer version] |
| 6 | SET | `chbf_svc_kei_ucwk_no = retHash[UCWK_NO];` // Update to latest version |
| 7 | SET | `chbf_svc_kei_ucwk_gene_add_dtm = retHash[GENE_ADD_DTM];` // Update reg datetime |
| 8 | SET | `this.svc_kei_ucwk_no[0] = chbf_svc_kei_ucwk_no;` // Update instance field |
| 9 | SET | `this.svc_kei_ucwk_gadtm[0] = chbf_svc_kei_ucwk_gene_add_dtm;` // Update instance field |
| 10 | — | Break out of loop |
| 11 | ELSE | Continue to next record (not a course change or not newer) |

**Block 4.1.3 — FTTH Auth Cancellation and Deletion (L10857-L10859)**

| # | Type | Code |
|---|------|------|
| 1 | CALL | `param = addSOD(handle, param, ODR_NAIYO_CD_103);` // FTTH Auth Cancellation SOD (103) |
| 2 | CALL | `param = addSOD(handle, param, ODR_NAIYO_CD_104);` // FTTH Auth Deletion SOD (104) |

**Block 4.1.4 — Equipment (BBR) Delivery SOD (L10865-L10876)**

> Condition: `chaf_kktsvkei_no != null && chaf_kktsvkei_gene_add_dtm != null` (post-change equipment provision service contract is valid)

| # | Type | Code |
|---|------|------|
| 1 | SET | `this.kktk_svc_kei_no[0] = chaf_kktsvkei_no;` // Post-change equipment service contract number |
| 2 | SET | `this.kktk_svc_kei_gadtm[0] = chaf_kktsvkei_gene_add_dtm;` // Post-change equipment reg datetime |
| 3 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no;` // Update service contract detail number |
| 4 | SET | `this.svc_kei_ucwk_gadtm[0] = chaf_svc_kei_ucwk_gene_add_dtm;` // Update reg datetime |

**Block 4.1.4.1 — jdgOdr163 (L10932)**

> Equipment provision service contract judgment for course change orders.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `jdgOdr163(handle, param, sodMap);` // Equipment judgment |

### Block 5 — POST-SERVICE COURSE CHANGE (svc_kei_stat = 100) (L10970)

> Condition: `SVC_KEI_STAT_100.equals(svc_kei_stat)` — In Service (service provision in progress).

**Block 5.1 — Inner check: svc_kei_no changed (L10977)**

> `chgSvcKeiJdg(svc_kei_no)` — same as Block 4.1.

| # | Type | Code |
|---|------|------|
| 1 | SET | `sameTrnNo = new String[1];` |
| 2 | CALL | `getSame_trn_no(param, handle, null, sameTrnNo);` // Acquire shared processing number |
| 3 | SET | `this.same_trn_no = sameTrnNo[0];` |
| 4 | SET | `this.svc_kei_ucwk_no = new String[1];` |
| 5 | SET | `this.svc_kei_ucwk_gadtm = new String[1];` |

**Block 5.1.1 — Inner check: svc_kei_ucwk_no valid (L10985)**

> Condition: `svc_kei_ucwk_no != null && svc_kei_ucwk_no.length() > 0 && chaf_svc_kei_ucwk_gene_add_dtm != null && chaf_svc_kei_ucwk_gene_add_dtm.length() > 0`

| # | Type | Code |
|---|------|------|
| 1 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no;` // Service contract detail number |
| 2 | SET | `this.svc_kei_ucwk_gadtm[0] = chaf_svc_kei_ucwk_gene_add_dtm;` // Reg datetime |
| 3 | SET | `this.old_vrsb_jdg_svc_dtl_cd = getNewPplanCd(handle, param, svc_kei_no);` // Get new pricing plan code for old version judgment (ANK-2765) |
| 4 | CALL | `param = addSOD(handle, param, ODR_NAIYO_CD_101);` // FTTH Auth Registration SOD (101) |

**Block 5.1.2 — Equipment (BBR) Delivery (L10993-L11006)**

> Condition: `chaf_kktsvkei_no != null && chaf_kktsvkei_gene_add_dtm != null`

| # | Type | Code |
|---|------|------|
| 1 | SET | `this.kktk_svc_kei_no[0] = chaf_kktsvkei_no;` // Post-change equipment service contract number |
| 2 | SET | `this.kktk_svc_kei_gadtm[0] = chaf_kktsvkei_gene_add_dtm;` // Post-change equipment reg datetime |

**Block 5.1.2.1 — jdgOdr163 (L11031)**

> Equipment provision service contract judgment for post-service course changes.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `jdgOdr163(handle, param, sodMap);` // Equipment judgment |

### Block 6 — POST-COURSE-CHANGE OPTION SERVICE SOD (L11056-L11166)

> Condition: `chaf_opsvkei_no != null && !"".equals(chaf_opsvkei_no)` (post-change option service contract number is valid)
> This block is shared between pre-service and post-service phases — moved outside both blocks per ST2-2012-0001030.

**Block 6.1 — Option service contract agreement lookup (L11061-L11071)**

| # | Type | Code |
|---|------|------|
| 1 | SET | `chafInHash = new HashMap<String, Object>();` // Input hash |
| 2 | SET | `chafResultHash = new HashMap<String, Object>();` // Result hash |
| 3 | SET | `chafInHash.put(OP_SVC_KEI_NO, chaf_opsvkei_no);` // Post-change option service contract number |
| 4 | SET | `chafInHash.put(GENE_ADD_DTM, chaf_opsvkei_gene_add_dtm);` // Reg datetime |
| 5 | CALL | `statusCode = callEKK0351A010SC(param, handle, chafInHash, chafResultHash, FUNC_CODE_1);` // Option service contract agreement inquiry |
| 6 | IF | `statusCode != 0` → throw CCException with SCCallException |
| 7 | SET | `chafEKK0351A010SCHash = (HashMap)chafResultHash.get(TEMPLATE_ID_EKK0351A010);` // Extract result hash |
| 8 | SET | `opSvcCd = (String)chafEKK0351A010SCHash.get(OP_SVC_CD);` // Option service code |

**Block 6.2 — Multi-Session SOD processing (L11076)**

> Condition: `OP_SVC_CD_MLTISE.equals(opSvcCd)` [B015 = Multi-Session Service]

| # | Type | Code |
|---|------|------|
| 1 | SET | `this.op_svc_kei_no_mltise = chaf_opsvkei_no;` // Option service contract number (multi-session) |
| 2 | SET | `this.op_gadtm_mltise = chaf_opsvkei_gene_add_dtm;` // Reg datetime |
| 3 | SET | `this.svc_kei_ucwk_no = new String[1];` // Reset service key |
| 4 | SET | `this.svc_kei_ucwk_gadtm = new String[1];` // Reset reg datetime |
| 5 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no;` // Service contract detail number |
| 6 | SET | `this.svc_kei_ucwk_gadtm[0] = chaf_svc_kei_ucwk_gene_add_dtm;` // Reg datetime |
| 7 | SET | `this.old_vrsb_jdg_svc_dtl_cd = getOldVrsbIdgSvcDtlCd(handle, param, svc_kei_no, this.svc_kei_ucwk_no[0], this.pplan_cd);` // Old version judgment code (ANK-2765) |
| 8 | SET | `inHashMltise = new HashMap<String, Object>();` // Input hash for option lookup |
| 9 | SET | `resultHashMltise = new HashMap<String, Object>();` // Result hash |
| 10 | SET | `inHashMltise.put(SVC_KEI_NO, svc_kei_no);` // Service contract number |
| 11 | SET | `inHashMltise.put(OP_SVC_CD, OP_SVC_CD_FIXIPAD);` // Fixed IP address (used as filter) |
| 12 | SET | `inHashMltise.put(SVC_KEI_UCWK_NO, svc_kei_ucwk_no);` // Service contract detail number (OM-2014-0002316) |
| 13 | CALL | `statusCode = callEKK0351B002SC(param, handle, inHashMltise, resultHashMltise, FUNC_CODE_1);` // Option service contract list inquiry |
| 14 | SET | `msgList = (CAANMsg[])resultHashMltise.get(TEMPLATE_ID_EKK0351B002);` // Extract message list |

**Block 6.2.1 — Status-based SOD selection (L11100-L11117)**

> Loop through option service records to get status, then decide between static (144) and dynamic (142) multi-session SODs.

| # | Type | Code |
|---|------|------|
| 1 | LOOP | For each msgList[i] |
| 2 | SET | `retHash = msgList[i].getMsgData();` // Get record data |
| 3 | SET | `op_svc_kei_stat = retHash[OP_SVC_KEI_STAT].toString();` // Option service contract status |
| 4 | IF | `op_svc_kei_stat = SVC_KEI_STAT_030 OR SVC_KEI_STAT_100` [Contracted or In Service] |
| 5 | CALL | `param = addSOD(handle, param, ODR_NAIYO_CD_144);` // Multi-Session Static Registration SOD (144) |
| 6 | ELSE | |
| 7 | CALL | `param = addSOD(handle, param, ODR_NAIYO_CD_142);` // Multi-Session Dynamic Registration SOD (142) |

**Block 6.3 — Fixed IP SOD processing (L11123)**

> Condition: `OP_SVC_CD_FIXIPAD.equals(opSvcCd)` [B004 = Fixed IP Address Service]

| # | Type | Code |
|---|------|------|
| 1 | SET | `this.svc_kei_ucwk_no = new String[1];` // Reset service key |
| 2 | SET | `this.svc_kei_ucwk_gadtm = new String[1];` // Reset reg datetime |
| 3 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no;` // Service contract detail number |
| 4 | SET | `this.svc_kei_ucwk_gadtm[0] = chaf_svc_kei_ucwk_gene_add_dtm;` // Reg datetime |
| 5 | SET | `this.op_svc_kei_no_fixipad = chaf_opsvkei_no;` // Post-change option service contract number (fixed IP) |
| 6 | SET | `this.op_gadtm_fixipad = chaf_opsvkei_gene_add_dtm;` // Reg datetime |
| 7 | SET | `this.old_vrsb_jdg_svc_dtl_cd = getOldVrsbIdgSvcDtlCd(handle, param, svc_kei_no, this.svc_kei_ucwk_no[0], this.pplan_cd);` // Old version judgment code (ANK-2765) |
| 8 | SET | `inHashKoteiIp = new HashMap<String, Object>();` // Input hash for option lookup |
| 9 | SET | `resultHashKoteiIp = new HashMap<String, Object>();` // Result hash |
| 10 | SET | `inHashKoteiIp.put(SVC_KEI_NO, svc_kei_no);` // Service contract number |
| 11 | SET | `inHashKoteiIp.put(OP_SVC_CD, OP_SVC_CD_FIXIPAD);` // Fixed IP address |
| 12 | SET | `inHashKoteiIp.put(SVC_KEI_UCWK_NO, svc_kei_ucwk_no);` // Service contract detail number (OM-2014-0002316) |
| 13 | CALL | `statusCode = callEKK0351B002SC(param, handle, inHashKoteiIp, resultHashKoteiIp, FUNC_CODE_1);` // Option service contract list inquiry |
| 14 | SET | `msgList = (CAANMsg[])resultHashKoteiIp.get(TEMPLATE_ID_EKK0351B002);` // Extract message list |

**Block 6.3.1 — Fixed IP status-based SOD selection (L11153-L11159)**

> Loop through option service records to get status, then decide whether to emit a fixed IP registration SOD.

| # | Type | Code |
|---|------|------|
| 1 | LOOP | For each msgList[i] |
| 2 | SET | `retHash = msgList[i].getMsgData();` |
| 3 | SET | `op_svc_kei_stat = retHash[OP_SVC_KEI_STAT].toString();` // Option service contract status |
| 4 | IF | `op_svc_kei_stat = SVC_KEI_STAT_030 OR SVC_KEI_STAT_100` [Contracted or In Service] |
| 5 | CALL | `param = addSOD(handle, param, ODR_NAIYO_CD_152);` // Fixed IP Address Registration SOD (152) |

### Block 7 — AUTHENTICATION ID UNIFIED FALLBACK (L11172-L11181)

> Condition (ANK-2765-00-00, IT1-2016-0000106): `chgSvcKeiJdg(svc_kei_no) AND isBlank(svc_kei_ucwk_no) AND isBlank(chaf_svc_kei_ucwk_gene_add_dtm)`
> Business meaning: The authentication ID (svc_kei_ucwk_no) has not changed (both blank), but the service contract number has changed (indicating a course change with pricing plan code change only).

| # | 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);` // Fallback course change SOD emission |

### Block 8 — FINALIZE (L11186-L11189)

> Set `mae_recode_ch_svc_kei_no` if same_trn_no is not blank, and return the param.

| # | Type | Code |
|---|------|------|
| 1 | IF | `!isBlank(this.same_trn_no)` |
| 2 | SET | `this.mae_recode_ch_svc_kei_no = new String(svc_kei_no);` // Store service contract number for pre-record change tracking |
| 3 | RETURN | `return param;` // Return processed parameter object |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| SOD | Acronym | Service Order Data — an internal order record emitted by the system to trigger downstream business processes (equipment delivery, service activation, account changes) |
| Course Change | Business term | コース変更 — the process of changing a customer's contracted service plan/pricing plan while retaining their existing service contract |
| pcrs_cd | Field | Pricing Course Code — identifies the customer's current pricing plan (e.g., FTTH 100M, FTTH 5G, Mezon 100M, Type-N 1G) |
| svc_kei_no | Field | Service Contract Number — unique identifier for the customer's service contract |
| svc_kei_stat | Field | Service Contract Status — indicates the lifecycle stage of the service contract (010=Received, 020=Under Review, 030=Contracted, 100=In Service) |
| svc_kei_ucwk_no | Field | Service Contract Detail Number — identifies a specific version/line item of a service contract, used for authentication (FTTH) linkage |
| svc_kei_ucwk_gene_add_dtm | Field | Service Contract Detail Registration Date-Time — timestamp of when the service contract detail was registered |
| chbf_ | Prefix | Change Before — indicates data state before the course change |
| chaf_ | Prefix | Change After — indicates data state after the course change |
| opsvkei | Abbreviation | Option Service Contract — additional/secondary service contracts (multi-session, fixed IP) attached to the primary service |
| kktsvkei | Abbreviation | Equipment Provision Service Contract — service contracts for leased equipment (BBR routers, ONU, etc.) |
| BBR | Business term | Broadband Router — home gateway equipment leased to the customer for internet connectivity |
| FTTH | Business term | Fiber To The Home — fiber-optic broadband internet service |
| ODR_NAIYO_CD_101 | Constant | FTTH Auth Registration — SOD to register FTTH authentication for a new course |
| ODR_NAIYO_CD_103 | Constant | FTTH Auth Cancellation — SOD to cancel existing FTTH authentication |
| ODR_NAIYO_CD_104 | Constant | FTTH Auth Deletion — SOD to delete FTTH authentication records |
| ODR_NAIYO_CD_142 | Constant | Multi-Session Dynamic Registration — SOD to register dynamic multi-session service |
| ODR_NAIYO_CD_144 | Constant | Multi-Session Static Registration — SOD to register static multi-session service |
| ODR_NAIYO_CD_152 | Constant | Fixed IP Address Registration — SOD to register a fixed IP address |
| IDO_DIV | Field | Movement Division — indicates the type of change (e.g., IDO_DIV_COURSECHG = "01" for course change) |
| old_vrsb_jdg_svc_dtl_cd | Field | Old Version Identification Judgment Service Detail Code — used for authentication ID unification; stores the previous pricing plan code |
| same_trn_no | Field | Same Processing Number — shared transaction tracking ID across related course change operations |
| EKK0161B004SC | SC Code | Service Contract Detail List Inquiry SC — queries KK_T_SVC_KEI_UCWK table |
| EKK0351A010SC | SC Code | Option Service Contract Agreement Inquiry SC — queries KK_T_OP_SVC_KEI_ISP table |
| EKK0351B002SC | SC Code | Option Service Contract List Inquiry (by SVC KEI NO) SC — queries KK_T_OP_SVC_KEI_ISP table |
| Multi-Session | Business term | マルチセッション — a service allowing multiple concurrent sessions (dynamic or static type) |
| Fixed IP Address | Business term | 固定IPアドレス — a static IP address assigned to the customer's connection |
| ANK | Abbreviation | ANK — internal project/work code prefix for feature enhancements |
| OM | Abbreviation | OM — internal project code prefix for operation maintenance/bug fixes |
| IT | Abbreviation | IT — internal project code prefix for IT-related enhancements |
| Type-N | Business term | Type-N — NTT West's fiber service brand (NTT光) |
| Mezon | Business term | メゾン — K-Opticom's mid-range fiber plan |
| Manshon | Business term | マンション — K-Opticom's apartment-building fiber plan |
| jdgOdr163 | Method | Order 163 Judgment — equipment provision service contract judgment for course change orders (IT1-2013-0001691) |
| shkkaMap | Method | Map filter/search — internal utility to filter and validate sub-maps from sodMap |
| IP Type | Field | IP Type — indicates whether the IP is dynamic or fixed, used to classify option services |