# Business Logic — JKKAdchgCheckerCC.checkSecurityPackOrInetsgwl() [277 LOC]

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

## 1. Role

### JKKAdchgCheckerCC.checkSecurityPackOrInetsgwl()

This method performs **portability validation** for optional discounted service contracts when a customer is undergoing an address change (転居先). Specifically, it checks whether "Security Pack" (セキュリティーパック), "Premium Pack" (プレミアムパック), "Internet Security" (インターネットセキュリティー), or "No-Net/No-Net-Family Premium" (ノーネットファミリープレミアム) optional services associated with the post-move address would conflict with the pre-move state of these same services — a critical business check to prevent unintended double-subscription or contract conflicts during relocation.

The method operates as a **shared validation utility** called from the address-change screen operation (KKSV0698OPOperation). It follows a **filter-and-dispatch** design pattern: it first gathers all optional service contracts linked to the address change detail records, then routes to three independent validation branches (discount pack branch, internet security branch, and no-net premium branch) based on the service type codes found. Each branch queries the post-move address for existing optional contracts with active status, skipping cancelled (キャンセル済 / `CD00055_CSLZM`) or terminated (解約済 / `CD00055_DSLZM`) records, and raises a check error flag if a conflict is detected.

Its role in the larger system is to protect business integrity during the address-change (住所変更) workflow: when a customer moves, existing optional services that should transfer to the new address are validated to ensure no conflicting services already exist at the destination. The result flags are written back into the request parameter map for the UI to display appropriate error messages to the user.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["checkSecurityPackOrInetsgwl"])
    START --> TRY["Try Block Start"]
    TRY --> SAVE_HANDLE["KeepSesHandle.set handle"]
    SAVE_HANDLE --> GET_DATA["param.getData fixedText"]
    GET_DATA --> CHECK_PARAM_NULL{"paramMap != null"}
    CHECK_PARAM_NULL -->|Yes| INIT_RESULTS["Initialize check results to OK"]
    INIT_RESULTS --> CHECK_SVC_KEYS["svcKeiNoNetBf or svcKeiNoNetAf not blank?"]
    CHECK_SVC_KEYS -->|No| RETURN["Return param"]
    CHECK_SVC_KEYS -->|Yes| GET_ADCHG_NO["get adchgAdchgNo from paramMap"]
    GET_ADCHG_NO --> CALL_EKK2101["setEKK2101B001 getEKK2101B001"]
    CALL_EKK2101 --> FILTER_EXIST["getExistDt mkFlg"]
    FILTER_EXIST --> FILTER_OP_SVC["getDtlDt OP_SVC_CD filter"]
    FILTER_OP_SVC --> OP_SVC_LOOP{"opSvcKeiLst has next"}
    OP_SVC_LOOP -->|Yes| GET_SVC_KEY_AFT["get CHAF_SKBT_NO"]
    GET_SVC_KEY_AFT --> CHECK_SVC_AFT_BLANK{"svcKeiNo_aft blank?"}
    CHECK_SVC_AFT_BLANK -->|Yes| OP_SVC_LOOP
    CHECK_SVC_AFT_BLANK -->|No| CALL_EKK0351A["setEKK0351A010 getEKK0351A010"]
    CALL_EKK0351A --> GET_OP_SVC_CD["get OP_SVC_CD"]
    GET_OP_SVC_CD --> CHECK_OP_SVC{"OP_SVC_CD == B131 or B132?"}
    CHECK_OP_SVC -->|No| OP_SVC_LOOP
    CHECK_OP_SVC -->|Yes| SET_NET_INETS["netInetsgwlUm = true if B131"]
    SET_NET_INETS --> SET_NET_NTFC["netNtfmlprmUm = true if B132"]
    SET_NET_NTFC --> OP_SVC_LOOP
    OP_SVC_LOOP -->|No| GET_NET_PACK["getDtlDt NET_PACK filter"]
    GET_NET_PACK --> NET_PACK_LOOP{"netPackLst has next"}
    NET_PACK_LOOP -->|Yes| GET_WRIB_SVC["get CHAF_SKBT_NO"]
    GET_WRIB_SVC --> CALL_EKK0451A["setEKK0451A010 getEKK0451A010"]
    CALL_EKK0451A --> GET_WRIB_SVC_CD["get WRIB_SVC_CD"]
    GET_WRIB_SVC_CD --> CHECK_WRIB_SVC{"W00000010 or W00000080?"}
    CHECK_WRIB_SVC -->|No| NET_PACK_LOOP
    CHECK_WRIB_SVC -->|Yes| SET_SEC_PACK["securityPackUm = true if W00000010"]
    SET_SEC_PACK --> SET_PREM_PACK["premiumPackUm = true if W00000080"]
    SET_PREM_PACK --> NET_PACK_LOOP
    NET_PACK_LOOP -->|No| CHECK_SEC_PREM{"securityPackUm or premiumPackUm?"}
    CHECK_SEC_PREM -->|Yes| CALL_EKK0451B["setEKK0451B002 getEKK0451B002_SUB"]
    CALL_EKK0451B --> WRIB_LIST_LOOP{"kk0451B002 has next"}
    WRIB_LIST_LOOP -->|Yes| CHECK_WRIB_STAT{"CD00055_DSLZM or CSLZM?"}
    CHECK_WRIB_STAT -->|Yes| WRIB_LIST_LOOP
    CHECK_WRIB_STAT -->|No| CHECK_WRIB_SVC_CD2{"wribSvcCd == W00000010?"}
    CHECK_WRIB_SVC_CD2 -->|Yes| SET_SEC_ERR1["check_security_result = 1"]
    SET_SEC_ERR1 --> CHECK_WRIB_SVC_CD3{"wribSvcCd == W00000080?"}
    CHECK_WRIB_SVC_CD3 -->|Yes| SET_SEC_ERR2["check_security_result = 2"]
    SET_SEC_ERR2 --> CHECK_PREM{"premiumPackUm and wribSvcCd == W00000080?"}
    CHECK_PREM -->|Yes| SET_PREM_ERR1["check_premium_result = 1"]
    SET_PREM_ERR1 --> CHECK_PREM_SEC["premiumPackUm and wribSvcCd == W00000010?"]
    CHECK_PREM_SEC -->|Yes| SET_PREM_ERR2["check_premium_result = 2"]
    CHECK_PREM_SEC -->|No| WRIB_LIST_LOOP
    CHECK_WRIB_SVC_CD2 -->|No| CHECK_WRIB_SVC_CD3
    CHECK_WRIB_SVC_CD3 -->|No| CHECK_PREM
    CHECK_PREM -->|No| WRIB_LIST_LOOP
    CHECK_SEC_PREM -->|No| CHECK_NET_INETS{"netInetsgwlUm?"}
    SET_NET_INETS --> CHECK_SEC_PREM
    SET_NET_NTFC --> CHECK_SEC_PREM
    SET_SEC_ERR2 --> CHECK_NET_INETS
    SET_PREM_ERR1 --> CHECK_NET_INETS
    SET_PREM_ERR2 --> CHECK_NET_INETS
    CHECK_NET_INETS -->|Yes| CALL_INETSGWL["setEKK0351B002 getEKK0351B002"]
    CALL_INETSGWL --> INETSGWL_LOOP{"kk0351B002 has next"}
    INETSGWL_LOOP -->|Yes| CHECK_INET_STAT{"CD00055_DSLZM or CSLZM?"}
    CHECK_INET_STAT -->|Yes| INETSGWL_LOOP
    CHECK_INET_STAT -->|No| CHECK_INET_SVC_CD{"opSvcCd == B131?"}
    CHECK_INET_SVC_CD -->|Yes| SET_INET_ERR["check_inetsgwl_result = 1"]
    SET_INET_ERR --> INETSGWL_LOOP
    CHECK_NET_INETS -->|No| CHECK_NET_NTFC{"netNtfmlprmUm?"}
    INETSGWL_LOOP --> CHECK_NET_NTFC
    CHECK_NET_NTFC -->|Yes| CALL_NTFC["setEKK0351B002 getEKK0351B002"]
    CALL_NTFC --> NTFC_LOOP{"kk0351B002 has next"}
    NTFC_LOOP -->|Yes| CHECK_NTFC_STAT{"CD00055_DSLZM or CSLZM?"}
    CHECK_NTFC_STAT -->|Yes| NTFC_LOOP
    CHECK_NTFC_STAT -->|No| CHECK_NTFC_SVC_CD{"opSvcCd == B132?"}
    CHECK_NTFC_SVC_CD -->|Yes| SET_NTFC_ERR["check_ntfmlprm_result = 1"]
    SET_NTFC_ERR --> NTFC_LOOP
    NTFC_LOOP --> RETURN
    CHECK_NET_NTFC -->|No| RETURN
    RETURN --> FINALLY["finally: keepSesHandle.remove"]
    FINALLY --> END(["Return param"])
