# Business Logic — JKKAdInfChgCC.siteiShsAdUpd() [641 LOC]

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

## 1. Role

### JKKAdInfChgCC.siteiShsAdUpd()

This method performs **Delivered Address Change Processing** (事前準備 - Pre-delivery address update), serving as the core business logic handler for updating a customer's delivered address (送付先住所) in the K-Opticom telecommunications customer management system. When a customer or corporate subscriber requests to change the address where their bills, notices, and goods are delivered, this method orchestrates the complete lifecycle: pre-flight validation, consent agreement retrieval, address field-level comparison, sub-type determination (individual vs. corporate), content update, and progress registration.

The method implements a **delegation pattern** combined with a **mapper-invoker pattern**: it uses `JKKAdInfChgMapperCC` to build SC (Service Component) request maps, and `ServiceComponentRequestInvoker` to execute those SCs against the backend. It branches its behavior based on the `updateNaiyo` (更新内容) parameter — when the update is not limited to phone number (電話) only or name only (名前), it performs full address field comparison and builds a "progress supplement" (進捗補足) description string documenting old vs. new values.

Its **role in the larger system** is as a sub-component of the broader address information change flow (住所情報変曳反映処理) invoked from `adInfChgCommit()`. After the main contract address change (`kshAdUpd`), this method handles the separate delivered address branch, ensuring the delivered address is independently updated and logged as a progress event (E090: Delivered Address Change).

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["siteiShsAdUpd params"]) --> PREP["Prepare: condMap, paramMap, mapper, scCall"]
    PREP --> CHECK_KSH["Check ksh_upd_um = getKshAdUpdUm"]
    CHECK_KSH --> "true (Ksh already updated)"| KSH_SKIP["Return early"]
    CHECK_KSH --> "false"| CHECK_SITEI["Check sitei_shs_upd_um = getSiteiShsAdUpdUm"]
    CHECK_SITEI --> "false"| SITEI_SKIP["Return early"]
    CHECK_SITEI --> "true"| EXIST_CUST["existCustRsvData check"]
    EXIST_CUST --> ECK0011["ECK0011A010 Customer Consent Agreement set + run + get"]
    ECK0011 --> SC_CHECK_1["scResultCheck"]
    SC_CHECK_1 --> GET_UPDATE_NAIYO["Get updateNaiyo"]
    GET_UPDATE_NAIYO --> UPDATE_CHECK{"updateNaiyo"}
    UPDATE_CHECK --> "UPDATE_TEL=2 or UPDATE_NM=3"| CK_MAP_PUT["Put RSV_APLY_YMD, UPD_DTM_BEF"]
    UPDATE_CHECK --> "other (address update)"| ADDR_PREP["Addr change fields: prepare ck0011_a010_map"]
    ADDR_PREP --> ZIP_COND{"Postal code change?"}
    ZIP_COND --> "different or one null"| ZIP_SET["Set prg_tkjk/prg_tkjk2 with old+new postal"]
    ZIP_COND --> "same both null"| STATE_CHECK{"State change?"}
    ZIP_SET --> STATE_CHECK
    STATE_CHECK --> "different or one null"| STATE_SET["AdChangeFlg = true"]
    STATE_CHECK --> "same both null"| CITY_CHECK{"City change?"}
    STATE_SET --> CITY_CHECK
    CITY_CHECK --> "different or one null"| CITY_SET["AdChangeFlg = true"]
    CITY_CHECK --> "same both null"| DIST_CHECK{"District change?"}
    CITY_SET --> DIST_CHECK
    DIST_CHECK --> "different or one null"| DIST_SET["AdChangeFlg = true"]
    DIST_CHECK --> "same both null"| BLOCK_CHECK{"Block change?"}
    DIST_SET --> BLOCK_CHECK
    BLOCK_CHECK --> "different or one null"| BLOCK_SET["AdChangeFlg = true"]
    BLOCK_CHECK --> "same both null"| ADDRTTM_CHECK{"Address room change?"}
    BLOCK_SET --> ADDRTTM_CHECK
    ADDRTTM_CHECK --> "different or one null"| ADDRTTM_SET["AdChangeFlg = true"]
    ADDRTTM_CHECK --> "same both null"| ADRRM_CHECK{"Building name change?"}
    ADDRTTM_SET --> NO_CHG["No address change"]
    ADRRM_CHECK --> "same all"| NO_CHG
    NO_CHG --> AD_FLG_CHECK{AdChangeFlg}
    STATE_SET --> AD_FLG_CHECK
    CITY_SET --> AD_FLG_CHECK
    DIST_SET --> AD_FLG_CHECK
    BLOCK_SET --> AD_FLG_CHECK
    ADDRTTM_SET --> AD_FLG_CHECK
    AD_FLG_CHECK --> "true"| FULL_ADDR["Build full address strings prg_tkjk/prg_tkjk2"]
    AD_FLG_CHECK --> "false"| SKIP_FULL["Skip full address"]
    FULL_ADDR --> CK_MAP_UPD["Update ck0011_a010_map with new values"]
    SKIP_FULL --> CK_MAP_UPD
    CK_MAP_UPD --> MANUAL_FLG["Set AD_MAN_INPUT_FLG from REIGAI param"]
    MANUAL_FLG --> CHK_LV["Set cssti_shs_ad_chk_lv = 1"]
    CHK_LV --> PUT_COMMON["Put RSV_APLY_YMD, UPD_DTM_BEF"]
    PUT_COMMON --> SUBKOJIN["Initialize subKojin, gene_Kojin, ck0021_a010_map"]
    SUBKOJIN --> ECK0021A["ECK0021A010 Individual Customer Consent set + run + get"]
    ECK0021A --> KOJIN_RESULT{"Individual result exists?"}
    KOJIN_RESULT --> "yes"| KOJIN_DETAIL{"Detail array exists?"}
    KOJIN_RESULT --> "no"| KOJIN_FALSE["subKojin = false"]
    KOJIN_DETAIL --> "yes"| KOJIN_TRUE["subKojin = true, get gene_Kojin"]
    KOJIN_DETAIL --> "no"| KOJIN_FALSE
    KOJIN_TRUE --> ECK0031A["ECK0031A010 Corporate Customer Consent set + run + get"]
    KOJIN_FALSE --> ECK0031A
    ECK0031A --> HOJIN_RESULT{"Corporate result exists?"}
    HOJIN_RESULT --> "yes"| HOJIN_DETAIL{"Detail array exists?"}
    HOJIN_RESULT --> "no"| HOJIN_FALSE["subHojin = false"]
    HOJIN_DETAIL --> "yes"| HOJIN_TRUE["subHojin = true, get gene_Hojin"]
    HOJIN_DETAIL --> "no"| HOJIN_FALSE
    HOJIN_TRUE --> BOTH_CHECK{subKojin AND subHojin}
    HOJIN_FALSE --> DETERMINE["Whichever exists wins"]
    BOTH_CHECK --> "true"| GENE_CMP["Compare gene_Kojin vs gene_Hojin"]
    GENE_CMP --> "kojin newer"| HOJIN_OFF["subHojin = false"]
    GENE_CMP --> "hojin newer"| KOJIN_OFF["subKojin = false"]
    KOJIN_OFF --> EXEC_IND
    HOJIN_OFF --> EXEC_IND
    DETERMINE --> EXEC_IND{"subKojin?"}
    EXEC_IND --> "true"| ECK0021C["ECK0021C010 Individual Content Update set + run + get"]
    EXEC_IND --> "false"| EXEC_HOJIN{"subHojin?"}
    EXEC_HOJIN --> "true"| ECK0031C["ECK0031C010 Corporate Content Update set + run + get"]
    EXEC_HOJIN --> "false"| THROW_ERR["throw CCException (illegal case)"]
    ECK0021C --> GET_UPD_DTM_AF["Get UPD_DTM_AF, ad_chk_lv errors"]
    ECK0031C --> GET_UPD_DTM_AF
    GET_UPD_DTM_AF --> PRG_TRUNC["Truncate prg_tkjk/prg_tkjk2 (strip trailing comma, max 128 chars)"]
    PRG_TRUNC --> EKK0081["EKK0081B003 Service Contract List get"]
    EKK0081 --> FST_SVC["Get fstSvcKeiNo from list or param"]
    FST_SVC --> PARENT_MAP["Build parent_map with SVC_KEI_NO, IDO_DIV, PRG_STAT=E090, PRG_TKJK"]
    PARENT_MAP --> EKK1091["EKK1091D010 Progress Registration set + run + get"]
    EKK1091 --> SC_CHECK_2["scResultCheck"]
    SC_CHECK_2 --> END_NODE(["Return / Next"])
    THROW_ERR --> END_NODE
    KSH_SKIP --> END_NODE
    SITEI_SKIP --> END_NODE
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `param` | `IRequestParameterReadWrite` | The request parameter object carrying the model group, control map, and all business data extracted from the screen. Contains the delivered address change fields (postal code, state, city, district, block, building name/number, address room), system ID, operation date, service contract number, and divergence reason list. Retrieved via `param.getData(fixedText)` to obtain the `paramMap` HashMap. |
| 2 | `fixedText` | `String` | User-specified arbitrary string used as a key to retrieve the correct data group from the `param` object. Acts as an identifier for multi-group request payloads (e.g., when multiple address changes are batched). |

