# Business Logic — JBSbatKKAdChgSodUpd.setWrisvcAutoAply() [337 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `eo.business.service.JBSbatKKAdChgSodUpd` |
| Layer | Batch Service |
| Module | `service` (Package: `eo.business.service`) |

## 1. Role

### JBSbatKKAdChgSodUpd.setWrisvcAutoAply()

This method orchestrates the preparation of **discount service automatic application data** (割引サービス自動適用) in the context of a **residential address change** (住所変更) batch job. Its purpose is to analyze the before-and-after service contract lines associated with a given address change record and build structured parameter maps (CC HashMaps) that describe what actions need to be taken on each service contract.

The method processes address change detail records through **three sequential passes**, each targeting a distinct business scenario:

- **Pass 1 — Old contract resignation**: When a before-service contract number exists and differs from the after-service contract number, it treats the old contract as being **resigned/cancelled** (解約) and flags it with `add_chge_div = "03"`. This handles the scenario where the customer's former service line is being decommissioned as part of the move.
- **Pass 2 — New contract registration**: When an after-service contract number exists and differs from the before-service contract number, it registers the new contract as a **new registration** (登録) with `add_chge_div = "01"`. This captures newly provisioned service lines at the new address.
- **Pass 3 — Unchanged contract fee exemption removal**: When both before and after service contract numbers are identical (the contract line is unchanged), it applies a special flag (`add_chge_div = "17"`, KOJIHI_KAP_CP_DEL — 工事費割賦CP削除) to remove construction fee installment charges from the unchanged contract. This was introduced to fix a bug where discount application CC was not being called when a residential address change was confirmed from HT to MT with the same contract number.

