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

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

## 1. Role

### JKKHakkoSODCC.courseChgeOdrCtrl()

This method performs the **course change order control process** (`コース変更オーダ制御処理`) for K-Opticom's telecommunications service fulfillment system. It is the central orchestrator that decides which Service Order Data (SOD) orders must be issued when a customer's Internet plan/course is changed — for example, upgrading from a 100M course to a 1G course, or changing the pricing tier of an eo Light Net contract.

The method handles **two distinct service lifecycle stages**: **pre-service** (contract status 010/020/030 — received, approved, or contracted but not yet providing) and **post-service** (contract status 100 — actively providing). For each stage, it determines which FTTH authentication registrations/cancellations, multi-session (multi-connection) registrations, and fixed global IP address registrations must be queued as SOD orders, based on the before-and-after state of the service contract details.

The method implements a **routing/dispatch pattern** — it extracts service state from the `sodMap`, validates that the price course is among the eligible course-change target courses, branches on the service contract status, and within each branch issues the appropriate sequence of SOD order creation calls (`addSOD`) to the downstream SOD issuance engine. It also delegates FTTH judgment logic (`jdgOdr163`) to a separate method.

This is a **shared utility component** called by `adchgFixOdrCtrl` (address-change fixed-order control) and `hakkoSOD` (order issuance), making it a critical node in the broader order-issuance pipeline.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["courseChgeOdrCtrl"])
    EXTRACT["Extract maps from sodMap:<br/>svc_kei_info, svc_kei_ucwk_info,<br/>opsvkei_info, kktsvkei_info"]
    CLEAN["Clean maps with shkkaMap()"]
    GET_VARS["Extract fields:<br/>svc_kei_no, svc_kei_ucwk_no,<br/>chaf_svc_kei_ucwk_gene_add_dtm,<br/>chaf_opsvkei_no,<br/>chaf_kktsvkei_no"]
    CHECK_PCRS{pcrs_cd is course-change<br/>eligible?}
    RETURN_EARLY["Return param early<br/>not course-change eligible"]
    CHECK_STAT{svc_kei_stat equals<br/>010/020/030?}
    PRE_SVC["(3) Pre-service course change<br/>processing"]
    CALL_CHG_JDG{"chgSvcKeiJdg<br/>contract number changed?"}
    EARLY_RETURN["Return param<br/>no change"]
    GET_SAME_TRN["getSame_trn_no<br/>acquire same transaction number"]
    INIT_ARRAYS["Init svc_kei_ucwk_no,<br/>svc_kei_ucwk_gadtm arrays"]
    CHECK_UCWK{svc_kei_ucwk_no AND<br/>chaf_svc_kei_ucwk_gene_add_dtm<br/>both non-null?}
    SET_UCWK_VARS["Set instance fields:<br/>svc_kei_ucwk_no, svc_kei_ucwk_gadtm,<br/>old_vrsb_jdg_svc_dtl_cd"]
    ADD_ODR_101["addSOD ODR_NAIYO_CD_101<br/>FTTH Registration"]
    QUERY_UCWK_LIST["callEKK0161B004SC<br/>Service Contract Detail List"]
    LOOP_COMPARE{"Loop: compare<br/>svc_kei_ucwk_no<br/>from query?"}
    CHECK_STAT_910_920{svc_kei_ucwk_stat<br/>equals 910 or 920?}
    CHECK_IDO_DIV{IDO_DIV equals<br/>00009 and GENE_ADD_DTM<br/>newer?}
    UPDATE_VARS["Update:<br/>chbf_svc_kei_ucwk_no,<br/>chbf_svc_kei_ucwk_gene_add_dtm"]
    ADD_ODR_103["addSOD ODR_NAIYO_CD_103<br/>FTTH Cancellation"]
    ADD_ODR_104["addSOD ODR_NAIYO_CD_104<br/>FTTH Deletion"]
    CHECK_KKTSVKEI{chaf_kktsvkei_no<br/>AND chaf_kktsvkei_gene_add_dtm<br/>both non-null?}
    SET_KKTK_VARS["Set device provision vars:<br/>kktk_svc_kei_no, kktk_svc_kei_gadtm,<br/>svc_kei_ucwk_no, svc_kei_ucwk_gadtm"]
    CALL_JDG163["jdgOdr163(handle, param, sodMap)"]
    CHECK_STAT_100{svc_kei_stat<br/>equals 100?}
    POST_SVC["(4) Post-service<br/>course change processing"]
    CALL_CHG_JDG2{"chgSvcKeiJdg<br/>contract number changed?"}
    SET_OLD_PPLAN["old_vrsb_jdg_svc_dtl_cd =<br/>getNewPplanCd()"]
    ADD_ODR_101_POST["addSOD ODR_NAIYO_CD_101<br/>FTTH Registration"]
    CHECK_KKTSVKEI2{chaf_kktsvkei_no<br/>AND chaf_kktsvkei_gene_add_dtm<br/>both non-null?}
    SET_KKTK_VARS2["Set device provision vars"]
    CALL_JDG163_2["jdgOdr163(handle, param, sodMap)"]
    CHECK_CHAF_OPSVKEI{chaf_opsvkei_no<br/>non-null and non-empty?}
    CALL_EKK0351A010["callEKK0351A010SC<br/>Option Service Contract Agreement"]
    GET_OP_SVC_CD{opSvcCd from result}
    CHECK_MLTISE{opSvcCd equals B015<br/>Multi-session?}
    SET_MLTISE_VARS["Set multi-session vars:<br/>op_svc_kei_no_mltise,<br/>op_gadtm_mltise,<br/>old_vrsb_jdg_svc_dtl_cd"]
    CALL_EKK0351B002["callEKK0351B002SC<br/>Option Service Contract List"]
    CHECK_OP_STAT{op_svc_kei_stat<br/>equals 030 or 100?}
    ADD_ODR_144["addSOD ODR_NAIYO_CD_144<br/>Multi-session Static Registration"]
    ADD_ODR_142["addSOD ODR_NAIYO_CD_142<br/>Multi-session Dynamic Registration"]
    CHECK_FIXIPAD{opSvcCd equals B004<br/>Fixed Global IP?}
    SET_FIXIPAD_VARS["Set fixed IP vars:<br/>op_svc_kei_no_fixipad,<br/>op_gadtm_fixipad,<br/>old_vrsb_jdg_svc_dtl_cd"]
    CALL_EKK0351B002_IP["callEKK0351B002SC<br/>Option Service Contract List (IP)"]
    CHECK_OP_STAT_IP{op_svc_kei_stat<br/>equals 030 or 100?}
    ADD_ODR_152["addSOD ODR_NAIYO_CD_152<br/>Fixed IP Registration"]
    CHECK_AUTHID{Authentication ID<br/>unchanged?}
    HAKKO_CHG_SOD["hakkoCourseChgSOD<br/>Issue course change SOD"]
    CHECK_SAME_TRN{same_trn_no<br/>non-blank?}
    SET_MAE_REC["mae_recode_ch_svc_kei_no = svc_kei_no"]
    END_RETURN["Return param"]

    START --> EXTRACT --> CLEAN --> GET_VARS --> CHECK_PCRS
    CHECK_PCRS -- No --> RETURN_EARLY --> END_RETURN
    CHECK_PCRS -- Yes --> CHECK_STAT
    CHECK_STAT -- Yes 010/020/030 --> PRE_SVC --> CALL_CHG_JDG
    CALL_CHG_JDG -- Yes --> GET_SAME_TRN --> INIT_ARRAYS --> CHECK_UCWK
    CHECK_UCWK -- Yes --> SET_UCWK_VARS --> ADD_ODR_101 --> QUERY_UCWK_LIST --> LOOP_COMPARE
    LOOP_COMPARE -- Match --> CHECK_STAT_910_920
    CHECK_STAT_910_920 -- Yes --> CHECK_IDO_DIV
    CHECK_IDO_DIV -- Yes --> UPDATE_VARS --> ADD_ODR_103 --> ADD_ODR_104 --> CHECK_KKTSVKEI
    CHECK_IDO_DIV -- No --> ADD_ODR_103 --> ADD_ODR_104 --> CHECK_KKTSVKEI
    CHECK_STAT_910_920 -- No --> ADD_ODR_103 --> ADD_ODR_104
    LOOP_COMPARE -- No match --> ADD_ODR_103
    CHECK_UCWK -- No --> ADD_ODR_103
    CHECK_KKTSVKEI -- Yes --> SET_KKTK_VARS --> CALL_JDG163
    CHECK_KKTSVKEI -- No --> CALL_JDG163
    CALL_CHG_JDG -- No --> EARLY_RETURN --> END_RETURN
    PRE_SVC --> CHECK_STAT_100
    CHECK_STAT -- No --> CHECK_STAT_100
    CHECK_STAT_100 -- Yes --> POST_SVC --> CALL_CHG_JDG2
    CALL_CHG_JDG2 -- Yes --> SET_OLD_PPLAN --> ADD_ODR_101_POST --> CHECK_KKTSVKEI2
    CALL_CHG_JDG2 -- No --> CHECK_CHAF_OPSVKEI
    CHECK_KKTSVKEI2 -- Yes --> SET_KKTK_VARS2 --> CALL_JDG163_2
    CHECK_KKTSVKEI2 -- No --> CALL_JDG163_2
    POST_SVC --> CHECK_CHAF_OPSVKEI
    CALL_JDG163 --> CHECK_CHAF_OPSVKEI
    CALL_JDG163_2 --> CHECK_CHAF_OPSVKEI
    CHECK_CHAF_OPSVKEI -- Yes --> CALL_EKK0351A010 --> GET_OP_SVC_CD
    CHECK_CHAF_OPSVKEI -- No --> CHECK_AUTHID
    GET_OP_SVC_CD --> CHECK_MLTISE
    CHECK_MLTISE -- Yes --> SET_MLTISE_VARS --> CALL_EKK0351B002 --> CHECK_OP_STAT
    CHECK_MLTISE -- No --> CHECK_FIXIPAD
    CHECK_OP_STAT -- Yes --> ADD_ODR_144 --> CHECK_FIXIPAD
    CHECK_OP_STAT -- No --> ADD_ODR_142 --> CHECK_FIXIPAD
    CHECK_FIXIPAD -- Yes --> SET_FIXIPAD_VARS --> CALL_EKK0351B002_IP --> CHECK_OP_STAT_IP
    CHECK_FIXIPAD -- No --> CHECK_AUTHID
    CHECK_OP_STAT_IP -- Yes --> ADD_ODR_152 --> CHECK_AUTHID
    CHECK_OP_STAT_IP -- No --> CHECK_AUTHID
    CHECK_AUTHID -- Yes --> HAKKO_CHG_SOD --> CHECK_SAME_TRN
    CHECK_AUTHID -- No --> CHECK_SAME_TRN
    CHECK_SAME_TRN -- Yes --> SET_MAE_REC --> END_RETURN
    CHECK_SAME_TRN -- No --> END_RETURN