**Instance / External State Read:**

| Field | Type | Business Description |
|-------|------|---------------------|
| `keepSesHandle` | `ThreadLocal<SessionHandle>` | Holds the session handle for the current request, passed to SC invocations to maintain transaction context. |

## 4. CRUD Operations / Called Services

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `JKKAdInfChgMapperCC.getInstance` | - | - | Singleton access to the mapper component for building SC request/response maps. |
| - | `ServiceComponentRequestInvoker.<init>` | - | - | Creates the SC invocation handler. |
| R | `JKKAdInfChgCC.getKshAdUpdUm` | JKKAdInfChgCC | - | Reads whether the main contract address needs update (early exit guard). |
| R | `JKKAdInfChgCC.getSiteiShsAdUpdUm` | JKKAdInfChgCC | - | Reads whether the delivered address needs update (early exit guard). |
| R | `JKKAdInfChgCC.existCustRsvData` | JKKAdInfChgCC | - | Checks for existing customer reservation data (future contract validation). |
| R | `JKKAdInfChgMapperCC.setECK0011A010` | ECK0011A010SC | - | Builds the request map for Customer Consent Agreement (consent holder). |
| C | `ServiceComponentRequestInvoker.run` | ECK0011A010SC | KK_T_CUST_AGREE (ECK) | Executes the Customer Consent Agreement retrieval SC. |
| R | `JKKAdInfChgMapperCC.getECK0011A010` | ECK0011A010SC | KK_T_CUST_AGREE (ECK) | Deserializes the Customer Consent Agreement result from response map. |
| - | `JKKAdInfChgMapperCC.scResultCheck` | ECK0011A010SC | - | Validates the SC execution result for errors. |
| R | `JKKAdInfChgMapperCC.setECK0021A010` | ECK0021A010SC | - | Builds the request map for Individual (Kojin) Customer Consent Agreement. |
| R | `JKKAdInfChgMapperCC.getECK0021A010` | ECK0021A010SC | KK_T_CUST_AGREE_INDIV (ECK) | Deserializes the Individual Customer Consent Agreement result. |
| R | `JKKAdInfChgMapperCC.setECK0031A010` | ECK0031A010SC | - | Builds the request map for Corporate (Hojin) Customer Consent Agreement. |
| R | `JKKAdInfChgMapperCC.getECK0031A010` | ECK0031A010SC | KK_T_CUST_AGREE_CORP (ECK) | Deserializes the Corporate Customer Consent Agreement result. |
| C | `JKKAdInfChgMapperCC.setECK0021C010` | ECK0021C010SC | - | Builds the request map for Individual Customer Content Update. |
| C | `ServiceComponentRequestInvoker.run` | ECK0021C010SC | KK_T_CUST_AGREE_INDIV (ECK) | Executes the Individual Content Update SC (applies new address). |
| R | `JKKAdInfChgMapperCC.getECK0021C010` | ECK0021C010SC | KK_T_CUST_AGREE_INDIV (ECK) | Deserializes the Individual Content Update result (returns UPD_DTM). |
| C | `JKKAdInfChgMapperCC.setECK0031C010` | ECK0031C010SC | - | Builds the request map for Corporate Customer Content Update. |
| C | `ServiceComponentRequestInvoker.run` | ECK0031C010SC | KK_T_CUST_AGREE_CORP (ECK) | Executes the Corporate Content Update SC (applies new address). |
| R | `JKKAdInfChgMapperCC.getECK0031C010` | ECK0031C010SC | KK_T_CUST_AGREE_CORP (ECK) | Deserializes the Corporate Content Update result (returns UPD_DTM). |
| - | `JKKAdInfChgMapperCC.scResultCheck` | - | - | Validates SC execution results for errors (called after each SC). |
| R | `JKKAdInfChgMapperCC.setEKK0081B003` | EKK0081B003SC | - | Builds the request map for active Service Contract List. |
| R | `JKKAdInfChgMapperCC.getEKK0081B003` | EKK0081B003SC | KK_T_SVC_CONTRACT (EKK) | Retrieves the list of active service contracts (to find first contract number). |
| R | `JKKAdInfChgMapperCC.setEKK1091D010` | EKK1091D010SC | - | Builds the request map for Progress Registration. |
| R | `JKKAdInfChgMapperCC.getEKK1091D010` | EKK1091D010SC | KK_T_PROGRESS (EKK) | Retrieves the Progress Registration result. |
| R | `JKKAdInfChgCC.getIdoRsnList` | JKKAdInfChgCC | - | Builds the divergence reason list for progress registration. |
| R | `JCCBPCommon.getSysDateTimeStamp` | - | - | Gets the current system timestamp for IDO_DTM (divergence time). |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | `KKSV0156OPOperation` | `adInfChgCommit` -> `siteiShsAdUpd` | `ECK0011A010 [R] KK_T_CUST_AGREE`, `ECK0021C010 [C] KK_T_CUST_AGREE_INDIV`, `ECK0031C010 [C] KK_T_CUST_AGREE_CORP`, `EKK0081B003 [R] KK_T_SVC_CONTRACT`, `EKK1091D010 [C] KK_T_PROGRESS` |

