# Business Logic — JBSbatKKAdChgSodUpd.setHikOpSvcKeiList() [80 LOC]

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

## 1. Role

### JBSbatKKAdChgSodUpd.setHikOpSvcKeiList()

This method is responsible for adding an option service contract line item (`opSvcKeiNo`) to the option service list during a telecom service contract change-transfer (引継ぎ — tsunagigi) batch process. The change-transfer process migrates active service contracts from a departing customer (e.g., due to address change or cancellation) to a new customer, and this method ensures that the relevant option services — such as McAfee security, Internet Security, Notan Premium mail, and Remote Support Plus — are correctly carried over.

The method implements a **routing/dispatch design pattern** based on the option service code (`opSvcCd`) retrieved via `getOpSvcCd()`. Security-focused option services (McAfee Multi Access `"B130"`, Internet Security FOR EO `"B131"`, and Notan Premium FOR EO `"B132"`) are added to the security operations list (`opSvcKeiSecurityOpList`) so that the security pack operation CC (CC: common component) can register them separately. Remote Support Plus (`"B021"`) is explicitly excluded from transfer (not inherited).

The method has a guard clause: it only processes option services when the change-transfer is a "release-and-new-registration" scenario (verified by `isRlsAdd()`), meaning the old service number differs from the new one. It also implements **duplicate prevention** by scanning existing lists before adding entries, and for mail services specifically (service code `"B001"`), it adds the new service key number to the email notification list.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["setHikOpSvcKeiList begin"])
    CHECK_IS_RLS["isRlsAdd(adchgNo, inNewSvcKeiNo)"]

    START --> CHECK_IS_RLS
    CHECK_IS_RLS -->|"false"| END_RETURN(["return — not a release-new-reg scenario"])

    CHECK_IS_RLS -->|"true"| CHECK_DUPLICATE1["for each opSvcKei in opSvcKeiList:
  op_svc_kei_no == opSvcKeiNo?"]
    CHECK_DUPLICATE1 -->|"yes, duplicate found"| END_RETURN
    CHECK_DUPLICATE1 -->|"no"| GET_OP_SVC_CD["workOpSvcCd = getOpSvcCd(opSvcKeiNo)"]
    GET_OP_SVC_CD --> CHECK_SECURITY["workOpSvcCd == B130 or B131 or B132?
(OP_SVC_CD_MCAFEE_MULTI_ACCSS ||
 OP_SVC_CD_INETSGWL ||
 OP_SVC_CD_NTFMLPRM)"]

    CHECK_SECURITY -->|"true — Security services"| ADD_SECURITY_MAP["opSvcKeiMap = new HashMap()"]
    ADD_SECURITY_MAP --> PUT_KEY["opSvcKeiMap.put(op_svc_kei_no, opSvcKeiNo)"]
    PUT_KEY --> PUT_CD["opSvcKeiMap.put(op_svc_cd, workOpSvcCd)"]
    PUT_CD --> ADD_TO_SEC_LIST["opSvcKeiSecurityOpList.add(opSvcKeiMap)"]
    ADD_TO_SEC_LIST --> END_RETURN

    CHECK_SECURITY -->|"false"| CHECK_RMT["workOpSvcCd == B021?
(OP_SVC_CD_RMTSPRT_PLUS)"]
    CHECK_RMT -->|"true — Remote Support Plus"| END_RETURN
    CHECK_RMT -->|"false"| CREATE_MAP["opSvcKeiMap = new HashMap()"]
    CREATE_MAP --> PUT_SVC["opSvcKeiMap.put(op_svc_kei_no, opSvcKeiNo)"]
    PUT_SVC --> ADD_TO_LIST["opSvcKeiList.add(opSvcKeiMap)"]
    ADD_TO_LIST --> CHECK_MAIL["getOpSvcCd(opSvcKeiNo) == B001?
(Mail service)"]
    CHECK_MAIL -->|"no"| END_RETURN
    CHECK_MAIL -->|"yes B001 — Mail"| CHECK_DUP_EMAIL["for each emailOpSvcKeiMap in emailOpSvcKeiNoList:
  svc_kei_no == inNewSvcKeiNo?"]
    CHECK_DUP_EMAIL -->|"yes, duplicate"| END_RETURN
    CHECK_DUP_EMAIL -->|"no"| END_RETURN
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `opSvcKeiList` | `ArrayList<HashMap<String, Object>>` | The primary option service contract line item list being built during the change-transfer. Each map contains option service metadata (keyed by `"op_svc_kei_no"`). Entries added here represent standard option services carried over to the new customer. |
| 2 | `opSvcKeiNo` | `String` | The option service contract line number — the identifier of the specific option service to be transferred. This is the key lookup value used to deduplicate against existing entries and to resolve the service code via `getOpSvcCd()`. |
| 3 | `emailOpSvcKeiNoList` | `ArrayList<HashMap<String, Object>>` | The email notification option service list. When the option service is a Mail-type service (`"B001"`), the new service key number (`inNewSvcKeiNo`) is added here for email notification purposes. Each map contains keys like `"svc_kei_no"`. |
| 4 | `inNewSvcKeiNo` | `String` | The new service key number after the change-transfer. Used in the `isRlsAdd()` check to confirm this is a release-and-new-registration scenario (old service number != new service number), and for deduplication in the email list. |
| 5 | `adchgNo` | `String` | The address change number (住所変更番号) — the unique identifier for the change-transfer record. Used by `isRlsAdd()` to look up address change details from the `KK_T_ADCHG_DTL` table to determine if this is a release-new-registration scenario. |
| 6 | `opSvcKeiSecurityOpList` | `ArrayList<HashMap<String, Object>>` | The security option service list. Security-focused services (McAfee, Internet Security, Notan Premium) are added here with both `op_svc_kei_no` and `op_svc_cd` fields so that the security pack operation common component (CC) can handle their separate registration flow. |

**Instance fields / external state read:**
- `db_KK_T_ADCHG_DTL2` — Database iterator used internally via `isRlsAdd()` to query address change detail records.

## 4. CRUD Operations / Called Services

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

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `JBSbatKKAdChgSodUpd.isRlsAdd` | — | `KK_T_ADCHG_DTL` | Reads address change detail records via `executeKK_T_ADCHG_DTL_KK_SELECT_003` to determine if the change-transfer is a release-and-new-registration scenario (oldSvcKeiNo != newSvcKeiNo). |
| R | `JBSbatKKAdChgSodUpd.getOpSvcCd` | — | — | Retrieves the option service code (`op_svc_cd`) for a given option service key number. Returns strings like `"B130"`, `"B001"`, `"B021"`. Used to route security services vs. mail services. |

**How to classify:**
- Both called methods are **Read (R)** operations: `isRlsAdd` queries the database for address change details, and `getOpSvcCd` looks up the service code.

## 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: `isRlsAdd` [R], `getOpSvcCd` [R], `getOpSvcCd` [R]

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Batch: JBSbatKKAdChgSodUpd | `JBSbatKKAdChgSodUpd.execute()` → `setHikOpSvcKeiList(opSvcKeiList, opSvcKeiNo, emailOpSvcKeiNoList, inNewSvcKeiNo, adchgNo, opSvcKeiSecurityOpList)` | `isRlsAdd [R] KK_T_ADCHG_DTL`, `getOpSvcCd [R]`, `getOpSvcCd [R]` |

## 6. Per-Branch Detail Blocks

### Block 1 — IF `(isRlsAdd(adchgNo, inNewSvcKeiNo))` (L2431)

> Only eligible for release-new-registration (解約新規のみ引継ぎ対象 — release-new-reg only is transfer target). If the address change detail shows the old and new service numbers differ, this block executes.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `isRlsAdd(adchgNo, inNewSvcKeiNo)` // Check if this is a release-new-registration [R KK_T_ADCHG_DTL] |
| 2 | COND | Branch: `false` → jump to Block 3 (final return) |
| 3 | COND | Branch: `true` → enter Block 2 |

### Block 1.1 — nested loop `(for opSvcKei in opSvcKeiList)` (L2437)

> Check if the option service number is already set (設定済みのオプションなら設定しない — skip if already set). Scans the existing option service list to prevent duplicates.

| # | Type | Code |
|---|------|------|
| 1 | LOOP | `for (HashMap<String, Object> opSvcKei : opSvcKeiList)` |
| 2 | EXEC | `opSvcKei.get("op_svc_kei_no")` // Retrieve existing option service key number |
| 3 | COND | `opSvcKei.get("op_svc_kei_no").equals(opSvcKeiNo)` — is this already in the list? |
| 4 | RETURN | `return;` // Already present, skip — duplicate prevention |
| 5 | LOOP_END | End of for-loop — if no duplicate found, proceed to service code routing |

### Block 1.2 — security service check `(JKKStrConst.OP_SVC_CD_MCAFEE_MULTI_ACCSS || OP_SVC_CD_INETSGWL || OP_SVC_CD_NTFMLPRM)` (L2445–L2453)

> If the option service is a security-related service, it is excluded from the standard list and added to the security operations list instead (インターネットセキュリティ・ノートンプレミアム・マカフィーマルチアクセス・リのオプションなので、セキュリティパック操作CCで登録を行うため — Internet Security, Notan Premium, McAfee Multi Access are registered via the security pack CC).

**Constants resolved:**
- `JKKStrConst.OP_SVC_CD_MCAFEE_MULTI_ACCSS = "B130"` (McAfee Multi Access)
- `JKKStrConst.OP_SVC_CD_INETSGWL = "B131"` (Internet Security FOR EO)
- `JKKStrConst.OP_SVC_CD_NTFMLPRM = "B132"` (Notan Premium FOR EO)

| # | Type | Code |
|---|------|------|
| 1 | CALL | `workOpSvcCd = getOpSvcCd(opSvcKeiNo)` [R] // Resolve the service code |
| 2 | COND | `OP_SVC_CD_MCAFEE_MULTI_ACCSS("B130") || OP_SVC_CD_INETSGWL("B131") || OP_SVC_CD_NTFMLPRM("B132")` |
| 3 | COND | `false` → skip to Block 1.3 |
| 4 | COND | `true` → security services, execute Block 1.2.1 |

### Block 1.2.1 — add to security list `(security services match)` (L2448–L2453)

| # | Type | Code |
|---|------|------|
| 1 | SET | `opSvcKeiMap = new HashMap<String, Object>()` |
| 2 | EXEC | `opSvcKeiMap.put("op_svc_kei_no", opSvcKeiNo)` |
| 3 | EXEC | `opSvcKeiMap.put("op_svc_cd", workOpSvcCd)` |
| 4 | EXEC | `opSvcKeiSecurityOpList.add(opSvcKeiMap)` // Added to security operations list |
| 5 | RETURN | `return;` // Security services handled separately |

### Block 1.3 — Remote Support Plus check `(OP_SVC_CD_RMTSPRT_PLUS)` (L2455–L2457)

> Remote Support Plus is excluded from transfer (リモートサポートは引継対象外 — Remote Support is not a transfer target).

**Constants resolved:**
- `JKKStrConst.OP_SVC_CD_RMTSPRT_PLUS = "B021"` (Remote Support Plus)

| # | Type | Code |
|---|------|------|
| 1 | COND | `OP_SVC_CD_RMTSPRT_PLUS("B021")` |
| 2 | COND | `true` → remote support plus, skip transfer |
| 3 | RETURN | `return;` // Do not inherit Remote Support Plus |
| 4 | COND | `false` → proceed to standard service handling |

### Block 1.4 — create standard option map `(non-security, non-RSPlus)` (L2459–L2463)

> Create the option service contract line number list (オプションサービス契約番号のリストを作成 — create option service contract number list) and add to the primary list.

| # | Type | Code |
|---|------|------|
| 1 | SET | `opSvcKeiMap = new HashMap<String, Object>()` |
| 2 | EXEC | `opSvcKeiMap.put("op_svc_kei_no", opSvcKeiNo)` |
| 3 | EXEC | `opSvcKeiList.add(opSvcKeiMap)` // Added to primary option service list |

### Block 1.4.1 — Mail service check `(!"B001".equals(getOpSvcCd(opSvcKeiNo)))` (L2465–L2468)

> Only the following processing for change-transfer that is not Mail (メール以外の引継ぎでは以下の処理は不要 — mail transfer does not need the following processing). If the service code is NOT `"B001"`, skip the email list processing.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `getOpSvcCd(opSvcKeiNo)` [R] // Get service code again (not cached from earlier) |
| 2 | COND | `"B001" != getOpSvcCd(opSvcKeiNo)` — not a Mail-type service |
| 3 | COND | `true` → not mail, skip email list processing |
| 4 | RETURN | `return;` |
| 5 | COND | `false` — this IS a Mail-type service (`"B001"`) → proceed to Block 1.4.2 |

### Block 1.4.2 — duplicate check for email list `(for emailOpSvcKeiMap in emailOpSvcKeiNoList)` (L2470–L2476)

> Check if the new service key number is already in the email notification list (設定済みのオプションなら設定しない — skip if already set).

| # | Type | Code |
|---|------|------|
| 1 | LOOP | `for (HashMap<String, Object> emailOpSvcKeiMap : emailOpSvcKeiNoList)` |
| 2 | EXEC | `emailOpSvcKeiMap.get("svc_kei_no")` // Retrieve existing service key number from email list |
| 3 | COND | `emailOpSvcKeiMap.get("svc_kei_no").equals(inNewSvcKeiNo)` — is this already in the email list? |
| 4 | RETURN | `return;` // Already present, skip |
| 5 | LOOP_END | End of for-loop — no duplicate found, processing is complete |

### Block 3 — final return `(outside if(isRlsAdd))` (L2495)

> If the change-transfer is not a release-new-registration scenario, simply return without processing.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return;` // Not a release-new-registration scenario — nothing to do |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `opSvcKeiNo` | Field | Option service contract line number — the identifier for a specific option service contract line item (オプションサービス契約番号) |
| `op_svc_kei_no` | Field | Database/map key for the option service contract line number |
| `op_svc_cd` | Field | Option service code — the classification code for the type of option service (e.g., `"B130"`, `"B001"`) |
| `inNewSvcKeiNo` | Field | New service key number — the service key number after the change-transfer |
| `svc_kei_no` | Field | Service key number — the primary identifier for a service contract line item |
| `adchgNo` | Field | Address change number (住所変更番号) — the unique identifier for a change-transfer record |
| `opSvcKeiList` | Field | Option service contract line item list — the primary list of option services being built for transfer |
| `emailOpSvcKeiNoList` | Field | Email notification option service list — list of option services requiring email notification after transfer |
| `opSvcKeiSecurityOpList` | Field | Security option service operations list — specialized list for security pack services (McAfee, Internet Security, Notan Premium) that are registered via a separate common component |
| `isRlsAdd` | Method | Release-and-New-Registration check (解約新規) — determines if the change-transfer involves a service number change (old != new), indicating a cancellation followed by a new registration |
| `getOpSvcCd` | Method | Get Option Service Code — resolves the service code from an option service key number |
| `KK_T_ADCHG_DTL` | Table | Address change detail table (住所変更明細テーブル) — stores address change records including old and new service key numbers |
| `KK_T_ADCHG_DTL2` | Table | Iterator/database handle for the address change detail table |
| `B130` | Constant | McAfee Multi Access (マカフィーマルチアクセス) — antivirus security service |
| `B131` | Constant | Internet Security FOR EO (インターネットセキュリティ FOR EO) — internet security suite |
| `B132` | Constant | Notan Premium FOR EO (ノートンプレミアム FOR EO) — premium security service |
| `B021` | Constant | Remote Support Plus (リモートサポートプラス) — remote technical support service, excluded from transfer |
| `B001` | Constant | Mail service code — identifies an email-type option service requiring special email-list handling |
| 引継ぎ (tsunagigi) | Business term | Service contract change-transfer — the process of transferring a customer's active service contracts to a new customer, typically due to address change or account transfer |
| 解約新規 (kaiyaku shinkei) | Business term | Release-and-New-Registration — a change-transfer scenario where the old contract is cancelled and a new one is created (old service number != new service number) |
| CC | Acronym | Common Component — shared business logic component in this architecture (also called CBS/SC in other contexts) |
| SOD | Acronym | Service Order Data — the telecom order fulfillment entity |
| McAfee | Business term | McAfee Multi Access — multi-device antivirus/security subscription service |
| Notan | Business term | Notan (Norton) Premium — Symantec/Norton premium security subscription service |
| Remote Support Plus | Business term | Fujitsu's remote technical support service, excluded from automatic transfer during change-transfer |