```

**CRITICAL — Constant Resolution:**

| Constant | Resolved Value | Business Meaning |
|----------|---------------|-----------------|
| `PCRS_CD_100M` | `"A03"` | 100M Course |
| `PCRS_CD_100M_PRM` | `"A04"` | 100M Premium Course |
| `PCRS_CD_1G` | `"A05"` | 1G Course |
| `PCRS_CD_5G` | `"A89"` | 5G Course |
| `PCRS_CD_10G` | `"A83"` | 10G Course |
| `PCRS_CD_SIMPLE_10G` | `"A97"` | eo Light Simple Plan 10G Course |
| `PCRS_CD_SIMPLE_10G_NETFLIX` | `"A99"` | eo Light Simple Plan 10G Course Netflix Pack |
| `PCRS_CD_TYPE_N_1G` | `"AA0"` | eo Light Net (Type N) 1G Course [Home Type] |
| `PCRS_CD_TYPE_N_10G` | `"AA1"` | eo Light Net (Type N) 10G Course [Home Type] |
| `PCRS_CD_TYPE_N_MANS_100M` | `"AA2"` | eo Light Net (Type N) 100M Course [Mansion Type] |
| `PCRS_CD_TYPE_N_MANS_1G` | `"AA3"` | eo Light Net (Type N) 1G Course [Mansion Type] |
| `PCRS_CD_TYPE_N_MANS_10G` | `"AA4"` | eo Light Net (Type N) 10G Course [Mansion Type] |
| `PCRS_CD_TYPE_N_1G_NETFLIX` | `"AB0"` | eo Light Net (Type N) 1G Course [Home Type] Netflix Pack |
| `PCRS_CD_TYPE_N_10G_NETFLIX` | `"AB1"` | eo Light Net (Type N) 10G Course [Home Type] Netflix Pack |
| `PCRS_CD_TYPE_N_MANS_100M_NETFLIX` | `"AB2"` | eo Light Net (Type N) 100M Course [Mansion Type] Netflix Pack |
| `PCRS_CD_TYPE_N_MANS_1G_NETFLIX` | `"AB3"` | eo Light Net (Type N) 1G Course [Mansion Type] Netflix Pack |
| `PCRS_CD_TYPE_N_MANS_10G_NETFLIX` | `"AB4"` | eo Light Net (Type N) 10G Course [Mansion Type] Netflix Pack |
| `PCRS_CD_MEZON_100M` | `"A08"` | Mansion Type 100M |
| `PCRS_CD_MEZON_100M_PRM` | `"A09"` | Mansion Type 100M Premium |
| `PCRS_CD_MEZON_1G` | `"A10"` | Mansion Type 1G |
| `PCRS_CD_MEZON_200M` | `"A11"` | Mansion Type 200M |
| `PCRS_CD_MEZON_5G` | `"A90"` | Mansion Type 5G |
| `PCRS_CD_MEZON_10G` | `"A84"` | Mansion Type 10G |
| `PCRS_CD_MEZON_1G_NETFLIX` | `"A92"` | Mansion Type 1G Netflix Pack |
| `PCRS_CD_MEZON_5G_NETFLIX` | `"A94"` | Mansion Type 5G Netflix Pack |
| `PCRS_CD_MEZON_10G_NETFLIX` | `"A96"` | Mansion Type 10G Netflix Pack |
| `PCRS_CD_MANS_GLB_MHIKARI` | `"A56"` | Mansion Global 100M Light |
| `PCRS_CD_MANS_GLB_MHIKARI_PRM` | `"A71"` | Mansion Global 100M Premium Light |
| `PCRS_CD_MANS_GLB_GHIKARI` | `"A57"` | Mansion Global 1G Light |
| `PCRS_CD_MANS_GLB_10GHIKARI` | `"A74"` | Mansion Global 10G Light |
| `CD00134_A50` through `CD00134_A53` | `"A50"-"A53"` | Mansion Global various VDSL courses |
| `CD00134_GLB100M_PREMIUM_VDSL` | Premium VDSL | Global Premium VDSL 100M |
| `CD00134_GLB100M_PREMIUM_ETHER` | Premium Ethernet | Global Premium Ethernet 100M |
| `SVC_KEI_STAT_010` | `"010"` | Received (not yet approved) |
| `SVC_KEI_STAT_020` | `"020"` | Approved (pending service start) |
| `SVC_KEI_STAT_030` | `"030"` | Contracted (service not yet providing) |
| `SVC_KEI_STAT_100` | `"100"` | Service Providing (actively in use) |
| `SVC_KEI_STAT_910` | `"910"` | Disputed |
| `SVC_KEI_STAT_920` | `"920"` | Cancelled |
| `IDO_DIV_COURSECHG` | `"00009"` | Dispute reason code: Course Change |
| `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"` | Multi-session (Dynamic) Registration |
| `ODR_NAIYO_CD_144` | `"144"` | Multi-session (Static) Registration |
| `ODR_NAIYO_CD_152` | `"152"` | Fixed Global IP Address Registration |
| `OP_SVC_CD_MLTISE` | `"B015"` | Multi-session (multi-connection) option service |
| `OP_SVC_CD_FIXIPAD` | `"B004"` | Fixed global IP address option service |

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `handle` | `SessionHandle` | Session handle carrying session management context (transaction/session state) used for database and service component calls |
| 2 | `param` | `IRequestParameterReadWrite` | Parameter object containing the model group and control map; serves as the input/output carrier for business data retrieval and writing |
| 3 | `fixedText` | `String` | User-specified arbitrary string — passed through to `hakkoCourseChgSOD` for audit/tracking purposes |
| 4 | `sodMap` | `HashMap<String, Object>` | SOD (Service Order Data) map containing nested sub-maps for each contract dimension: service contract info, service contract detail info, option service contract info, and equipment provision service contract info |