**Caller Details:** The method is called from `adInfChgCommit()` within the same class `JKKAdInfChgCC`, which itself is invoked by screen operation class `KKSV0156OPOperation` (Address Information Change Screen). The `adInfChgCommit()` method is the main entry point that orchestrates the full address change flow: pre-check -> main contract address update -> **delivered address update** (this method) -> usage place address update -> billing address update -> guide address update.

**Terminal operations reached from this method:**

| Operation | Type | Target |
|-----------|------|--------|
| `scResultCheck` | - | Error validation (no data change) |
| `getECK0011A010` | R | Customer Consent Agreement (ECK entity) |
| `setECK0011A010` | R | SC request build for Customer Consent |
| `run` (ECK0011A010) | C | Customer Consent Agreement SC |
| `setECK0021A010` | R | SC request build for Individual Customer Consent |
| `getECK0021A010` | R | Individual Customer Consent Agreement result |
| `run` (ECK0021A010) | C | Individual Customer Consent Agreement SC |
| `setECK0021C010` | C | Individual Customer Content Update SC |
| `getECK0021C010` | R | Individual Content Update result (UPD_DTM) |
| `run` (ECK0021C010) | C | Individual Customer Content Update SC |
| `setECK0031A010` | R | SC request build for Corporate Customer Consent |
| `getECK0031A010` | R | Corporate Customer Consent Agreement result |
| `run` (ECK0031A010) | C | Corporate Customer Consent Agreement SC |
| `setECK0031C010` | C | Corporate Customer Content Update SC |
| `getECK0031C010` | R | Corporate Content Update result (UPD_DTM) |
| `run` (ECK0031C010) | C | Corporate Customer Content Update SC |
| `setEKK0081B003` | R | SC request build for Service Contract List |
| `getEKK0081B003` | R | Active Service Contract List result |
| `run` (EKK0081B003) | R | Service Contract List query |
| `setEKK1091D010` | R | SC request build for Progress Registration |
| `getEKK1091D010` | R | Progress Registration result |
| `run` (EKK1091D010) | C | Progress Registration SC |
| `getIdoRsnList` | R | Divergence reason list builder |
| `getSysDateTimeStamp` | R | System timestamp |

## 6. Per-Branch Detail Blocks

### Block 1 — Preparation (L5451)

Sets up the working data structures and service components.

| # | Type | Code |
|---|------|------|
| 1 | SET | `condMap = new HashMap<String, String>()` // Condition map for SC queries |
| 2 | SET | `paramMap = param.getData(fixedText)` // Extracts request data HashMap |
| 3 | SET | `mapper = JKKAdInfChgMapperCC.getInstance()` // Mapper for SC request building |
| 4 | SET | `scCall = new ServiceComponentRequestInvoker()` // SC request invoker |