```

**Constant Resolution Reference:**

| Constant | Value | Meaning |
|----------|-------|---------|
| `OP_SVC_CD_INETSGWL` | `"B131"` | Internet Security (オプションサービス種別コード) |
| `OP_SVC_CD_NTFMLPRM` | `"B132"` | No-Net Family Premium (オプションサービス種別コード) |
| `WRIB_SVC_CD_SECURITY_PACK` | `"W00000010"` | Security Pack (割引サービスコード) |
| `WRIB_SVC_SMARTLINK_PREMIUM` | `"W00000080"` | Premium Pack (割引サービスコード) |
| `CD00055_DSLZM` | `"910"` | Contract Terminated (解約済ステータス) |
| `CD00055_CSLZM` | `"920"` | Contract Cancelled (キャンセル済ステータス) |

All constants are defined in `JKKStrConst.java`. `OP_SVC_CD_INETSGWL` and `OP_SVC_CD_NTFMLPRM` are at [-> JKKStrConst.java:2039] and [-> JKKStrConst.java:2041] respectively. `WRIB_SVC_CD_SECURITY_PACK` and `WRIB_SVC_SMARTLINK_PREMIUM` are at [-> JKKStrConst.java:5283] and [-> JKKStrConst.java:5286]. `CD00055_DSLZM` and `CD00055_CSLZM` are at [-> JKKStrConst.java:2721] and [-> JKKStrConst.java:2725].

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `handle` | `SessionHandle` | Database session handle carrying the transactional context for the address-change workflow. Used for persistence operations when querying SC layers. Preserved in a ThreadLocal (`keepSesHandle`) across method execution and cleaned up in the finally block. |
| 2 | `param` | `IRequestParameterReadWrite` | Request parameter container holding both the model group data and control map for the address-change screen. Contains pre-move and post-move service contract numbers (`net_svc_kei_no_bf`, `net_svc_kei_no_af`), the address change detail number (`adchg_adchg_no`), and a system identifier (`sysid`). The method writes check result flags back into this object's data map (`check_security_result`, `check_premium_result`, `check_inetsgwl_result`, `check_ntfmlprm_result`). |
| 3 | `fixedText` | `String` | User-defined arbitrary text string passed through to SC layer calls for logging and traceability purposes. Used as an identifier prefix in mapper and service component invocations. |

**Instance fields / external state read:**
| Field | Type | Business Description |
|-------|------|---------------------|
| `keepSesHandle` | `ThreadLocal<SessionHandle>` | Thread-local storage for preserving the session handle across the method's try-finally boundary. Set at the start, removed in the finally block to prevent memory leaks. |

## 4. CRUD Operations / Called Services

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `JKKAdchgMapperCC.setEKK2101B001` | EKK2101B001 | KK_T_ADCHG_DTL (Address Change Detail) | Sets conditions and calls the SC to fetch address change detail records |
| R | `JKKAdchgMapperCC.getEKK2101B001` | EKK2101B001 | KK_T_ADCHG_DTL (Address Change Detail) | Retrieves address change detail list from SC response |
| R | `JKKAdchgMapperCC.scResultCheck` | EKK2101B001 | - | Checks SC layer result for errors |
| R | `JKKAdchgMapperCC.setEKK0351A010` | EKK0351A010 | KK_T_OP_SVC_KEI_AGREE (Option Service Contract Agreement) | Sets conditions and calls the SC to fetch option service contract agreement details for a specific service contract number |
| R | `JKKAdchgMapperCC.getEKK0351A010` | EKK0351A010 | KK_T_OP_SVC_KEI_AGREE | Retrieves option service contract agreement data |
| R | `JKKAdchgMapperCC.scResultCheck` | EKK0351A010 | - | Checks SC layer result for errors |
| R | `JKKAdchgMapperCC.setEKK0451A010` | EKK0451A010 | KK_T_WRIB_SVC_KEI_AGREE (Discount Service Contract Agreement) | Sets conditions and calls the SC to fetch discount service contract agreement details |
| R | `JKKAdchgMapperCC.getEKK0451A010` | EKK0451A010 | KK_T_WRIB_SVC_KEI_AGREE | Retrieves discount service contract agreement data |
| R | `JKKAdchgMapperCC.scResultCheck` | EKK0451A010 | - | Checks SC layer result for errors |
| R | `JKKAdchgMapperCC.setEKK0451B002` | EKK0451B002 | KK_T_WRIB_SVC_KEI (Discount Service Contract List) | Sets conditions and calls the SC to list discount service contracts for a given service contract number |
| R | `JKKAdchgMapperCC.getEKK0451B002_SUB` | EKK0451B002 | KK_T_WRIB_SVC_KEI | Retrieves discount service contract list from SC response |
| R | `JKKAdchgMapperCC.scResultCheck` | EKK0451B002 | - | Checks SC layer result for errors |
| R | `JKKAdchgMapperCC.setEKK0351B002` | EKK0351B002 | KK_T_OP_SVC_KEI (Option Service Contract List) | Sets conditions and calls the SC to list option service contracts for a given service contract number and option service type code |
| R | `JKKAdchgMapperCC.getEKK0351B002` | EKK0351B002 | KK_T_OP_SVC_KEI | Retrieves option service contract list from SC response |
| R | `JKKAdchgMapperCC.scResultCheck` | EKK0351B002 | - | Checks SC layer result for errors |
| R | `JCCBPCommon.getOpeDate` | - | - | Retrieves the current operation date used as a condition key in SC queries |
| - | `JCCbatMojiChgReferenceCache.getInstance` | - | - | Retrieves singleton cache instance (if referenced) |
| - | `JCCbatMojiChgRuleCache.getInstance` | - | - | Retrieves singleton cache instance (if referenced) |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Screen:KKSV0698 | `KKSV0698OPOperation` -> `CCRequestBroker` -> `JKKAdchgCheckerCC.checkSecurityPackOrInetsgwl` | `EKK2101B001 [R] KK_T_ADCHG_DTL`, `EKK0351A010 [R] KK_T_OP_SVC_KEI_AGREE`, `EKK0451A010 [R] KK_T_WRIB_SVC_KEI_AGREE`, `EKK0451B002 [R] KK_T_WRIB_SVC_KEI`, `EKK0351B002 [R] KK_T_OP_SVC_KEI` |

**Caller Context:** KKSV0698 is an address-change confirmation screen (転居先確認画面). The method is invoked through a `CCRequestBroker` (CCターゲット) as a validation step during the address-change operation. It serves as a pre-commit check before finalizing the address change, ensuring that any optional discounted services or security services that would transfer to the new address do not create contractual conflicts.

## 6. Per-Branch Detail Blocks

**Block 1** — [TRY-CATCH] `(exception handling boundary, preserves session handle)` (L1969)

> The entire method body is wrapped in a try-finally block to guarantee session handle cleanup regardless of whether exceptions occur.

| # | Type | Code |
|---|------|------|
| 1 | SET | `keepSesHandle.set(handle)` // Preserve session handle in ThreadLocal [-> ThreadLocal.set] |
| 2 | EXEC | `paramMap = (HashMap)(param.getData(fixedText))` // Retrieve data map from request parameter [-> paramMap.get] |
| 3 | SET | `CHECK_RESULT_OK = "0"` // Success/OK check result flag constant |
| 4 | SET | `CHECK_RESULT_NG = "1"` // Error/NG check result flag constant |
| 5 | SET | `CHECK_RESULT_NG2 = "2"` // Critical conflict check result flag constant |

**Block 1.1** — [IF] `(paramMap != null)` (L1988)

> Guard clause: if the data map is null, skip all processing and return early.

| # | Type | Code |
|---|------|------|
| 1 | SET | `svcKeiNoNetBf = (String)paramMap.get("net_svc_kei_no_bf")` // Pre-move FTTH Net service contract number |
| 2 | SET | `svcKeiNoNetAf = (String)paramMap.get("net_svc_kei_no_af")` // Post-move FTTH Net service contract number |
| 3 | SET | `sysid = (String)paramMap.get("sysid")` // System identifier |
| 4 | SET | `adchgAdchgNo = (String)paramMap.get("adchg_adchg_no")` // Address change detail number |

**Block 1.1.1** — [IF] `(svcKeiNoNetAf == null || StringUtils.isEmpty(svcKeiNoNetAf))` (L1998)

> If the post-move FTTH Net service contract number is empty, the check is irrelevant — return immediately.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return param;` // Early return — no post-move net contract to check |