**Instance fields read by this method:**

| Field | Type | Business Description |
|-------|------|---------------------|
| `pcrs_cd` | `String` | Price course code — determines whether this contract is eligible for course change processing |
| `svc_kei_stat` | `String` | Service contract status — determines whether the service is pre-service (010/020/030) or actively providing (100) |

## 4. CRUD Operations / Called Services

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

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `JKKHakkoSODCC.shkkaMap` | - | - | Clean/normalize maps extracted from `sodMap` (service contract info, service contract detail info, option service contract info, equipment provision service contract info) |
| R | `JKKHakkoSODCC.callEKK0161B004SC` | EKK0161B004SC | Service Contract Detail Inquiry (SVC_KEI_UCWK list) | Query the list of service contract details for the given `svc_kei_no`; used to find the contract detail number before the course change when the current detail differs from the expected one |
| R | `JKKHakkoSODCC.callEKK0351A010SC` | EKK0351A010SC | Option Service Contract Agreement | Execute agreement inquiry for option service contract (before/after course change); retrieves option service code (`opSvcCd`) such as B015 (multi-session) or B004 (fixed global IP) |
| R | `JKKHakkoSODCC.callEKK0351B002SC` | EKK0351B002SC | Option Service Contract List | Query the list of option service contracts by `svc_kei_no` to determine the option service contract status (`op_svc_kei_stat`) for registration eligibility |
| R | `JKKHakkoSODCC.getNewPplanCd` | - | - | Retrieve the new price plan code for old VR (version/revision) identification judgment when service is actively providing |
| R | `JKKHakkoSODCC.getOldVrsbIdgSvcDtlCd` | - | - | Retrieve the old version identification service detail code for comparison purposes during post-service course change |
| R | `JKKHakkoSODCC.getSame_trn_no` | - | - | Acquire a shared transaction number (`same_trn_no`) for grouping related course change SOD orders together |
| C | `JKKHakkoSODCC.addSOD` | - | Service Order Data (SOD) | Create a new SOD order record for each specified order content code (101, 103, 104, 142, 144, 152, etc.) |
| - | `JKKHakkoSODCC.chgSvcKeiJdg` | - | - | Judge whether the service contract number has changed compared to the previous processing record |
| - | `JKKHakkoSODCC.isBlank` | - | - | Utility to check if a string is null or empty |
| - | `JKKHakkoSODCC.jdgOdr163` | - | - | Delegate FTTH order judgment logic (FTTH order content determination) to a separate processing method |
| - | `JKKHakkoSODCC.hakkoCourseChgSOD` | - | Service Order Data (SOD) | Issue the course change SOD when the authentication ID has not changed (only price plan code changed) |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Method: `JKKHakkoSODCC.adchgFixOdrCtrl` | `adchgFixOdrCtrl` -> `courseChgeOdrCtrl` | `addSOD [C] SOD`, `callEKK0351B002SC [R] Option Service Contract`, `callEKK0351A010SC [R] Option Service Agreement`, `getOldVrsbIdgSvcDtlCd [R] Service Detail` |
| 2 | Method: `JKKHakkoSODCC.hakkoSOD` | `hakkoSOD` -> `courseChgeOdrCtrl` | `addSOD [C] SOD`, `callEKK0351B002SC [R] Option Service Contract`, `callEKK0351A010SC [R] Option Service Agreement`, `getSame_trn_no [R] Transaction No`, `chgSvcKeiJdg [-] Contract Number Check`, `jdgOdr163 [-] FTTH Order Judgment` |