### Block 2 — Contract Address Update Guard (L5458)

Checks whether the main contract address (`ksh`) has already been updated in this flow. If so, early return to avoid duplicate processing.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `ksh_upd_um = getKshAdUpdUm(paramMap)` // Checks Ksh update flag |
| 2 | IF-ELSE | `if (ksh_upd_um)` [L5462] |
| 2.1 | EXEC | `return;` // Contract address already updated, stop processing |

### Block 3 — Delivered Address Update Flag Check (L5466)

Checks whether the delivered address is marked as needing an update.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `sitei_shs_upd_um = getSiteiShsAdUpdUm(paramMap)` // Checks SiteiShs update flag |
| 2 | IF-ELSE | `if (!sitei_shs_upd_um)` [L5468] |
| 2.1 | EXEC | `return;` // Delivered address not targeted, stop processing |

### Block 4 — Customer Reservation Data Existence Check (L5474)

Validates that no conflicting future reservation data exists for this customer.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `existCustRsvData(param, paramMap, scCall, fixedText, mapper)` // ANK-2661-00-00 |

### Block 5 — Customer Consent Agreement Retrieval (ECK0011A010) (L5478)

Retrieves the consent agreement for the customer to get the current address baseline. Uses `CSSTI_SHS_APLY_YMD` as the operation date (not `OPE_DATE`).

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `condMap.clear()` |
| 2 | SET | `condMap.put(COND_KEY_SYSID, paramMap.get(PARAM_KEY_SYSID))` |
| 3 | SET | `condMap.put(COND_KEY_OPEDATE, paramMap.get(PARAM_KEY_CSSTI_SHS_APLY_YMD))` // OM-2014-0001265: switched from OPE_DATE to CSSTI_SHS_APLY_YMD |
| 4 | CALL | `reqMap = mapper.setECK0011A010(param, fixedText, condMap)` // Builds request |
| 5 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` // Executes SC |
| 6 | CALL | `ck0011_a010_map = mapper.getECK0011A010(param, fixedText, resMap)` // Deserializes response |
| 7 | CALL | `mapper.scResultCheck(param)` // Validates result |

### Block 6 — Update Content Classification (L5496)

Reads the update content type to determine if this is a pure address change or a limited update (phone only / name only).

| # | Type | Code |
|---|------|------|
| 1 | SET | `updateNaiyo = paramMap.get(PARAM_KEY_UPDATE_NAIYO)` |
| 2 | IF-ELSE | `if (!UPDATE_TEL.equals(updateNaiyo) && !UPDATE_NM.equals(updateNaiyo))` [L5499, UPDATE_TEL="2", UPDATE_NM="3"] |

#### Block 6.1 — Address Field Comparison (L5503)

Only reached when update is NOT phone-only or name-only. Compares each address component between DB (current) and param (new).

| # | Type | Code |
|---|------|------|
| 1 | SET | `ck0011_a010_map.put(CSSTI_SHS_AD_CD, paramMap.get(PARAM_KEY_CSSTI_SHS_AD_AD_CD))` // Delivered address code |
| 2 | IF-ELSE | **Postal Code Change Detection** — checks if old/new postal code differs (L5505) |
| 2.1 | IF-ELSE | Both null/empty -> no change |
| 2.2 | IF-ELSE | Old exists, new null/empty -> no change |
| 2.3 | IF-ELSE | Old null/empty, new exists -> set prg_tkjk/prg_tkjk2 with old blank + new value |
| 2.4 | IF-ELSE | Both exist but differ -> set prg_tkjk/prg_tkjk2 with old + new |
| 3 | IF-ELSE | **Prefecture (State) Change Detection** (L5544) |
| 3.1 | If different -> `AdChangeFlg = true` |
| 4 | IF-ELSE | **City Change Detection** (L5562) |
| 4.1 | If different -> `AdChangeFlg = true` |
| 5 | IF-ELSE | **District Change Detection** (L5580) |
| 5.1 | If different -> `AdChangeFlg = true` |
| 6 | IF-ELSE | **Block Change Detection** (L5598) |
| 6.1 | If different -> `AdChangeFlg = true` |
| 7 | IF-ELSE | **Address Room/Number Change Detection** (L5616) |
| 7.1 | If different -> `AdChangeFlg = true` |
| 8 | IF-ELSE | **Building Name Change Detection** (L5634) |
| 8.1 | If different -> `AdChangeFlg = true` |

Each address component comparison follows the same 4-way pattern:
- (old IS empty) AND (new IS empty) -> no change
- (old EXISTS) AND (new IS empty) -> no change
- (old IS empty) AND (new EXISTS) -> `AdChangeFlg = true`
- (old != new) -> `AdChangeFlg = true`

#### Block 6.1.1 — Full Address String Construction (L5665)

If any address field changed (`AdChangeFlg = true`), build a complete address string for the progress supplement field.

| # | Type | Code |
|---|------|------|
| 1 | IF-ELSE | `if (AdChangeFlg)` [L5665] |
| 2 | SET | `prg_tkjk = prg_tkjk + PCG_CSSTI_SHS_AD_TEXT + state + city + oaztsu + azcho + bnchigo + adrttm + adrm + KUTEN_CANMA` // Old full address |
| 3 | SET | `prg_tkjk2 = prg_tkjk2 + PCG_CSSTI_SHS_AD_TEXT_AF + newState + newCity + newOaztsu + newAzcho + newBnchigo + newAdrttm + newAdrm + KUTEN_CANMA` // New full address |

#### Block 6.1.2 — Map Population with New Values (L5680)

Populate the `ck0011_a010_map` with the new delivered address values for the update SC.

| # | Type | Code |
|---|------|------|
| 1 | SET | `ck0011_a010_map.put(CSSTI_SHS_PCD, paramMap.get(PARAM_KEY_CSSTI_SHS_AD_PCD))` |
| 2 | SET | `ck0011_a010_map.put(CSSTI_SHS_STATE_NM, paramMap.get(PARAM_KEY_CSSTI_SHS_AD_STATE))` |
| 3 | SET | `ck0011_a010_map.put(CSSTI_SHS_CITY_NM, paramMap.get(PARAM_KEY_CSSTI_SHS_AD_CITY))` |
| 4 | SET | `ck0011_a010_map.put(CSSTI_SHS_OAZTSU_NM, paramMap.get(PARAM_KEY_CSSTI_SHS_AD_OAZTSU))` |
| 5 | SET | `ck0011_a010_map.put(CSSTI_SHS_AZCHO_NM, paramMap.get(PARAM_KEY_CSSTI_SHS_AD_AZCHO))` |
| 6 | SET | `ck0011_a010_map.put(CSSTI_SHS_BNCHIGO, paramMap.get(PARAM_KEY_CSSTI_SHS_AD_BNCHIGO))` |
| 7 | SET | `ck0011_a010_map.put(CSSTI_SHS_ADRTTM, paramMap.get(PARAM_KEY_CSSTI_SHS_AD_ADRTTM))` |
| 8 | SET | `ck0011_a010_map.put(CSSTI_SHS_ADRRM, paramMap.get(PARAM_KEY_CSSTI_SHS_AD_ADRRM))` |
| 9 | SET | `ck0011_a010_map.put(CSSTI_SHS_AD_MAN_INPUT_FLG, REIGAI ? "1" : "0")` // OM-2013-0000871: manual input flag |
| 10 | SET | `ck0011_a010_map.put("cssti_shs_ad_chk_lv", "1")` // ST3-2013-0000040: check level |

#### Block 6.1.3 — Common Map Population (L5705)

Populate shared fields regardless of address change scope.

| # | Type | Code |
|---|------|------|
| 1 | SET | `ck0011_a010_map.put(RSV_APLY_YMD, paramMap.get(PARAM_KEY_CSSTI_SHS_APLY_YMD))` |
| 2 | SET | `ck0011_a010_map.put(UPD_DT_CUST_UPD_DTM_BEF, paramMap.get(PARAM_KEY_CSSTI_SHS_AD_UPD_DTM_BF))` |

#### Block 6.2 — Phone/Name Only Update Path (L5496 ELSE)

If `updateNaiyo` is `"2"` (phone only) or `"3"` (name only), skip address field comparison entirely.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | (No address processing; proceeds directly to Block 7) |

### Block 7 — Sub-Type Determination (Individual vs. Corporate) (L5725)

Determines whether the delivered address belongs to an individual customer (個人, Kojin), corporate customer (法人, Hojin), or both. Uses generation timestamp comparison to resolve conflicts.

| # | Type | Code |
|---|------|------|
| 1 | SET | `subKojin = false` // Individual sub-type flag |
| 2 | SET | `gene_Kojin = new String()` // Individual generation timestamp |
| 3 | SET | `ck0021_a010_map = new HashMap<String, Object>()` // Individual consent map |
| 4 | SET | `subHojin = false` // Corporate sub-type flag |
| 5 | SET | `gene_Hojin = new String()` // Corporate generation timestamp |
| 6 | SET | `ck0031_a010_map = new HashMap<String, Object>()` // Corporate consent map |

#### Block 7.1 — Individual Customer Consent (ECK0021A010) (L5733)

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `condMap.clear()` |
| 2 | SET | `condMap.put(COND_KEY_SYSID, paramMap.get(PARAM_KEY_SYSID))` |
| 3 | SET | `condMap.put(COND_KEY_OPEDATE, paramMap.get(PARAM_KEY_KSH_APLY_YMD))` // Contract address apply date |
| 4 | CALL | `reqMap = mapper.setECK0021A010(param, fixedText, condMap)` |
| 5 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` |
| 6 | IF-ELSE | `if (resMap.containsKey(JCMConstants.TEMPLATE_LIST_KEY))` [L5742] |
| 6.1 | SET | `templates = (CAANMsg[])resMap.get(JCMConstants.TEMPLATE_LIST_KEY)` |
| 6.2 | SET | `template = templates[0]` |
| 6.3 | SET | `templateArrayKojin = template.getCAANMsgList(ECK0021A010CBSMsg1List)` |
| 6.4 | IF-ELSE | `if (templateArrayKojin != null && templateArrayKojin.length > 0)` [L5751] |
| 6.4.1 | CALL | `ck0021_a010_map = mapper.getECK0021A010(param, fixedText, resMap)` |
| 6.4.2 | CALL | `mapper.scResultCheck(param)` |
| 6.4.3 | SET | `gene_Kojin = ck0021_a010_map.get(GENE_ADD_DTM)` |
| 6.4.4 | SET | `subKojin = true` |
| 6.5 | ELSE | `subKojin = false` |