**Block 1.1.2** — [ELSE-IMPLICIT] `(svcKeiNoNetAf is not empty, proceed with checks)` (L2000)

> Initialize boolean flags and check result fields before entering the main validation logic.

| # | Type | Code |
|---|------|------|
| 1 | SET | `netNtfmlprmUm = false` // No-Net/Family Premium existence flag |
| 2 | SET | `netInetsgwlUm = false` // Internet Security existence flag |
| 3 | SET | `securityPackUm = false` // Security Pack existence flag |
| 4 | SET | `premiumPackUm = false` // Premium Pack existence flag |
| 5 | EXEC | `paramMap.put("check_security_result", CHECK_RESULT_OK)` // Initialize security check result to OK [-> CHECK_RESULT_OK="0"] |
| 6 | EXEC | `paramMap.put("check_premium_result", CHECK_RESULT_OK)` // Initialize premium check result to OK [-> CHECK_RESULT_OK="0"] |
| 7 | EXEC | `paramMap.put("check_inetsgwl_result", CHECK_RESULT_OK)` // Initialize internet security check result to OK [-> CHECK_RESULT_OK="0"] |
| 8 | EXEC | `paramMap.put("check_ntfmlprm_result", CHECK_RESULT_OK)` // Initialize no-net premium check result to OK [-> CHECK_RESULT_OK="0"] |