## 6. Per-Branch Detail Blocks

### Block 1 — INIT (lines 10675–10698)

> Extract and clean all nested maps from the `sodMap` parameter, then extract key fields from each map.

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | SET | `chafEKK0351A010SCHash = null` | Initialize after-change option service contract agreement hash (commented-out before-change hash not used) |
| 2 | SET | `svc_kei_info_Map = sodMap.get(SVC_KEI_INFO)` | Extract service contract info map |
| 3 | SET | `svc_kei_ucwk_info_Map = sodMap.get(SVC_KEI_UCWK_INFO)` | Extract service contract detail info map |
| 4 | SET | `opsvkei_info_Map = sodMap.get(OPSVKEI_INFO)` | Extract option service contract info map |
| 5 | SET | `kktsvkei_info_Map = sodMap.get(KKTSVKEI_INFO)` | Extract equipment provision service contract info map |
| 6 | CALL | `shkkaMap(svc_kei_info_Map)` | Clean/normalize service contract info map |
| 7 | CALL | `shkkaMap(svc_kei_ucwk_info_Map)` | Clean/normalize service contract detail info map |
| 8 | CALL | `shkkaMap(opsvkei_info_Map)` | Clean/normalize option service contract info map |
| 9 | CALL | `shkkaMap(kktsvkei_info_Map)` | Clean/normalize equipment provision service contract info map |

### Block 2 — FIELD EXTRACTION (lines 10699–10722)