#### Block 7.2 — Corporate Customer Consent (ECK0031A010) (L5784)

Same pattern as Block 7.1 for corporate (Hojin) consent.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `condMap.clear()` |
| 2 | SET | `condMap.put(COND_KEY_SYSID, paramMap.get(PARAM_KEY_SYSID))` |
| 3 | SET | `condMap.put(COND_KEY_OPEDATE, paramMap.get(PARAM_KEY_KSH_APLY_YMD))` |
| 4 | CALL | `reqMap = mapper.setECK0031A010(param, fixedText, condMap)` |
| 5 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` |
| 6 | IF-ELSE | `if (resMap.containsKey(JCMConstants.TEMPLATE_LIST_KEY))` [L5798] |
| 6.1 | SET | `templateArrayHojin = template.getCAANMsgList(ECK0031A010CBSMsg1List)` |
| 6.2 | IF-ELSE | `if (templateArrayHojin != null && templateArrayHojin.length > 0)` [L5805] |
| 6.2.1 | CALL | `ck0031_a010_map = mapper.getECK0031A010(param, fixedText, resMap)` |
| 6.2.2 | SET | `gene_Hojin = ck0031_a010_map.get(GENE_ADD_DTM)` |
| 6.2.3 | SET | `subHojin = true` |

#### Block 7.3 — Resolution Logic (L5833)

If both individual and corporate sub-types have data, compare generation timestamps to decide which is newer.

| # | Type | Code |
|---|------|------|
| 1 | IF-ELSE | `if (subKojin && subHojin)` [L5833] |
| 2 | IF-ELSE | `if (gene_Kojin.compareTo(gene_Hojin) > 0)` [L5837] |
| 2.1 | SET | `subHojin = false` // Individual is newer |
| 3 | ELSE | SET `subKojin = false` // Corporate is newer |
| 4 | ELSE | // Only one exists — keep it; the other is false by default |

### Block 8 — Sub-Type Content Update (L5852)

Executes the content update SC for whichever sub-type won the resolution.

#### Block 8.1 — Individual Content Update (ECK0021C010) (L5854)

| # | Type | Code |
|---|------|------|
| 1 | IF-ELSE | `if (subKojin)` [L5854] |
| 2 | CALL | `reqMap = mapper.setECK0021C010(param, fixedText, ck0011_a010_map, ck0021_a010_map)` |
| 3 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` |
| 4 | CALL | `ck0021_c010_map = mapper.getECK0021C010(param, fixedText, resMap)` |
| 5 | CALL | `mapper.scResultCheck(param)` |
| 6 | SET | `paramMap.put(PARAM_KEY_CSSTI_SHS_AD_UPD_DTM_AF, ck0021_c010_map.get(UPD_DTM))` // Update timestamp after |
| 7 | SET | `ad_chk_lv_res = paramMap.get(ECK0021C010CBSMsg.KEISHA_AD_CHK_LV_ERR)` // Contract address check error |
| 8 | SET | `ad_chk_lv_res = paramMap.get(ECK0021C010CBSMsg.CONT_AD_CHK_LV_ERR)` // Contents address check error |
| 9 | SET | `ad_chk_lv_res = paramMap.get(ECK0021C010CBSMsg.OFFC_AD_CHK_LV_ERR)` // Workplace address check error |
| 10 | SET | `ad_chk_lv_res = paramMap.get(ECK0021C010CBSMsg.SKSHA_AD_CHK_LV_ERR)` // Parent address check error |
| 11 | SET | `ad_chk_lv_res = paramMap.get(ECK0021C010CBSMsg.CSSTI_SHS_AD_CHK_LV_ERR)` // Delivered address check error |