**Block 1.1.3** — [IF] `(!JKKStringUtil.isNullBlank(svcKeiNoNetBf) || !JKKStringUtil.isNullBlank(svcKeiNoNetAf))` (L2013)

> If either the pre-move or post-move FTTH Net service contract number is present, proceed with the full validation workflow.

| # | Type | Code |
|---|------|------|
| 1 | SET | `condMap = new HashMap()` // Prepare conditions map for SC queries |
| 2 | SET | `mapper = JKKAdchgMapperCC.getInstance()` // Retrieve mapper singleton |
| 3 | SET | `scCall = new ServiceComponentRequestInvoker()` // Create SC request invoker |

**Block 1.1.3.1** — [OPTIONAL SERVICE CONTRACT AGREEMENT DETAIL FETCH — e.g. Internet Security / No-Net Family Premium] (L2020)

> Fetch address change details, filter by option service code, then query each option service contract agreement to identify which optional services are present at the post-move address.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `condMap.clear()` // Clear conditions map |
| 2 | EXEC | `condMap.put(JKKAdchgMapperCC.COND_KEY_ADCHG_NO, adchgAdchgNo)` // Set address change detail number as query key [-> condMap.put] |
| 3 | CALL | `reqMap = mapper.setEKK2101B001(param, fixedText, condMap)` // Set SC conditions for address change detail query |
| 4 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` // Execute SC layer with session handle |
| 5 | CALL | `kk2101_b001_list = mapper.getEKK2101B001(param, fixedText, resMap)` // Retrieve address change detail list |
| 6 | CALL | `mapper.scResultCheck(param)` // Check SC result for errors |
| 7 | CALL | `exAdchgDtl = getExistDt(kk2101_b001_list, EKK2101B001CBSMsg1List.MK_FLG)` // Filter valid (enabled) records only |
| 8 | CALL | `opSvcKeiLst = getDtlDt(exAdchgDtl, JKKAdchgInitDspConstCC.CDXXXXX_OP_SVC_KEI)` // Filter option service contract details |

**Block 1.1.3.1.1** — [WHILE] `(opSvcKeiLstIte.hasNext())` (L2030)

> Iterate over each option service contract detail record to identify Internet Security (B131) or No-Net Family Premium (B132) services.

| # | Type | Code |
|---|------|------|
| 1 | SET | `curOpSvcKei = opSvcKeiLstIte.next()` // Get next option service contract record |
| 2 | EXEC | `condMap.clear()` // Clear conditions map for next query |
| 3 | SET | `svcKeiNo_aft = (String)curOpSvcKei.get(EKK2101B001CBSMsg1List.CHAF_SKBT_NO)` // Get post-move service contract number |

**Block 1.1.3.1.1.1** — [IF] `(StringUtils.isEmpty(svcKeiNo_aft))` (L2044)

> If the service contract number is blank, skip to the next record.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `continue;` // Skip record with no contract number |

**Block 1.1.3.1.1.2** — [OPTION SERVICE AGREEMENT DETAIL QUERY] (L2048)

> Query the option service contract agreement details to determine the service type code for the post-move service.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `condMap.put(JKKAdchgMapperCC.COND_KEY_OP_SVC_KEI_NO, svcKeiNo_aft)` // Set service contract number |
| 2 | EXEC | `condMap.put(JKKAdchgMapperCC.COND_KEY_OPEDATE, JKKAdchgConstCC.DEFAULT_RSV_APLY_YMD)` // Set default reservation application date [-> DEFAULT_RSV_APLY_YMD] |
| 3 | CALL | `reqMap = mapper.setEKK0351A010(param, fixedText, condMap)` // Query option service contract agreement |
| 4 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` // Execute SC layer |
| 5 | CALL | `kk0351_a010_map = mapper.getEKK0351A010(param, fixedText, resMap)` // Retrieve option service agreement |
| 6 | CALL | `mapper.scResultCheck(param)` // Check SC result for errors |
| 7 | SET | `opSvcCd = (String)kk0351_a010_map.get(EKK0351A010CBSMsg1List.OP_SVC_CD)` // Get option service type code |