> Extract course-change-required parameters from each map.

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | SET | `svc_kei_no = svc_kei_info_Map.get(INFO_SVC_KEI_NO)` | Service contract number |
| 2 | SET | `svc_kei_ucwk_no = svc_kei_ucwk_info_Map.get(INFO_SVC_KEI_UCWK_NO)` | Service contract detail number (after change) |
| 3 | SET | `chbf_svc_kei_ucwk_gene_add_dtm = svc_kei_ucwk_info_Map.get(INFO_CHBF_SVC_KEI_UCWK_GENE_ADD_DTM)` | Before-change service contract detail registration date-time |
| 4 | SET | `chaf_svc_kei_ucwk_gene_add_dtm = svc_kei_ucwk_info_Map.get(INFO_CHAF_SVC_KEI_UCWK_GENE_ADD_DTM)` | After-change service contract detail registration date-time |
| 5 | SET | `chaf_opsvkei_no = opsvkei_info_Map.get(INFO_CHAF_OPSVKEI_NO)` | After-change option service contract number |
| 6 | SET | `chaf_opsvkei_gene_add_dtm = opsvkei_info_Map.get(INFO_CHAF_OPSVKEI_GENE_ADD_DTM)` | After-change option service contract registration date-time |
| 7 | SET | `chaf_kktsvkei_no = kktsvkei_info_Map.get(INFO_CHAF_KKTSVKEI_NO)` | After-change equipment provision service contract number |
| 8 | SET | `chaf_kktsvkei_gene_add_dtm = kktsvkei_info_Map.get(INFO_CHAF_KKTSVKEI_GENE_ADD_DTM)` | After-change equipment provision service contract registration date-time |

### Block 3 — COURSE CHANGE ELIGIBILITY CHECK (lines 10723–10805)

> Check whether the `pcrs_cd` (price course code) is among the course-change-eligible courses. If not, return early.

**Condition:** `pcrs_cd` does NOT match any of the eligible price course codes

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | IF | `!pcrs_cd.equals(A03) && !A04 && !A05 && !A06 && !A07 && !A89 && !A83 && !A97 && !A99 && !AA0 && !AA1 && !AA2 && !AA3 && !AA4 && !AB0 && !AB1 && !AB2 && !AB3 && !AB4 && !A08 && !A09 && !A10 && !A11 && !A90 && !A84 && !pcrs_cd.matches("^A5[45]") && !CD00134_A50 && !CD00134_A51 && !CD00134_A52 && !CD00134_A53 && !CD00134_GLB100M_PREMIUM_VDSL && !CD00134_GLB100M_PREMIUM_ETHER && !A56 && !A57 && !A74 && !A71 && !A91 && !A92 && !A93 && !A94 && !A95 && !A96` | [PCRS_CD] Price course code is NOT course-change eligible |

### Block 3.1 — EARLY RETURN (lines 10806–10808)

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | RETURN | `return param` | Return parameter unchanged — not a course-change-eligible contract |

### Block 4 — PRE-SERVICE COURGE CHANGE (lines 10811–10931)

> Process course change when the service contract status is **010** (Received), **020** (Approved), or **030** (Contracted) — i.e., before service starts.

**Condition:** `svc_kei_stat` equals `"010"` OR `"020"` OR `"030"`

### Block 4.1 — CONTRACT NUMBER CHANGE CHECK (lines 10818–10819)

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | IF | `chgSvcKeiJdg(svc_kei_no)` | Service contract number differs from previous processing record |

### Block 4.1.1 — NO CHANGE BRANCH (lines 10819–10820)

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | IF_NO_MATCH | (no contract number change) | Return param — no course change processing needed |

### Block 4.1.2 — CHANGE DETECTED (lines 10822–10931)

> The contract number has changed. Set up transaction tracking and issue SOD orders.

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | SET | `sameTrnNo = new String[1]` | Create array for same transaction number |
| 2 | CALL | `getSame_trn_no(param, handle, null, sameTrnNo)` | Acquire the shared transaction number for this batch of course change orders |
| 3 | SET | `this.same_trn_no = sameTrnNo[0]` | Store the transaction number in instance field |
| 4 | SET | `this.svc_kei_ucwk_no = new String[1]` | Initialize service contract detail number array |
| 5 | SET | `this.svc_kei_ucwk_gadtm = new String[1]` | Initialize service contract detail registration date-time array |

### Block 4.1.3 — AUTHENTICATION ID VALIDATION (lines 10829–10840)

> Before issuing FTTH orders, validate that the service contract detail number and after-change registration date-time are both present.