#### Block 8.2 — Corporate Content Update (ECK0031C010) (L5898)

Same pattern as Block 8.1 for corporate.

| # | Type | Code |
|---|------|------|
| 1 | IF-ELSE | `else if (subHojin)` [L5898] |
| 2 | CALL | `reqMap = mapper.setECK0031C010(param, fixedText, ck0011_a010_map, ck0031_a010_map)` |
| 3 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` |
| 4 | CALL | `ck0031_c010_map = mapper.getECK0031C010(param, fixedText, resMap)` |
| 5 | CALL | `mapper.scResultCheck(param)` |
| 6 | SET | `paramMap.put(PARAM_KEY_CSSTI_SHS_AD_UPD_DTM_AF, ck0031_c010_map.get(UPD_DTM))` |
| 7 | SET | `ad_chk_lv_res = paramMap.get(ECK0031C010CBSMsg.KEISHA_AD_CHK_LV_ERR)` |
| 8 | SET | `ad_chk_lv_res = paramMap.get(ECK0031C010CBSMsg.CONT_AD_CHK_LV_ERR)` |
| 9 | SET | `ad_chk_lv_res = paramMap.get(ECK0031C010CBSMsg.CSSTI_SHS_AD_CHK_LV_ERR)` |

#### Block 8.3 — Illegal Case (L5938)

Neither individual nor corporate sub-type was found.

| # | Type | Code |
|---|------|------|
| 1 | IF-ELSE | `else` [L5938] |
| 2 | THROW | `throw new CCException(JKKAdInfChgConstCC.ERR_STR_RESULT_CD, new Exception())` // Illegal customer type |

### Block 9 — Progress Supplement Text Truncation (L5943)

Trims trailing comma and truncates to max length for the progress supplement field.

| # | Type | Code |
|---|------|------|
| 1 | SET | `prg_tkjk_length = prg_tkjk.length()` |
| 2 | IF-ELSE | `if (prg_tkjk != null && !"".equals(prg_tkjk) && prg_tkjk_length > 0)` [L5945] |
| 2.1 | SET | `prg_tkjk = prg_tkjk.substring(0, prg_tkjk_length - 1)` // Strip trailing comma |
| 2.2 | IF-ELSE | `if (prg_tkjk_length - 1 > PRG_TKJK_MAX_VALUE)` [PRG_TKJK_MAX_VALUE=128] |
| 2.2.1 | SET | `prg_tkjk = prg_tkjk.substring(0, PRG_TKJK_MAX_VALUE)` // Truncate to 128 chars |
| 3 | IF-ELSE | Same logic for `prg_tkjk2` (ANK-2394-00-00, post-13.00) |

### Block 10 — Service Contract List Query (EKK0081B003) (L5963)

Retrieves active service contracts to determine the first service contract number for progress registration.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `condMap.clear()` |
| 2 | SET | `condMap.put(COND_KEY_SYSID, paramMap.get(PARAM_KEY_SYSID))` |
| 3 | SET | `condMap.put(COND_KEY_OPEDATE, paramMap.get(PARAM_KEY_OPE_DATE))` // Uses actual OPE_DATE here |
| 4 | CALL | `reqMap = mapper.setEKK0081B003(param, fixedText, condMap)` |
| 5 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` |
| 6 | CALL | `kk0081_b003_list = mapper.getEKK0081B003(param, fixedText, resMap)` |
| 7 | CALL | `mapper.scResultCheck(param)` |
| 8 | IF-ELSE | `if (kk0081_b003_list.size() == 0)` [L5978] |
| 8.1 | SET | `fstSvcKeiNo = paramMap.get(PARAM_KEY_SVC_KEI_NO)` // Use from param |
| 9 | ELSE | SET `fstSvcKeiNo = kk0081_b003_list.get(0).get(SVC_KEI_NO)` // Use from first contract |