**Block 1.1.3.1.1.3** — [IF] `!(opSvcCd.equals(OP_SVC_CD_INETSGWL) \|\| opSvcCd.equals(OP_SVC_CD_NTFMLPRM))` [OP_SVC_CD_INETSGWL="B131" (JKKStrConst.java:2039), OP_SVC_CD_NTFMLPRM="B132" (JKKStrConst.java:2041)] (L2051)

> If the option service is neither Internet Security (B131) nor No-Net Family Premium (B132), skip to the next record. Only these two optional services are relevant for the portability check.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `continue;` // Skip non-relevant option service |

**Block 1.1.3.1.1.4** — [IF] `(opSvcCd.equals(OP_SVC_CD_INETSGWL))` [OP_SVC_CD_INETSGWL="B131"] (L2053)

> This is an Internet Security optional service — flag it as present.

| # | Type | Code |
|---|------|------|
| 1 | SET | `netInetsgwlUm = true` // Mark Internet Security as existing at post-move address |

**Block 1.1.3.1.1.5** — [IF] `(opSvcCd.equals(OP_SVC_CD_NTFMLPRM))` [OP_SVC_CD_NTFMLPRM="B132"] (L2056)

> This is a No-Net Family Premium optional service — flag it as present.

| # | Type | Code |
|---|------|------|
| 1 | SET | `netNtfmlprmUm = true` // Mark No-Net Family Premium as existing at post-move address |

**Block 1.1.3.2** — [DISCOUNT PACK DETAIL FETCH — Security Pack / Premium Pack] (L2060)

> Fetch discount service contracts (e.g., Security Pack, Premium Pack) from the address change details, then query each discount service contract agreement to determine which discount packs are present at the post-move address.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `netPackLst = getDtlDt(exAdchgDtl, JKKAdchgInitDspConstCC.CDXXXXX_NET_PACK)` // Filter discount service package details |
| 2 | SET | `netPackLstIte = netPackLst.iterator()` // Prepare iterator |

**Block 1.1.3.2.1** — [WHILE] `(netPackLstIte.hasNext())` (L2064)

> Iterate over each discount service package record.

| # | Type | Code |
|---|------|------|
| 1 | SET | `curKojiAkNo = netPackLstIte.next()` // Get next discount service contract record |
| 2 | EXEC | `condMap.clear()` // Clear conditions map |
| 3 | SET | `wribSvcKeiAft = (String)curKojiAkNo.get(EKK2101B001CBSMsg1List.CHAF_SKBT_NO)` // Get discount service contract number |

**Block 1.1.3.2.1.1** — [IF] `(StringUtils.isEmpty(wribSvcKeiAft))` (L2075)

> If the discount service contract number is blank, skip to the next record.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `continue;` // Skip record with no contract number |

**Block 1.1.3.2.1.2** — [DISCOUNT SERVICE AGREEMENT DETAIL QUERY] (L2079)