**Condition:** `svc_kei_ucwk_no != null && length > 0 && chaf_svc_kei_ucwk_gene_add_dtm != null && length > 0` [IT1-2012-0002125: If speed unchanged, no FTTH auth/registration needed]

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no` | Set instance field with service contract detail number |
| 2 | SET | `this.svc_kei_ucwk_gadtm[0] = chaf_svc_kei_ucwk_gene_add_dtm` | Set instance field with registration date-time |
| 3 | SET | `this.old_vrsb_jdg_svc_dtl_cd = this.pplan_cd` [ANK-2765-00-00] | Set old VR identification code from current price plan code |
| 4 | CALL | `addSOD(handle, param, ODR_NAIYO_CD_101)` [FTTH Registration] | Issue FTTH authentication registration SOD |

### Block 4.1.4 — OLD AUTH ID DETECTION LOOP (lines 10847–10896)

> Query all service contract details for this `svc_kei_no` to find the detail number before the course change (if authentication ID changed).

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | SET | `inHashUcwk = new HashMap` | Initialize input hash for query |
| 2 | SET | `resultHashUcwk = new HashMap` | Initialize result hash for query |
| 3 | SET | `inHashUcwk.put(SVC_KEI_NO, svc_kei_no)` | Set service contract number as query key |
| 4 | CALL | `callEKK0161B004SC(param, handle, inHashUcwk, resultHashUcwk, FUNC_CODE_1)` | Query service contract detail list [EKK0161B004: Service Contract Detail Agreement] |
| 5 | SET | `msgListUcwk = resultHashUcwk.get(TEMPLATE_ID_EKK0161B004)` | Get result message array |
| 6 | FOR | `for(i = 0; i < msgListUcwk.length; i++)` | Loop through each service contract detail record |
| 7 | SET | `retHash = msgListUcwk[i].getMsgData()` | Extract map from message |
| 8 | IF | `retHash.get(SVC_KEI_UCWK_NO).equals(svc_kei_ucwk_no)` | Same detail number — skip (already the current one) |
| 9 | ELSE | — | Detail number differs, check status |
| 10 | IF | `retHash.get(SVC_KEI_UCWK_STAT) equals 910 OR 920` | Status is disputed or cancelled |
| 11 | IF | `IDO_DIV equals 00009 AND GENE_ADD_DTM newer` [IDO_DIV_COURSECHG = "00009"] | Dispute reason is course change AND this record is newer |
| 12 | SET | `chbf_svc_kei_ucwk_no = retHash.get(SVC_KEI_UCWK_NO)` | Preserve the before-change detail number |
| 13 | SET | `chbf_svc_kei_ucwk_gene_add_dtm = retHash.get(GENE_ADD_DTM)` | Preserve the before-change registration date-time |
| 14 | SET | `this.svc_kei_ucwk_no[0] = chbf_svc_kei_ucwk_no` | Update instance field with before-change detail number |
| 15 | SET | `this.svc_kei_ucwk_gadtm[0] = chbf_svc_kei_ucwk_gene_add_dtm` | Update instance field with before-change date-time |
| 16 | BREAK | — | Exit loop — found the right before-change record |

### Block 4.1.5 — FTTH CANCELLATION AND DELETION (lines 10905–10909)

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | CALL | `addSOD(handle, param, ODR_NAIYO_CD_103)` [FTTH Cancellation] | Issue FTTH authentication cancellation SOD |
| 2 | CALL | `addSOD(handle, param, ODR_NAIYO_CD_104)` [FTTH Deletion] | Issue FTTH authentication deletion SOD |

### Block 4.1.6 — EQUIPMENT PROVISION SERVICE (lines 10918–10929)

> If after-change equipment provision service contract info is available, set up device provisioning variables.

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

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | SET | `this.kktk_svc_kei_no[0] = chaf_kktsvkei_no` | Set after-change equipment provision contract number |
| 2 | SET | `this.kktk_svc_kei_gadtm[0] = chaf_kktsvkei_gene_add_dtm` | Set after-change equipment provision registration date-time |
| 3 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no` | Set service contract detail number |
| 4 | SET | `this.svc_kei_ucwk_gadtm[0] = chaf_svc_kei_ucwk_gene_add_dtm` | Set service contract detail registration date-time |
| 5 | CALL | `jdgOdr163(handle, param, sodMap)` | Delegate FTTH order judgment processing |

### Block 5 — POST-SERVICE COURSE CHANGE (lines 10943–10966)

> Process course change when the service contract status is **100** (Service Providing) — i.e., the service is actively in use.

**Condition:** `svc_kei_stat` equals `"100"`

### Block 5.1 — CONTRACT NUMBER CHANGE CHECK (lines 10950–10951)

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | IF | `chgSvcKeiJdg(svc_kei_no)` | Service contract number differs from previous processing record |