### Block 11 — Progress Registration (EKK1091D010) (L5983)

Registers the progress event for "Delivered Address Change" (E090).

| # | Type | Code |
|---|------|------|
| 1 | SET | `parent_map = new HashMap<String, Object>()` |
| 2 | SET | `parent_map.put(SVC_KEI_NO, paramMap.get(PARAM_KEY_SVC_KEI_NO))` // OM-2014-0004032: from param (not fstSvcKeiNo) |
| 3 | SET | `parent_map.put(IDO_DIV, paramMap.get(PARAM_KEY_IDO_DIV))` |
| 4 | SET | `parent_map.put(IDO_DTM, JCCBPCommon.getSysDateTimeStamp())` |
| 5 | SET | `parent_map.put(PRG_STAT, CD00647_E090)` // "E090" - Delivered Address Change progress status |
| 6 | SET | `parent_map.put(PRG_TKJK_1, prg_tkjk)` // Old address supplement text |
| 7 | SET | `parent_map.put(PRG_TKJK_2, prg_tkjk2)` // New address supplement text |
| 8 | IF-ELSE | `if (!StringUtils.isEmpty(mskm_dtl_no))` [L5998] |
| 8.1 | SET | `parent_map.put(MSKM_DTL_NO, paramMap.get(PARAM_KEY_MSKM_DTL_NO))` |
| 9 | CALL | `reqMap = mapper.setEKK1091D010(param, fixedText, parent_map, getIdoRsnList(param, fixedText))` |
| 10 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` |
| 11 | CALL | `mapper.getEKK1091D010(param, fixedText, resMap)` |
| 12 | CALL | `mapper.scResultCheck(param)` |

### Block 12 — Exception Handling (L6006)

| # | Type | Code |
|---|------|------|
| 1 | CATCH | `catch (Exception ex)` |
| 2 | THROW | `throw new CCException(JKKAdInfChgConstCC.ERR_STR_RESULT_CD, ex.getCause())` // Maps to "サービスコンポーネントの実行結果にエラーがあります" |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `siteiShsAdUpd` | Method | Delivered Address Update — updates the address where bills, notices, and goods are delivered to a customer |
| `ksh_upd_um` | Field | Contract Address Update Flag — whether the main contract address (契約者住所) needs updating |
| `sitei_shs_upd_um` | Field | Delivered Address Update Flag — whether the delivered address (送付先住所) needs updating |
| `updateNaiyo` | Field | Update Content (更新内容) — specifies what is being updated: "0"=all, "1"=address only, "2"=phone only, "3"=name only, "4"=address+phone |
| `PARAM_KEY_UPDATE_NAIYO` | Field | Map key for updateNaiyo — `"upd_naiyo"` |
| `COND_KEY_SYSID` | Constant | System ID condition key |
| `COND_KEY_OPEDATE` | Constant | Operation date condition key |
| `PARAM_KEY_SYSID` | Field | System identifier for the customer |
| `PARAM_KEY_CSSTI_SHS_AD_AD_CD` | Field | Delivered address code — classification code for the delivery address type |
| `PARAM_KEY_CSSTI_SHS_AD_PCD` | Field | Delivered address postal code (送付先住所郵便番号) |
| `PARAM_KEY_CSSTI_SHS_AD_STATE` | Field | Delivered address prefecture (都道府県) |
| `PARAM_KEY_CSSTI_SHS_AD_CITY` | Field | Delivered address city/ward/town (市区町村) |
| `PARAM_KEY_CSSTI_SHS_AD_OAZTSU` | Field | Delivered address district (邦町) |
| `PARAM_KEY_CSSTI_SHS_AD_AZCHO` | Field | Delivered address block (町丁番) |
| `PARAM_KEY_CSSTI_SHS_AD_BNCHIGO` | Field | Delivered address block extra (丁番外号) |
| `PARAM_KEY_CSSTI_SHS_AD_ADRTTM` | Field | Delivered address room/building number (室号) |
| `PARAM_KEY_CSSTI_SHS_AD_ADRRM` | Field | Delivered address building name (建物名) |
| `PARAM_KEY_CSSTI_SHS_APLY_YMD` | Field | Reservation apply date (予約適用年月日) — the effective date of the reservation |
| `PARAM_KEY_KSH_APLY_YMD` | Field | Contract address apply date — effective date for the contract address |
| `PARAM_KEY_OPE_DATE` | Field | Operation date (運用日付) |
| `PARAM_KEY_SVC_KEI_NO` | Field | Service contract number (サービス契約番号) |
| `PARAM_KEY_IDO_DIV` | Field | Divergence classification (異動区分) — type of data divergence/change |
| `PARAM_KEY_IDO_RSN_LIST` | Field | Divergence reason list (異動理由リスト) |
| `PARAM_KEY_CSSTI_SHS_AD_MAN_INPUT_FLG` | Field | Manual input flag — indicates the address was manually entered rather than auto-populated |
| `PARAM_KEY_REIGAI` | Field | Outlier/exemption flag — when true, sets manual input flag to "1" |
| `PARAM_KEY_CSSTI_SHS_AD_UPD_DTM_BF` | Field | Delivered address update timestamp before (更新年月日時分秒前) |
| `PARAM_KEY_CSSTI_SHS_AD_UPD_DTM_AF` | Field | Delivered address update timestamp after (更新年月日時分秒後) |
| `PARAM_KEY_MSKM_DTL_NO` | Field | Emergency notice detail number (緊急通報試知事項詳細番号) |
| `PARAM_KEY_FUNC_CD` | Field | Function code (機能コード) — identifies the operation mode |
| `prg_tkjk` | Field | Progress supplement text (進捗補足事項) — concatenated old address description |
| `prg_tkjk2` | Field | Progress supplement text (after) — concatenated new address description (ANK-2394-00-00) |
| `PRG_TKJK_MAX_VALUE` | Constant | Maximum length for progress supplement text = **128** characters |
| `CD00647_E090` | Constant | Progress status code = **"E090"** — Delivered Address Change (緊急通報住所変曳) |
| `CD00002_NASHI` | Constant | "0" — No / Absent |
| `CD00002_ARI` | Constant | "1" — Yes / Present |
| `CD00036_OWN_ORNER` | Constant | "1" — Individual customer (個人) |
| `CD00036_COMP_ORNER` | Constant | "2" — Corporate customer (法人) |
| `UPDATE_TEL` | Constant | "2" — Phone number only update |
| `UPDATE_NM` | Constant | "3" — Name only update |
| `UPDATE_ALL` | Constant | "0" — All fields update |
| `ERR_STR_RESULT_CD` | Constant | Error message string: "サービスコンポーネントの実行結果にエラーがあります" (Error in service component execution result) |
| `FUNC_CODE_1` | Constant | "1" — Check + Register |
| `FUNC_CODE_2` | Constant | "2" — Check only |
| `subKojin` | Field | Individual (Kojin) sub-type flag — whether the delivered address belongs to an individual customer |
| `subHojin` | Field | Corporate (Hojin) sub-type flag — whether the delivered address belongs to a corporate customer |
| `gene_Kojin` | Field | Individual generation/addition timestamp — used to compare which sub-type is newer |
| `gene_Hojin` | Field | Corporate generation/addition timestamp — used to compare which sub-type is newer |
| `AdChangeFlg` | Field | Address Change Flag — set to true if any address component has changed |
| `ECK0011A010` | SC | Customer Consent Agreement — retrieves the consent holder information |
| `ECK0021A010` | SC | Individual Customer Consent Agreement — retrieves consent for individual (個人) customers |
| `ECK0021C010` | SC | Individual Customer Content Update — updates content for individual customers |
| `ECK0031A010` | SC | Corporate Customer Consent Agreement — retrieves consent for corporate (法人) customers |
| `ECK0031C010` | SC | Corporate Customer Content Update — updates content for corporate customers |
| `EKK0081B003` | SC | Service Contract List (non-canceled) — retrieves active service contracts |
| `EKK1091D010` | SC | Progress Registration — registers a change event in the progress log |
| Kojin (個人) | Business term | Individual customer — a natural person who is a subscriber |
| Hojin (法人) | Business term | Corporate customer — a legal entity (company, organization) that is a subscriber |
| Ksh (契約者住所) | Business term | Contract address — the primary address associated with the customer's contract |
| Sitei Shs (送付先住所) | Business term | Delivered address — the address where bills, notices, and goods are delivered (may differ from contract address) |
| AdInfChg (住所情報変曳) | Business term | Address Information Change — the overall process of updating customer address data |
| Progress (進捗) | Business term | Progress log — audit trail recording what data changed and when |
| Divergence (異動) | Business term | Data divergence — tracked changes to customer data for audit and notification purposes |
| Fmtcel Ido (フェムトセル異動) | Business term | Format cell divergence — a type of divergence notification for formatted data changes (name/canji) |
| CSSTI_SHS_AD_CHK_LV_ERR | Field | Delivered address check level error — error result from address validation |
| KEISHA_AD_CHK_LV_ERR | Field | Contract address check level error |
| CONT_AD_CHK_LV_ERR | Field | Contents address check level error |
| OFFC_AD_CHK_LV_ERR | Field | Workplace address check level error |
| SKSHA_AD_CHK_LV_ERR | Field | Parent address check level error |
| AD_MAN_INPUT_FLG | Field | Manual input flag — "1" if address was manually entered, "0" if auto-populated |
| cssti_shs_ad_chk_lv | Field | Delivered address check level — set to "1" for validation level |
| RSV_APLY_YMD | Field | Reservation apply date (予約適用年月日) |
| UPD_DTM | Field | Update datetime (更新年月日時分秒) |
| GENE_ADD_DTM | Field | Generation/addition datetime (世代登録年月日時分秒) |
| KK_T_CUST_AGREE | DB Table | Customer consent agreement table (ECK entity) |
| KK_T_CUST_AGREE_INDIV | DB Table | Individual customer consent agreement table (ECK0021 entity) |
| KK_T_CUST_AGREE_CORP | DB Table | Corporate customer consent agreement table (ECK0031 entity) |
| KK_T_SVC_CONTRACT | DB Table | Service contract table (EKK entity) |
| KK_T_PROGRESS | DB Table | Progress log table (EKK1091 entity) |
| IRequestParameterReadWrite | Interface | Request parameter interface carrying screen data and control maps |
| ServiceComponentRequestInvoker | Class | Invoker that executes Service Component (SC) requests against the backend |
| JKKAdInfChgMapperCC | Class | Mapper component that builds and deserializes SC request/response maps |
| KKSV0156 | Screen | Address Information Change Screen — the front-end screen that triggers this flow |