> Query the discount service contract agreement details.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `condMap.put(JKKAdchgMapperCC.COND_KEY_WRIB_SVC_KEI_NO, wribSvcKeiAft)` // Set discount service contract number |
| 2 | CALL | `JCCBPCommon.getOpeDate(null)` // Get current operation date [-> JCCBPCommon.getOpeDate] |
| 3 | EXEC | `condMap.put(JKKAdchgMapperCC.COND_KEY_OPEDATE, getOpeDate)` // Set operation date |
| 4 | CALL | `reqMap = mapper.setEKK0451A010(param, fixedText, condMap)` // Query discount service contract agreement |
| 5 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` // Execute SC layer |
| 6 | CALL | `kk0451_a010 = mapper.getEKK0451A010(param, fixedText, resMap)` // Retrieve discount service agreement |
| 7 | CALL | `mapper.scResultCheck(param)` // Check SC result for errors |
| 8 | SET | `wribSvcCd = (String)kk0451_a010.get(EKK0451A010CBSMsg1List.WRIB_SVC_CD)` // Get discount service code |

**Block 1.1.3.2.1.3** — [IF] `!(wribSvcCd.equals(WRIB_SVC_CD_SECURITY_PACK) \|\| wribSvcCd.equals(WRIB_SVC_SMARTLINK_PREMIUM))` [WRIB_SVC_CD_SECURITY_PACK="W00000010" (JKKStrConst.java:5283), WRIB_SVC_SMARTLINK_PREMIUM="W00000080" (JKKStrConst.java:5286)] (L2085)

> If the discount service is neither Security Pack nor Premium Pack, skip to the next record.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `continue;` // Skip non-relevant discount service |

**Block 1.1.3.2.1.4** — [IF] `(wribSvcCd.equals(WRIB_SVC_CD_SECURITY_PACK))` [WRIB_SVC_CD_SECURITY_PACK="W00000010"] (L2088)

> Security Pack is present at the post-move address.

| # | Type | Code |
|---|------|------|
| 1 | SET | `securityPackUm = true` // Mark Security Pack as existing |

**Block 1.1.3.2.1.5** — [IF] `(wribSvcCd.equals(WRIB_SVC_SMARTLINK_PREMIUM))` [WRIB_SVC_SMARTLINK_PREMIUM="W00000080"] (L2091)

> Premium Pack is present at the post-move address.

| # | Type | Code |
|---|------|------|
| 1 | SET | `premiumPackUm = true` // Mark Premium Pack as existing |

**Block 1.1.3.3** — [IF] `(securityPackUm == true \|\| premiumPackUm == true)` (L2095)

> If either Security Pack or Premium Pack exists at the post-move address, validate whether the same discount packs already exist at the destination by querying the full discount service contract list.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `condMap.clear()` // Clear conditions map |
| 2 | EXEC | `condMap.put(JKKAdchgMapperCC.COND_KEY_SVC_KEI_NO, svcKeiNoNetAf)` // Set post-move service contract number |
| 3 | CALL | `reqMap = mapper.setEKK0451B002(param, fixedText, condMap)` // Query discount service contract list by service contract number |
| 4 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` // Execute SC layer |
| 5 | CALL | `kk0451_b002_list = mapper.getEKK0451B002_SUB(param, fixedText, resMap)` // Retrieve discount service contract list |
| 6 | CALL | `mapper.scResultCheck(param)` // Check SC result for errors |

**Block 1.1.3.3.1** — [WHILE] `(kk0451B002Ite.hasNext())` (L2104)

> Iterate over each discount service contract record in the list to check for conflicts.

| # | Type | Code |
|---|------|------|
| 1 | SET | `curWribSvcKeiLst = kk0451B002Ite.next()` // Get next discount service contract record |
| 2 | EXEC | `condMap.clear()` // Clear conditions map |
| 3 | SET | `wribSvcKeiStat = (String)curWribSvcKeiLst.get(EKK0451B002CBSMsg1List.WRIB_SVC_KEI_STAT)` // Get contract status |
| 4 | SET | `wribSvcCd = (String)curWribSvcKeiLst.get(EKK0451B002CBSMsg1List.WRIB_SVC_CD)` // Get discount service code |

**Block 1.1.3.3.1.1** — [IF] `(wribSvcKeiStat.equals(CD00055_DSLZM) \|\| wribSvcKeiStat.equals(CD00055_CSLZM))` [CD00055_DSLZM="910" (JKKStrConst.java:2721), CD00055_CSLZM="920" (JKKStrConst.java:2725)] (L2109)

> If the contract status is terminated (解約済 = 910) or cancelled (キャンセル済 = 920), skip this record — it is no longer active and does not constitute a conflict.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `continue;` // Skip cancelled/terminated contracts |

**Block 1.1.3.3.1.2** — [IF] `(securityPackUm == true && wribSvcCd.equals(WRIB_SVC_CD_SECURITY_PACK))` [WRIB_SVC_CD_SECURITY_PACK="W00000010"] (L2112)

> Security Pack is expected to transfer, and Security Pack already exists at the destination — this is a direct conflict.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `paramMap.put("check_security_result", CHECK_RESULT_NG)` // Set security check error to NG (1) [-> CHECK_RESULT_NG="1"] |

**Block 1.1.3.1.2.1** — [IF] `(securityPackUm == true && wribSvcCd.equals(WRIB_SVC_SMARTLINK_PREMIUM))` [WRIB_SVC_SMARTLINK_PREMIUM="W00000080"] (L2116)

> Security Pack is expected to transfer, but Premium Pack exists at the destination — this is a cross-type conflict (critical).

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `paramMap.put("check_security_result", CHECK_RESULT_NG2)` // Set security check error to NG2 (2) [-> CHECK_RESULT_NG2="2"] |

**Block 1.1.3.3.1.3** — [IF] `(premiumPackUm == true && wribSvcCd.equals(WRIB_SVC_SMARTLINK_PREMIUM))` [WRIB_SVC_SMARTLINK_PREMIUM="W00000080"] (L2120)