### Block 5.1.1 — CHANGE DETECTED (lines 10952–10963)

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | SET | `sameTrnNo = new String[1]` | Create array for same transaction number |
| 2 | CALL | `getSame_trn_no(param, handle, null, sameTrnNo)` | Acquire shared transaction number |
| 3 | SET | `this.same_trn_no = sameTrnNo[0]` | Store transaction number |
| 4 | SET | `this.svc_kei_ucwk_no = new String[1]` | Initialize arrays |
| 5 | SET | `this.svc_kei_ucwk_gadtm = new String[1]` | Initialize arrays |
| 6 | IF | `svc_kei_ucwk_no != null && chaf_svc_kei_ucwk_gene_add_dtm != null` | Authentication ID validation |
| 7 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no` | Set service contract detail number |
| 8 | SET | `this.svc_kei_ucwk_gadtm[0] = chaf_svc_kei_ucwk_gene_add_dtm` | Set registration date-time |
| 9 | SET | `this.old_vrsb_jdg_svc_dtl_cd = getNewPplanCd(handle, param, svc_kei_no)` [ANK-2765-00-00] | Get new price plan code for old VR identification judgment |
| 10 | CALL | `addSOD(handle, param, ODR_NAIYO_CD_101)` [FTTH Registration] | Issue FTTH authentication registration SOD |

### Block 5.1.2 — EQUIPMENT PROVISION SERVICE (lines 10968–10979)

> Set device provisioning variables when equipment provision info is present.

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

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | SET | `this.kktk_svc_kei_no[0] = chaf_kktsvkei_no` | Set device provision contract number |
| 2 | SET | `this.kktk_svc_kei_gadtm[0] = chaf_kktsvkei_gene_add_dtm` | Set device provision registration date-time |
| 3 | CALL | `jdgOdr163(handle, param, sodMap)` | Delegate FTTH order judgment processing |

### Block 6 — OPTION SERVICE CONTRACT PROCESSING (lines 10991–11112)

> After both pre-service and post-service branches, process option service contracts (multi-session and fixed global IP address) if `chaf_opsvkei_no` is present. This is **unified logic** shared by both branches.

**Condition:** `chaf_opsvkei_no != null && !"".equals(chaf_opsvkei_no)`

### Block 6.1 — QUERY AFTER-CHANGE OPTION SERVICE (lines 10997–11012)

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | SET | `chafInHash = new HashMap` | Initialize input hash |
| 2 | SET | `chafInHash.put(OP_SVC_KEI_NO, chaf_opsvkei_no)` | Set option service contract number |
| 3 | SET | `chafInHash.put(GENE_ADD_DTM, chaf_opsvkei_gene_add_dtm)` | Set registration date-time |
| 4 | CALL | `callEKK0351A010SC(param, handle, chafInHash, chafResultHash, FUNC_CODE_1)` | Query option service contract agreement [EKK0351A010] |
| 5 | SET | `chafEKK0351A010SCHash = chafResultHash.get(TEMPLATE_ID_EKK0351A010)` | Extract result hash |
| 6 | SET | `opSvcCd = chafEKK0351A010SCHash.get(OP_SVC_CD)` | Get option service code (B015 or B004) |

### Block 6.2 — MULTI-SESSION OPTION SERVICE (lines 11018–11079)

> When the after-change option service code is **B015** (Multi-session / Multi-connection).

**Condition:** `opSvcCd` equals `"B015"` [OP_SVC_CD_MLTISE]

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | SET | `this.op_svc_kei_no_mltise = chaf_opsvkei_no` | Set multi-session option service contract number |
| 2 | SET | `this.op_gadtm_mltise = chaf_opsvkei_gene_add_dtm` | Set multi-session registration date-time |
| 3 | SET | `this.svc_kei_ucwk_no = new String[1]` [IT1-2012-0001514] | Initialize service contract detail number array |
| 4 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no` | Set service contract detail number |
| 5 | SET | `this.svc_kei_ucwk_gadtm[0] = chaf_svc_kei_ucwk_gene_add_dtm` | Set service contract detail registration date-time |
| 6 | SET | `this.old_vrsb_jdg_svc_dtl_cd = getOldVrsbIdgSvcDtlCd(handle, param, svc_kei_no, svc_kei_ucwk_no[0], pplan_cd)` [ANK-2765-00-00] | Get old VR identification service detail code |
| 7 | SET | `inHashMltise = new HashMap` | Initialize input hash for option list query |
| 8 | SET | `inHashMltise.put(SVC_KEI_NO, svc_kei_no)` | Set service contract number |
| 9 | SET | `inHashMltise.put(OP_SVC_CD, OP_SVC_CD_FIXIPAD)` | Set option service code for fixed IP [query for other option types] |
| 10 | SET | `inHashMltise.put(SVC_KEI_UCWK_NO, svc_kei_ucwk_no)` [OM-2014-0002316] | Set service contract detail number |
| 11 | CALL | `callEKK0351B002SC(param, handle, inHashMltise, resultHashMltise, FUNC_CODE_1)` | Query option service contract list [EKK0351B002] |
| 12 | SET | `msgList = resultHashMltise.get(TEMPLATE_ID_EKK0351B002)` | Get result message array |
| 13 | FOR | `for(i = 0; i < msgList.length; i++)` | Loop through option service contract records |
| 14 | SET | `op_svc_kei_stat = retHash.get(OP_SVC_KEI_STAT)` | Extract option service contract status |
| 15 | IF | `op_svc_kei_stat equals 030 OR 100` | Contracted or service providing |
| 16 | CALL | `addSOD(handle, param, ODR_NAIYO_CD_144)` [Multi-session Static Registration] | Register static multi-session SOD |
| 17 | ELSE | — | Not contracted/providing |
| 18 | CALL | `addSOD(handle, param, ODR_NAIYO_CD_142)` [Multi-session Dynamic Registration] | Register dynamic multi-session SOD |

### Block 6.3 — FIXED GLOBAL IP ADDRESS OPTION SERVICE (lines 11085–11112)

> When the after-change option service code is **B004** (Fixed Global IP Address).

**Condition:** `opSvcCd` equals `"B004"` [OP_SVC_CD_FIXIPAD]

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | SET | `this.svc_kei_ucwk_no = new String[1]` | Initialize service contract detail number array |
| 2 | SET | `this.svc_kei_ucwk_no[0] = svc_kei_ucwk_no` | Set service contract detail number |
| 3 | SET | `this.svc_kei_ucwk_gadtm[0] = chaf_svc_kei_ucwk_gene_add_dtm` | Set registration date-time |
| 4 | SET | `this.op_svc_kei_no_fixipad = chaf_opsvkei_no` | Set fixed IP option service contract number |
| 5 | SET | `this.op_gadtm_fixipad = chaf_opsvkei_gene_add_dtm` | Set fixed IP registration date-time |
| 6 | SET | `this.old_vrsb_jdg_svc_dtl_cd = getOldVrsbIdgSvcDtlCd(handle, param, svc_kei_no, svc_kei_ucwk_no[0], pplan_cd)` [ANK-2765-00-00] | Get old VR identification service detail code |
| 7 | SET | `inHashKoteiIp = new HashMap` | Initialize input hash for fixed IP query |
| 8 | SET | `inHashKoteiIp.put(SVC_KEI_NO, svc_kei_no)` | Set service contract number |
| 9 | SET | `inHashKoteiIp.put(OP_SVC_CD, OP_SVC_CD_FIXIPAD)` | Set fixed global IP option service code |
| 10 | SET | `inHashKoteiIp.put(SVC_KEI_UCWK_NO, svc_kei_ucwk_no)` [OM-2014-0002316] | Set service contract detail number |
| 11 | CALL | `callEKK0351B002SC(param, handle, inHashKoteiIp, resultHashKoteiIp, FUNC_CODE_1)` | Query option service contract list [EKK0351B002] |
| 12 | SET | `msgList = resultHashKoteiIp.get(TEMPLATE_ID_EKK0351B002)` | Get result message array |
| 13 | FOR | `for(i = 0; i < msgList.length; i++)` | Loop through option service contract records |
| 14 | SET | `op_svc_kei_stat = retHash.get(OP_SVC_KEI_STAT)` | Extract option service contract status |
| 15 | IF | `op_svc_kei_stat equals 030 OR 100` | Contracted or service providing |
| 16 | CALL | `addSOD(handle, param, ODR_NAIYO_CD_152)` [Fixed Global IP Registration] | Register fixed global IP address SOD |