The method uses a **builder/delegation pattern**: it queries data, constructs detailed HashMap parameter structures (mirroring the format expected by `KKSV056503CC` — a screen-level component), and accumulates them into the instance-level `wrisvc_auto_aply_list` for downstream batch processing. A **dedup guard** prevents re-processing the same `adchgNo` within a single batch run by tracking processed IDs in `adchgNoList`.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["setWrisvcAutoAply(adchgNo, mskmNo)"])
    CHECK_DUPLICATE{"adchgNo already in<br>adchgNoList?"}
    GET_ADCHG_DTL_1["getAdChgDtlInfo(adchgNo)<br>first query"]
    LOOP1{"adchgDtlInfo<br>not null?"}
    GET_BF_AFK{"Extract bfSvcKeiNo and afSvcKeiNo"}
    CHECK_CHANGE{"bfSvcKeiNo != afSvcKeiNo<br>(old contract changed)?"}
    GET_SVC_KEI_1["getSvcKeiInfo(bfSvcKeiNo)<br>query old contract"]
    BUILD_CC_1["Build kKSV056503CC HashMap<br>add_chge_div = 03 (resignation)<br>func_code = 1<br>ido_div = CD00576_ADCHG_ADD<br>mskm_sbt_cd = 00017<br>svc_dlre_cd = 01<br>kojihi_kap_adchg_div = 00020"]
    BUILD_SVC_GROUP_1["Build svc_kei_grp_list with<br>old contract details"]
    COLLECT_1["Add to wrisvc_auto_aply_list"]
    NEXT_1["db_KK_T_ADCHG_DTL2.selectNext()"]
    END_LOOP_1

    GET_ADCHG_DTL_2["getAdChgDtlInfo(adchgNo)<br>second query"]
    LOOP2{"adchgDtlInfo<br>not null?"}
    CHECK_NEW{"afSvcKeiNo != bfSvcKeiNo<br>(new contract added)?"}
    GET_SVC_KEI_2["getSvcKeiInfo(afSvcKeiNo)<br>query new contract"]
    BUILD_CC_2["Build kKSV056503CC HashMap<br>add_chge_div = 01 (registration)<br>func_code = 1<br>ido_div = CD00576_ADCHG_ADD<br>mskm_sbt_cd = 00017<br>kojihi_kap_adchg_div = 00020"]
    BUILD_SVC_GROUP_2["Build svc_kei_grp_list with<br>new contract details"]
    COLLECT_2["Add to wrisvc_auto_aply_list"]
    NEXT_2["db_KK_T_ADCHG_DTL2.selectNext()"]
    END_LOOP_2

    GET_ADCHG_DTL_3["getAdChgDtlInfo(adchgNo)<br>third query"]
    LOOP3{"adchgDtlInfo<br>not null?"}
    CHECK_SAME{"bfSvcKeiNo same as<br>afSvcKeiNo (unchanged)?"}
    GET_SVC_KEI_3["getSvcKeiInfo(afSvcKeiNo)<br>query unchanged contract"]
    BUILD_CC_3["Build kKSV056503CC HashMap<br>add_chge_div = 17 (KOJIHI_KAP_CP_DEL)<br>func_code = 1<br>ido_div = CD00576_ADCHG_ADD<br>mskm_sbt_cd = 00017<br>kojihi_kap_adchg_div = 00020"]
    BUILD_SVC_GROUP_3["Build svc_kei_grp_list with<br>unchanged contract details"]
    COLLECT_3["Add to wrisvc_auto_aply_list"]
    NEXT_3["db_KK_T_ADCHG_DTL2.selectNext()"]
    END_LOOP_3

    RETURN(["return - batch complete"])

    START --> CHECK_DUPLICATE
    CHECK_DUPLICATE -- yes --> RETURN
    CHECK_DUPLICATE -- no --> ADDED["adchgNoList.add(adchgNo)"]
    ADDED --> GET_ADCHG_DTL_1
    GET_ADCHG_DTL_1 --> LOOP1
    LOOP1 -- yes --> GET_BF_AFK
    GET_BF_AFK --> CHECK_CHANGE
    CHECK_CHANGE -- yes --> GET_SVC_KEI_1
    GET_SVC_KEI_1 --> BUILD_CC_1
    BUILD_CC_1 --> BUILD_SVC_GROUP_1
    BUILD_SVC_GROUP_1 --> COLLECT_1
    COLLECT_1 --> NEXT_1
    NEXT_1 --> LOOP1
    CHECK_CHANGE -- no --> NEXT_1
    LOOP1 -- no --> GET_ADCHG_DTL_2
    GET_ADCHG_DTL_2 --> LOOP2
    LOOP2 -- yes --> CHECK_NEW
    CHECK_NEW -- yes --> GET_SVC_KEI_2
    GET_SVC_KEI_2 --> BUILD_CC_2
    BUILD_CC_2 --> BUILD_SVC_GROUP_2
    BUILD_SVC_GROUP_2 --> COLLECT_2
    COLLECT_2 --> NEXT_2
    NEXT_2 --> LOOP2
    CHECK_NEW -- no --> NEXT_2
    LOOP2 -- no --> GET_ADCHG_DTL_3
    GET_ADCHG_DTL_3 --> LOOP3
    LOOP3 -- yes --> CHECK_SAME
    CHECK_SAME -- yes --> GET_SVC_KEI_3
    GET_SVC_KEI_3 --> BUILD_CC_3
    BUILD_CC_3 --> BUILD_SVC_GROUP_3
    BUILD_SVC_GROUP_3 --> COLLECT_3
    COLLECT_3 --> NEXT_3
    NEXT_3 --> LOOP3
    CHECK_SAME -- no --> NEXT_3
    LOOP3 -- no --> RETURN