> Premium Pack is expected to transfer, and Premium Pack already exists at the destination — direct conflict.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `paramMap.put("check_premium_result", CHECK_RESULT_NG)` // Set premium check error to NG (1) |

**Block 1.1.3.3.1.4** — [IF] `(premiumPackUm == true && wribSvcCd.equals(WRIB_SVC_CD_SECURITY_PACK))` [WRIB_SVC_CD_SECURITY_PACK="W00000010"] (L2124)

> Premium Pack is expected to transfer, but Security Pack exists at the destination — cross-type conflict (critical).

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `paramMap.put("check_premium_result", CHECK_RESULT_NG2)` // Set premium check error to NG2 (2) |

**Block 1.1.3.4** — [IF] `(netInetsgwlUm == true)` (L2129)

> If Internet Security (B131) exists at the post-move address, validate whether Internet Security already exists at the destination by querying the option service contract list.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `condMap.clear()` // Clear conditions map |
| 2 | EXEC | `condMap.put(JKKAdchgMapperCC.COND_KEY_SVC_KEI_NO, svcKeiNoNetAf)` // Set post-move service contract number |
| 3 | EXEC | `condMap.put(JKKAdchgMapperCC.COND_KEY_OP_SVC_CD, OP_SVC_CD_INETSGWL)` // Filter by Internet Security option service code [-> OP_SVC_CD_INETSGWL="B131"] |
| 4 | CALL | `reqMap = mapper.setEKK0351B002(param, fixedText, condMap)` // Query option service contract list for Internet Security |
| 5 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` // Execute SC layer |
| 6 | CALL | `kk0351_b002_list = mapper.getEKK0351B002(param, fixedText, resMap)` // Retrieve option service contract list |
| 7 | CALL | `mapper.scResultCheck(param)` // Check SC result for errors |

**Block 1.1.3.4.1** — [WHILE] `(kk0351B002Ite.hasNext())` (L2138)

> Iterate over each option service contract record in the list.

| # | Type | Code |
|---|------|------|
| 1 | SET | `curOpSvcKeiLst = kk0351B002Ite.next()` // Get next record |
| 2 | EXEC | `condMap.clear()` // Clear conditions map |
| 3 | SET | `opSvcKeiStat = (String)curOpSvcKeiLst.get(EKK0351B002CBSMsg1List.OP_SVC_KEI_STAT)` // Get option service contract status |
| 4 | SET | `opSvcCd = (String)curOpSvcKeiLst.get(EKK0351B002CBSMsg1List.OP_SVC_CD)` // Get option service code |

**Block 1.1.3.4.1.1** — [IF] `(opSvcKeiStat.equals(CD00055_DSLZM) \|\| opSvcKeiStat.equals(CD00055_CSLZM))` [CD00055_DSLZM="910", CD00055_CSLZM="920"] (L2146)

> Skip terminated or cancelled records.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `continue;` // Skip non-active contracts |

**Block 1.1.3.4.1.2** — [IF] `(opSvcCd.equals(OP_SVC_CD_INETSGWL))` [OP_SVC_CD_INETSGWL="B131"] (L2151)

> Internet Security contract is already active at the destination — this is a conflict.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `paramMap.put("check_inetsgwl_result", CHECK_RESULT_NG)` // Set internet security check error to NG (1) |

**Block 1.1.3.5** — [IF] `(netNtfmlprmUm == true)` (L2155)

> If No-Net Family Premium (B132) exists at the post-move address, validate whether No-Net Family Premium already exists at the destination by querying the option service contract list.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `condMap.clear()` // Clear conditions map |
| 2 | EXEC | `condMap.put(JKKAdchgMapperCC.COND_KEY_SVC_KEI_NO, svcKeiNoNetAf)` // Set post-move service contract number |
| 3 | EXEC | `condMap.put(JKKAdchgMapperCC.COND_KEY_OP_SVC_CD, OP_SVC_CD_NTFMLPRM)` // Filter by No-Net Family Premium code [-> OP_SVC_CD_NTFMLPRM="B132"] |
| 4 | CALL | `reqMap = mapper.setEKK0351B002(param, fixedText, condMap)` // Query option service contract list for No-Net Family Premium |
| 5 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` // Execute SC layer |
| 6 | CALL | `kk0351_b002_list = mapper.getEKK0351B002(param, fixedText, resMap)` // Retrieve option service contract list |
| 7 | CALL | `mapper.scResultCheck(param)` // Check SC result for errors |

**Block 1.1.3.5.1** — [WHILE] `(kk0351B002Ite.hasNext())` (L2164)

> Iterate over each option service contract record in the list.

| # | Type | Code |
|---|------|------|
| 1 | SET | `curOpSvcKeiLst = kk0351B002Ite.next()` // Get next record |
| 2 | EXEC | `condMap.clear()` // Clear conditions map |
| 3 | SET | `opSvcKeiStat = (String)curOpSvcKeiLst.get(EKK0351B002CBSMsg1List.OP_SVC_KEI_STAT)` // Get option service contract status |
| 4 | SET | `opSvcCd = (String)curOpSvcKeiLst.get(EKK0351B002CBSMsg1List.OP_SVC_CD)` // Get option service code |