### Block 7 — AUTHENTICATION ID UNCHANGED CHECK (lines 11117–11124)

> If the authentication ID (service contract detail number) has not changed — meaning only the price plan/course changed — issue the course change SOD through the `hakkoCourseChgSOD` method.

**Condition:** `chgSvcKeiJdg(svc_kei_no) && isBlank(svc_kei_ucwk_no) && isBlank(chaf_svc_kei_ucwk_gene_add_dtm)` [IT1-2016-0000106]

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | IF | Contract number changed AND authentication ID unchanged (svc_kei_ucwk_no blank AND chaf_svc_kei_ucwk_gene_add_dtm blank) | Only the price plan/course changed, not the authentication ID |
| 2 | CALL | `hakkoCourseChgSOD(handle, param, fixedText)` | Issue course change SOD for price plan change-only |

### Block 8 — FINALIZATION (lines 11127–11130)

| # | Type | Code | Business Description |
|---|------|------|---------------------|
| 1 | IF | `!isBlank(this.same_trn_no)` | Transaction number was acquired |
| 2 | SET | `this.mae_recode_ch_svc_kei_no = new String(svc_kei_no)` | Record the "before record change" service contract number |
| 3 | RETURN | `return param` | Return the processed parameter object |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|-----------------|
| `svc_kei_no` | Field | Service contract number — unique identifier for a service contract line item |
| `svc_kei_ucwk_no` | Field | Service contract detail number — internal tracking ID for service contract details (authentication ID for FTTH) |
| `svc_kei_stat` | Field | Service contract status — lifecycle state of the contract (010=Received, 020=Approved, 030=Contracted, 100=Service Providing, 910=Disputed, 920=Cancelled) |
| `pcrs_cd` | Field | Price course code — identifies the specific pricing plan (e.g., A03=100M, A05=1G, A83=10G, A97=eo Light Simple 10G) |
| `pplan_cd` | Field | Price plan code — historical VR identification value used for course change dispute tracking |
| `chbf_svc_kei_ucwk_no` | Field | Before-change service contract detail number |
| `chaf_svc_kei_ucwk_no` | Field | After-change service contract detail number |
| `chbf_svc_kei_ucwk_gene_add_dtm` | Field | Before-change service contract detail registration date-time (YYYYMMDDHHmmssSSS) |
| `chaf_svc_kei_ucwk_gene_add_dtm` | Field | After-change service contract detail registration date-time |
| `op_svc_kei_no` | Field | Option service contract number — identifies option services like multi-session or fixed IP |
| `op_svc_kei_stat` | Field | Option service contract status — indicates whether the option service is contracted (030) or providing (100) |
| `kktk_svc_kei_no` | Field | Equipment provision service contract number — for device-related services (BBR, MRT, etc.) |
| `same_trn_no` | Field | Shared transaction number — groups multiple SOD orders created by the same course change operation |
| `mae_recode_ch_svc_kei_no` | Field | Before-record-change service contract number — tracks the previous contract number for audit trail |
| `old_vrsb_jdg_svc_dtl_cd` | Field | Old version identification service detail code — used to determine if the price plan actually changed |
| SOD | Acronym | Service Order Data — the internal order fulfillment entity used to trigger operational actions |
| FTTH | Business term | Fiber To The Home — fiber-optic broadband internet service (eo Light Net) |
| BBR | Acronym | Broadband Router — router equipment provision service (BBR code C014) |
| MRT | Acronym | Multi-router — multi-router equipment provision service (C024) |
| VA | Acronym | Virtual Account — VoIP phone service (C004 for telephone VA) |
| HGW | Acronym | Home Gateway — eo Home Gateway device service (C025) |
| Multi-session | Business term | Multi-connection option service (B015) — allows multiple concurrent connections |
| Fixed Global IP | Business term | Fixed global IP address option service (B004) — reserves a static public IP address |
| Multi-session Dynamic | Business term | Dynamic multi-session registration (ODR_NAIYO_CD_142) — for non-contracted/multi-session |
| Multi-session Static | Business term | Static multi-session registration (ODR_NAIYO_CD_144) — for contracted/static multi-session |
| Course Change | Business term | Service plan/course change — upgrading or downgrading the broadband speed tier or pricing plan |
| 100M Course | Business term | 100 Megabit course (A03) — base speed tier |
| 1G Course | Business term | 1 Gigabit course (A05) — high-speed tier |
| 5G Course | Business term | 5 Gigabit course (A89) — premium speed tier |
| 10G Course | Business term | 10 Gigabit course (A83) — maximum speed tier |
| Mansion Type | Business term | Apartment/mansion building service tier (different pricing and provisioning from home type) |
| Type N | Business term | eo Light Net Type N — specific service type for certain provisioning scenarios |
| Netflix Pack | Business term | Bundled Netflix streaming service add-on for compatible courses |
| 異動区分 | Field | Dispute/movement reason code (IDO_DIV) — 00009 indicates course change as the dispute reason |
| 登録年月日時 | Field | Registration date-time — timestamp when a contract detail was registered (format: YYYYMMDDHHmmssSSS) |
| 契約番号 | Field | Contract number — the service contract line item identifier |
| 認証ID | Field | Authentication ID — FTTH authentication identifier (service contract detail number) |
| 課金情報 | Field | Billing information — data used for billing calculations including price courses and plans |
| コース変更 | Business term | Course change — the act of changing a customer's broadband service plan/price tier |
| 業務データ取得・書込用/I/F | Field | Business data retrieval and writing interface — the parameter object type for data transport |
| セッションマネージャ | Field | Session manager — handles session state management for the transaction |