```

**Constant Resolution Reference:**

| Constant | Actual Value | Business Meaning |
|----------|-------------|------------------|
| `JKKStrConst.CD00576_ADCHG_ADD` | `"00019"` | Address change addition classification — distinguishes add operations from modifications or cancellations |
| `ADD_CHGE_DIV_KOJIHI_KAP_CP_DEL` | `"17"` | Registration/change classification for construction fee installment charge plan removal (工事費割賦CP削除) |
| `add_chge_div = "01"` | `"01"` | Registration (新規登録) — new service contract line |
| `add_chge_div = "03"` | `"03"` | Resignation (解約) — decommissioned service contract line |
| `func_code = "1"` | `"1"` | Function code — standard processing mode |
| `mskm_sbt_cd = "00017"` | `"00017"` | Application subtype code — discount service automatic application |
| `svc_dlre_cd = "01"` | `"01"` | Service resignation reason code (regular resignation: 通常解約) |
| `kojihi_kap_adchg_div = "00020"` | `"00020"` | Construction fee change classification — fee application adjustment |
| `grp_div = "00"` | `"00"` | Group classification — standard group |
| `tg_kei_skbt_cd = "01"` | `"01"` | Target contract identification code — main contract line |

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `adchgNo` | `String` | Address change number — the unique identifier for a residential address change record. Used as the primary key to query all before/after service contract detail rows (`CHBF_SKBT_NO`, `CHAF_SKBT_NO`). Drives all three query loops. |
| 2 | `mskmNo` | `String` | Master contract number (マスター契約番号) — the customer's overarching contract identifier. Placed into every CC HashMap under key `mskm_no`, linking all derived service actions back to the customer's master contract. |

**Instance fields read by this method:**

| Field | Type | Business Description |
|-------|------|---------------------|
| `adchgNoList` | `List<String>` | Deduplication guard — tracks which `adchgNo` values have already been processed in the current batch run. Prevents duplicate CC invocations. |
| `wrisvc_auto_aply_list` | `ArrayList<HashMap<String,Object>>` | Accumulator for all prepared CC parameter maps. Populated across all three loops and consumed by downstream batch processing. |
| `db_KK_T_ADCHG_DTL2` | `JBSbatCommonDBInterface` | Database iterator for `KK_T_ADCHG_DTL2` table — used to paginate through address change detail records via `selectNext()`. |

## 4. CRUD Operations / Called Services

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

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `getAdChgDtlInfo(adchgNo)` | JBSbatKKAdChgSodUpd | KK_T_ADCHG_DTL2 | Queries address change detail records (before/after service contract numbers). Called 3 times for 3 passes. |
| R | `getString(CHBF_SKBT_NO)` | JBSbatKKAdChgSodUpd | KK_T_ADCHG_DTL2 | Reads the before-service contract number (変更前サービス契約番号). |
| R | `getString(CHAF_SKBT_NO)` | JBSbatKKAdChgSodUpd | KK_T_ADCHG_DTL2 | Reads the after-service contract number (変更後サービス契約番号). |
| R | `db_KK_T_ADCHG_DTL2.selectNext()` | JBSbatKK_T_ADCHG_DTL2 | KK_T_ADCHG_DTL2 | Advances iterator to the next address change detail row in cursor-based pagination. |
| R | `getSvcKeiInfo(bfSvcKeiNo)` / `getSvcKeiInfo(afSvcKeiNo)` | JBSbatKKAdChgSodUpd | KK_T_SVC_KEI | Queries service contract header information (service code, status, pricing group, etc.) by contract number. |
| R | `getString(SYSID)` | JBSbatKK_T_SVC_KEI | KK_T_SVC_KEI | Reads system ID from service contract record. |
| R | `getString(SVC_CD)` | JBSbatKK_T_SVC_KEI | KK_T_SVC_KEI | Reads service code (e.g., FTTH, Mail) from service contract record. |
| R | `getString(SVC_KEI_STAT)` | JBSbatKK_T_SVC_KEI | KK_T_SVC_KEI | Reads service contract status. |
| R | `getString(PRC_GRP_CD)` | JBSbatKK_T_SVC_KEI | KK_T_SVC_KEI | Reads pricing group code. |
| R | `getString(PCRS_CD)` | JBSbatKK_T_SVC_KEI | KK_T_SVC_KEI | Reads pricing course code. |
| R | `getString(PPLAN_CD)` | JBSbatKK_T_SVC_KEI | KK_T_SVC_KEI | Reads pricing plan code. |
| R | `getString(SVC_ENDYMD)` | JBSbatKK_T_SVC_KEI | KK_T_SVC_KEI | Reads service end date/year-month-day. |
| R | `getString(SVC_CHRG_ENDYMD)` | JBSbatKK_T_SVC_KEI | KK_T_SVC_KEI | Reads service charge end date/year-month-day. |

### Inferred additional CRUD evidence:

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| I | `JBSbatKKAdChgSodUpd.adchgNoList.add` | - | (in-memory) | Adds `adchgNo` to the deduplication tracking list. |
| I | `JBSbatKKAdChgSodUpd.wrisvc_auto_aply_list.add` | - | (in-memory) | Accumulates prepared CC parameter HashMap into the collection consumed by downstream batch processing. |

## 5. Dependency Trace

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

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

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Batch: JBSbatKKAdChgSodUpd | `execute()` -> `setWrisvcAutoAply(adchgNo, mskmNo)` | `getAdChgDtlInfo [R] KK_T_ADCHG_DTL2`, `getSvcKeiInfo [R] KK_T_SVC_KEI`, `selectNext [R] KK_T_ADCHG_DTL2` |

The method is invoked by the `execute()` method within the same class (`JBSbatKKAdChgSodUpd`), which serves as the main batch processing entry point. It reads from two database tables — `KK_T_ADCHG_DTL2` (address change details) and `KK_T_SVC_KEI` (service contract header) — and accumulates its results in-memory into `wrisvc_auto_aply_list` for downstream consumption by the batch pipeline.

## 6. Per-Branch Detail Blocks

### Block 1 — IF (duplicate guard) (L2793)

Guard clause: skips processing if this `adchgNo` has already been handled in the current batch.

| # | Type | Code |
|---|------|------|
| 1 | IF | `adchgNoList.contains(adchgNo)` — [duplicate adchgNo, early return] |
| 2 | RETURN | `return;` (early exit for duplicate) |
| 3 | SET | `adchgNoList.add(adchgNo);` — register this adchgNo as processed |

### Block 2 — WHILE (Pass 1: Old contract resignation loop) (L2796)

> 住所変更詳細を検索 (Search address change details). First pass: processes service contracts that are being **resigned/removed** as part of an address change. Handles the before-service contract number (変更前サービス契約番号）as the resigned contract.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `getAdChgDtlInfo(adchgNo)` — query first address change detail row [-> KK_T_ADCHG_DTL2] |
| 2 | WHILE | `adchgDtlInfo != null` — iterate through all detail rows |
| 3 | CALL | `adchgDtlInfo.getString(JBSbatKK_T_ADCHG_DTL.CHBF_SKBT_NO)` — read before-service contract number |
| 4 | CALL | `adchgDtlInfo.getString(JBSbatKK_T_ADCHG_DTL.CHAF_SKBT_NO)` — read after-service contract number |
| 5 | CALL | `adchgDtlInfo.getString(JBSbatKK_T_ADCHG_DTL.SVC_KEI_IDO_SBT_CD)` — read service migration subtype code |

#### Block 2.1 — IF (service contract changed) (L2811)

> 変更前サービス契約番号（解約・保留・解約/新規 分）を解約として呼び出す (Treat the before-service contract number as a resignation). The old contract is being decommissioned because the address change has moved the customer to a different service line.

| # | Type | Code |
|---|------|------|
| 1 | IF | `!isNullBlank(bfSvcKeiNo) && !bfSvcKeiNo.equals(afSvcKeiNo)` — [old contract exists AND differs from new] (L2811) |
| 2 | SET | `kKSV056503CC = new HashMap<String, Object>()` |
| 3 | CALL | `getSvcKeiInfo(bfSvcKeiNo)` — query old service contract [-> KK_T_SVC_KEI] |
| 4 | SET | `kKSV056503CC.put("sysid", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.SYSID))` |
| 5 | SET | `kKSV056503CC.put("add_chge_div", "03")` — [-> 解約 (Resignation)] |
| 6 | SET | `kKSV056503CC.put("func_code", "1")` |
| 7 | SET | `kKSV056503CC.put("ido_div", JKKStrConst.CD00576_ADCHG_ADD)` — [-> "00019" (Address change addition)] |
| 8 | SET | `kKSV056503CC.put("mskm_sbt_cd", "00017")` |
| 9 | SET | `kKSV056503CC.put("mskm_no", mskmNo)` |
| 10 | SET | `kKSV056503CC.put("svc_dlre_cd", "01")` — [-> 通常解約 (Regular resignation)] |
| 11 | SET | `kKSV056503CC.put("kojihi_kap_adchg_div", "00020")` |
| 12 | SET | `svc_kei_grp_list = new ArrayList<HashMap<String, Object>>()` |
| 13 | SET | `svc_kei_grp_list_map = new HashMap<String, Object>()` |
| 14 | SET | `svc_kei_list = new ArrayList<HashMap<String, Object>>()` |
| 15 | SET | `svc_kei_list_map = new HashMap<String, Object>()` |
| 16 | SET | `kKSV056503CC.put("svc_kei_grp_list", svc_kei_grp_list)` |
| 17 | SET | `svc_kei_grp_list_map.put("grp_div", "00")` |
| 18 | SET | `svc_kei_grp_list_map.put("svc_kei_list", svc_kei_list)` |
| 19 | SET | `svc_kei_list_map.put("sysid", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.SYSID))` |
| 20 | SET | `svc_kei_list_map.put("tg_kei_skbt_cd", "01")` |
| 21 | SET | `svc_kei_list_map.put("svc_kei_no", bfSvcKeiNo)` |
| 22 | SET | `svc_kei_list_map.put("svc_cd", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.SVC_CD))` |
| 23 | SET | `svc_kei_list_map.put("svc_kei_stat", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.SVC_KEI_STAT))` |
| 24 | SET | `svc_kei_list_map.put("prc_grp_cd", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.PRC_GRP_CD))` |
| 25 | SET | `svc_kei_list_map.put("pcrs_cd", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.PCRS_CD))` |
| 26 | SET | `svc_kei_list_map.put("pplan_cd", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.PPLAN_CD))` |
| 27 | SET | `svc_kei_list_map.put("svc_endymd", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.SVC_ENDYMD))` |
| 28 | SET | `svc_kei_list_map.put("svc_chrg_endymd", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.SVC_CHRG_ENDYMD))` |
| 29 | CALL | `svc_kei_list.add(svc_kei_list_map)` |
| 30 | CALL | `svc_kei_grp_list.add(svc_kei_grp_list_map)` |
| 31 | IF | `wrisvc_auto_aply_list == null` — [L2871] |
| 32 | SET | `wrisvc_auto_aply_list = new ArrayList<HashMap<String, Object>>()` |
| 33 | CALL | `wrisvc_auto_aply_list.add(kKSV056503CC)` — accumulate CC params |
| 34 | CALL | `db_KK_T_ADCHG_DTL2.selectNext()` — advance iterator |

### Block 3 — WHILE (Pass 2: New contract registration loop) (L2896)

> 追加サービス分の呼出を解約分の後で処理するため、別ループとする (Use a separate loop to process additional services after resignation services). Second pass: processes service contracts that are **newly registered** as part of the address change. Handles the after-service contract number (変更後サービス契約番号) as a new registration.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `getAdChgDtlInfo(adchgNo)` — reset iterator, query first row again |
| 2 | WHILE | `adchgDtlInfo != null` — iterate through all detail rows |
| 3 | CALL | `adchgDtlInfo.getString(JBSbatKK_T_ADCHG_DTL.CHBF_SKBT_NO)` |
| 4 | CALL | `adchgDtlInfo.getString(JBSbatKK_T_ADCHG_DTL.CHAF_SKBT_NO)` |

#### Block 3.1 — IF (new contract added) (L2908)

> 変更後サービス契約番号（追加・解約/新規 分）を登録として呼び出す (Treat the after-service contract number as a new registration). The new contract is being provisioned at the new address.

| # | Type | Code |
|---|------|------|
| 1 | IF | `!isNullBlank(afSvcKeiNo) && !afSvcKeiNo.equals(bfSvcKeiNo)` — [new contract exists AND differs from old] (L2908) |
| 2 | SET | `kKSV056503CC = new HashMap<String, Object>()` |
| 3 | CALL | `getSvcKeiInfo(afSvcKeiNo)` — query new service contract [-> KK_T_SVC_KEI] |
| 4 | SET | `kKSV056503CC.put("sysid", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.SYSID))` |
| 5 | SET | `kKSV056503CC.put("add_chge_div", "01")` — [-> 登録 (Registration)] |
| 6 | SET | `kKSV056503CC.put("func_code", "1")` |
| 7 | SET | `kKSV056503CC.put("ido_div", JKKStrConst.CD00576_ADCHG_ADD)` — [-> "00019"] |
| 8 | SET | `kKSV056503CC.put("mskm_sbt_cd", "00017")` |
| 9 | SET | `kKSV056503CC.put("mskm_no", mskmNo)` |
| 10 | SET | `kKSV056503CC.put("kojihi_kap_adchg_div", "00020")` |
| 11 | SET | `svc_kei_grp_list = new ArrayList<HashMap<String, Object>>()` |
| 12 | SET | `svc_kei_grp_list_map = new HashMap<String, Object>()` |
| 13 | SET | `svc_kei_list = new ArrayList<HashMap<String, Object>>()` |
| 14 | SET | `svc_kei_list_map = new HashMap<String, Object>()` |
| 15 | SET | `kKSV056503CC.put("svc_kei_grp_list", svc_kei_grp_list)` |
| 16 | SET | `svc_kei_grp_list_map.put("grp_div", "00")` |
| 17 | SET | `svc_kei_grp_list_map.put("svc_kei_list", svc_kei_list)` |
| 18 | SET | `svc_kei_list_map.put("tg_kei_skbt_cd", "01")` |
| 19 | SET | `svc_kei_list_map.put("svc_kei_no", afSvcKeiNo)` |
| 20 | SET | `svc_kei_list_map.put("svc_cd", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.SVC_CD))` |
| 21 | SET | `svc_kei_list_map.put("svc_kei_stat", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.SVC_KEI_STAT))` |
| 22 | SET | `svc_kei_list_map.put("prc_grp_cd", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.PRC_GRP_CD))` |
| 23 | SET | `svc_kei_list_map.put("pcrs_cd", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.PCRS_CD))` |
| 24 | SET | `svc_kei_list_map.put("pplan_cd", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.PPLAN_CD))` |
| 25 | CALL | `svc_kei_list.add(svc_kei_list_map)` |
| 26 | CALL | `svc_kei_grp_list.add(svc_kei_grp_list_map)` |
| 27 | IF | `wrisvc_auto_aply_list == null` |
| 28 | SET | `wrisvc_auto_aply_list = new ArrayList<HashMap<String, Object>>()` |
| 29 | CALL | `wrisvc_auto_aply_list.add(kKSV056503CC)` |
| 30 | CALL | `db_KK_T_ADCHG_DTL2.selectNext()` |

### Block 4 — WHILE (Pass 3: Unchanged contract fee exemption removal loop) (L3047)

> 工事費割賦請求STEP2 HT⇒MTに住所変更確定したが割引適用CCが呼ばれない (Fix for ANK-3383-00-00: discount application CC was not called when residential address change was confirmed from HT to MT with unchanged contract). Third pass (IT2-2018-0000061): processes service contracts where **both before and after contract numbers are identical** — meaning the contract line was retained during the address change. These contracts have construction fee installment charges removed.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `getAdChgDtlInfo(adchgNo)` — reset iterator, query first row again |
| 2 | WHILE | `adchgDtlInfo != null` — iterate through all detail rows |
| 3 | CALL | `adchgDtlInfo.getString(JBSbatKK_T_ADCHG_DTL.CHBF_SKBT_NO)` |
| 4 | CALL | `adchgDtlInfo.getString(JBSbatKK_T_ADCHG_DTL.CHAF_SKBT_NO)` |

#### Block 4.1 — IF (contract unchanged) (L3058)

> 変更前サービス契約番号と変更後サービス契約番号が同じ場合 (When before and after service contract numbers are the same — contract retained during address change).

| # | Type | Code |
|---|------|------|
| 1 | IF | `!isNullBlank(bfSvcKeiNo) && !isNullBlank(afSvcKeiNo) && afSvcKeiNo.equals(bfSvcKeiNo)` — [both exist AND are identical] (L3058) |
| 2 | SET | `kKSV056503CC = new HashMap<String, Object>()` |
| 3 | CALL | `getSvcKeiInfo(afSvcKeiNo)` — query service contract [-> KK_T_SVC_KEI] |
| 4 | SET | `kKSV056503CC.put("sysid", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.SYSID))` |
| 5 | SET | `kKSV056503CC.put("add_chge_div", ADD_CHGE_DIV_KOJIHI_KAP_CP_DEL)` — [-> "17" (工事費割賦CP削除)] |
| 6 | SET | `kKSV056503CC.put("func_code", "1")` |
| 7 | SET | `kKSV056503CC.put("ido_div", JKKStrConst.CD00576_ADCHG_ADD)` — [-> "00019"] |
| 8 | SET | `kKSV056503CC.put("mskm_sbt_cd", "00017")` |
| 9 | SET | `kKSV056503CC.put("mskm_no", mskmNo)` |
| 10 | SET | `kKSV056503CC.put("kojihi_kap_adchg_div", "00020")` |
| 11 | SET | `svc_kei_grp_list = new ArrayList<HashMap<String, Object>>()` |
| 12 | SET | `svc_kei_grp_list_map = new HashMap<String, Object>()` |
| 13 | SET | `svc_kei_list = new ArrayList<HashMap<String, Object>>()` |
| 14 | SET | `svc_kei_list_map = new HashMap<String, Object>()` |
| 15 | SET | `kKSV056503CC.put("svc_kei_grp_list", svc_kei_grp_list)` |
| 16 | SET | `svc_kei_grp_list_map.put("grp_div", "00")` |
| 17 | SET | `svc_kei_grp_list_map.put("svc_kei_list", svc_kei_list)` |
| 18 | SET | `svc_kei_list_map.put("tg_kei_skbt_cd", "01")` |
| 19 | SET | `svc_kei_list_map.put("svc_kei_no", afSvcKeiNo)` |
| 20 | SET | `svc_kei_list_map.put("svc_cd", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.SVC_CD))` |
| 21 | SET | `svc_kei_list_map.put("svc_kei_stat", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.SVC_KEI_STAT))` |
| 22 | SET | `svc_kei_list_map.put("prc_grp_cd", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.PRC_GRP_CD))` |
| 23 | SET | `svc_kei_list_map.put("pcrs_cd", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.PCRS_CD))` |
| 24 | SET | `svc_kei_list_map.put("pplan_cd", svcKeiInfo.getString(JBSbatKK_T_SVC_KEI.PPLAN_CD))` |
| 25 | CALL | `svc_kei_list.add(svc_kei_list_map)` |
| 26 | CALL | `svc_kei_grp_list.add(svc_kei_grp_list_map)` |
| 27 | IF | `wrisvc_auto_aply_list == null` |
| 28 | SET | `wrisvc_auto_aply_list = new ArrayList<HashMap<String, Object>>()` |
| 29 | CALL | `wrisvc_auto_aply_list.add(kKSV056503CC)` |
| 30 | CALL | `db_KK_T_ADCHG_DTL2.selectNext()` |

### Block 5 — RETURN (L3127)

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return;` — batch processing complete. `wrisvc_auto_aply_list` now contains all accumulated CC parameter maps for all three scenarios. |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `adchgNo` | Field | Address change number — unique identifier for a residential address change (住所変更) record |
| `mskmNo` | Field | Master contract number (マスター契約番号) — the customer's overarching service contract identifier |
| `bfSvcKeiNo` | Field | Before-service contract number (変更前サービス契約番号) — the service contract ID that existed before the address change |
| `afSvcKeiNo` | Field | After-service contract number (変更後サービス契約番号) — the service contract ID that will exist after the address change |
| `svcKeiIdoSbtCd` | Field | Service migration subtype code (サービス移行サブタイプコード) — classifies the type of service line migration |
| `adchgNoList` | Field | Deduplication list tracking which address change numbers have been processed in the current batch |
| `wrisvc_auto_aply_list` | Field | Discount service automatic application list (割引サービス自動適用リスト) — accumulator for CC parameter maps |
| `add_chge_div` | Field | Registration/change classification (登録/変更区分) — distinguishes new registration (01) from resignation (03) from construction fee removal (17) |
| `svc_dlre_cd` | Field | Service resignation reason code (サービス解約理由コード) — reason for contract cancellation (01 = regular resignation) |
| `kojihi_kap_adchg_div` | Field | Construction fee change classification (工事費変更区分) — fee application adjustment code (00020 = fee application) |
| `ido_div` | Field | Migration classification (異動区分) — distinguishes address change addition operations |
| `mskm_sbt_cd` | Field | Master contract subtype code (マスター契約サブタイプコード) — application subtype (00017 = discount service auto application) |
| `svc_kei_grp_list` | Field | Service contract group list (サービス契約グループリスト) — nested structure organizing service contracts by group |
| `svc_kei_list` | Field | Service contract list (サービス契約リスト) — list of individual service contract records within a group |
| `tg_kei_skbt_cd` | Field | Target contract identification code (対象契約識別コード) — identifies the main contract line (01) |
| `grp_div` | Field | Group classification (グループ区分) — grouping identifier (00 = standard group) |
| `svc_endymd` | Field | Service end year-month-day (サービス終了年月日) — service termination date |
| `svc_chrg_endymd` | Field | Service charge end year-month-day (サービス課金終了年月日) — service billing termination date |
| `JBSbatKKAdChgSodUpd` | Class | Address change SOD update batch service — handles service order data updates during residential address changes |
| KKSV056503CC | Component | CC (Control Component) for service contract resignation/registration — processes service contract lifecycle changes |
| KK_T_ADCHG_DTL2 | Table | Address change detail table — stores before/after service contract mappings for address changes |
| KK_T_SVC_KEI | Table | Service contract header table — stores service contract master data (code, status, pricing) |
| SOD | Acronym | Service Order Data — telecom order fulfillment entity for service contracts |
| CC | Acronym | Control Component — a component class that processes specific business operations, typically consuming HashMap parameters and performing database or system operations |
| HT | Business term | House Terminal — residential customer premises equipment location type |
| MT | Business term | Middle Terminal — intermediate network equipment location type (vs. direct-to-home) |
| 工事費割賦 (Koujihi Gyuufu) | Japanese term | Construction fee installment — monthly installment charges for installation/construction costs |
| 割賦CP削除 | Japanese term | Installment charge plan removal — removing the monthly installment charge plan from a contract |
| 住所変更 (Jusho Henkou) | Japanese term | Residential address change — the business process of updating a customer's service address |
| 解約 (Kaiyaku) | Japanese term | Resignation/cancellation — terminating a service contract |
| 登録 (Touroku) | Japanese term | Registration — creating a new service contract |
| 通常解約 (Tsujou Kaiyaku) | Japanese term | Regular resignation — standard contract cancellation reason (code 01) |
| 回線併合 (Kaisen Heigou) | Japanese term (commented out) | Line merging — combining service lines (no longer used in current logic) |
| 転居元 (Tenkyo-moto) | Japanese term (commented out) | Previous address — the old address being moved from (no longer used) |
| 転居先 (Tenkyo-saki) | Japanese term (commented out) | New address — the destination address being moved to (no longer used) |
| CD00576_ADCHG_ADD | Constant | `"00019"` — Address change addition classification constant |
| ADD_CHGE_DIV_KOJIHI_KAP_CP_DEL | Constant | `"17"` — Registration/change classification for construction fee installment charge plan removal |