**Block 1.1.3.5.1.1** — [IF] `(opSvcKeiStat.equals(CD00055_DSLZM) \|\| opSvcKeiStat.equals(CD00055_CSLZM))` [CD00055_DSLZM="910", CD00055_CSLZM="920"] (L2172)

> Skip terminated or cancelled records.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `continue;` // Skip non-active contracts |

**Block 1.1.3.5.1.2** — [IF] `(opSvcCd.equals(OP_SVC_CD_NTFMLPRM))` [OP_SVC_CD_NTFMLPRM="B132"] (L2177)

> No-Net Family Premium contract is already active at the destination — this is a conflict.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `paramMap.put("check_ntfmlprm_result", CHECK_RESULT_NG)` // Set no-net premium check error to NG (1) |

**Block 1.2** — [RETURN] `(exit from paramMap != null branch)` (L2183)

> After completing all validation checks (or skipping them entirely), return the parameter with updated check result flags.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return param;` // Return param with check result flags set in paramMap |

**Block 2** — [FINALLY] `(session handle cleanup)` (L2186)

> Always clean up the ThreadLocal session handle to prevent memory leaks, even if exceptions were thrown.

| # | Type | Code |
|---|------|------|
| 1 | IF | `keepSesHandle.get() != null` // Check if session handle was set |
| 2 | EXEC | `keepSesHandle.remove()` // Clean up ThreadLocal to prevent memory leak |
| 3 | RETURN | (implicit — control returns to caller) |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `svc_kei_no_bf` | Field | Pre-move service contract number — the service contract number before the address change |
| `svc_kei_no_af` | Field | Post-move service contract number — the service contract number after the address change (転居先) |
| `adchg_adchg_no` | Field | Address change detail number — unique identifier for a specific address change record |
| `sysid` | Field | System identifier — identifies the originating system or branch |
| `net_svc_kei_no_bf` | Field | Pre-move FTTH Net service contract number — identifies the Internet service contract before relocation |
| `net_svc_kei_no_af` | Field | Post-move FTTH Net service contract number — identifies the Internet service contract after relocation |
| `OP_SVC_CD` | Field | Option Service Code — classifies the type of optional service (e.g., Internet Security, No-Net Family Premium) |
| `WRIB_SVC_CD` | Field | Discount Service Code — classifies the type of discounted service package (e.g., Security Pack, Premium Pack) |
| `WRIB_SVC_KEI_STAT` | Field | Discount Service Contract Status — indicates whether the contract is active, terminated, or cancelled |
| `OP_SVC_KEI_STAT` | Field | Option Service Contract Status — indicates whether the contract is active, terminated, or cancelled |
| `CHAF_SKBT_NO` | Field | Post-change Service Contract Number — the service contract number after the address change is applied |
| `ADCHG_DTL_SBT_CD` | Field | Address Change Detail Sub-type Code — classifies the type of address change detail |
| `MK_FLG` | Field | Enabled Flag — indicates whether a record is active/valid (true) or invalid (false) |
| FTTH | Business term | Fiber To The Home — fiber-optic broadband internet service |
| Security Pack | Business term | Discounted security software/service package — a paid add-on offering antivirus and internet safety tools |
| Premium Pack | Business term | SmartLink Premium discount package — a premium discount service bundle with enhanced features |
| Internet Security (インターネットセキュリティー) | Business term | Optional internet security service (OP_SVC_CD="B131") — subscription-based network protection service |
| No-Net Family Premium (ノーネットファミリープレミアム) | Business term | Optional no-net family premium service (OP_SVC_CD="B132") — bundled family service discount |
| CD00055_DSLZM | Constant | Contract Terminated (解約済) — status code "910" indicating a contract has been terminated |
| CD00055_CSLZM | Constant | Contract Cancelled (キャンセル済) — status code "920" indicating a contract has been cancelled |
| Address Change (住所変更) | Business term | The business process of changing a customer's registered address, which may trigger transfer of existing service contracts |
| Portability Check (引き継ぎチェック) | Business term | The validation that determines whether existing optional/discounted services can be transferred to a new address without conflict |
| SC (Service Component) | Technical term | Service Component — a middle-tier business logic layer (e.g., EKK2101B001, EKK0351A010) that handles data access and business rules |
| KK_T_ADCHG_DTL | Entity | Address Change Detail table — stores detail records for address change operations |
| KK_T_OP_SVC_KEI_AGREE | Entity | Option Service Contract Agreement table — stores agreements for optional services |
| KK_T_WRIB_SVC_KEI_AGREE | Entity | Discount Service Contract Agreement table — stores agreements for discount service packages |
| KK_T_WRIB_SVC_KEI | Entity | Discount Service Contract table — stores discount service contract records |
| KK_T_OP_SVC_KEI | Entity | Option Service Contract table — stores option service contract records |
| CC (Common Component) | Technical term | A shared business component class providing reusable validation and processing logic across multiple screens |
| `check_security_result` | Field | Check result flag for security pack portability: "0"=OK, "1"=conflict, "2"=critical conflict |
| `check_premium_result` | Field | Check result flag for premium pack portability: "0"=OK, "1"=conflict, "2"=critical conflict |
| `check_inetsgwl_result` | Field | Check result flag for internet security portability: "0"=OK, "1"=conflict |
| `check_ntfmlprm_result` | Field | Check result flag for no-net family premium portability: "0"=OK, "1"=conflict |
