# Business Logic — JFUTelOptSvcMskmCmpCC.setTelSelOptPackMapping() [165 LOC]

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

## 1. Role

### JFUTelOptSvcMskmCmpCC.setTelSelOptPackMapping()

This method handles the mapping and execution of telephone selection option pack (オプションパック — "option pack") subscription and cancellation operations within the eo customer backbone system. It is a shared component-level method called by the screen entry point `JFUSetOptPackMskmCC.setSaveData()` during the final stage of the telephone option service contract registration/cancellation workflow. The method implements a **routing/dispatch design pattern**: when the operation involves a pack replacement (both a subscription and a cancellation in the same `packList`), it first performs a pre-check CC call to obtain the warranty contract status list (`wrib_svc_kei_list`), validates that the service start date is not in the future relative to the operational date, verifies the warranty contract status permits the operation, and enforces a duplicate discount prevention rule. For non-check (registration) mode, it iterates over each pack entry in `packList`, builds a structured `parentMap` with the appropriate business fields depending on whether the transaction division is "01" (register) or "02" (cancel), sets the correct service cancellation reason codes, resolves the update timestamp for subsequent pack items, and delegates each entry to the `OpPackCC` service component for execution. The method also enforces business constraints including: (1) the service start date must not be in the future, (2) duplicate discount applications are prohibited (at most one net-positive pack count), and (3) check-mode calls short-circuit after the pre-check CC to allow the screen to display current data without side effects.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["setTelSelOptPackMapping"])
    outStart["outDebugLog: Start"]
    inMap["HashMap inMap = param.getData(fixedText)"]
    checkPackList{"packList.size() > 0?"}
    buildParentMap1["Build parentMap with func_cd=1, trn_div=00, sysid, svc_kei_no, svc_kei_ucwk_no"]
    setData1["param.setData(OpPackCC, parentMap)"]
    callExe1["execute(handle, param, OpPackCC)"]
    getOutMap["HashMap outMap = param.getData(OpPackCC)"]
    getWribList["ArrayList wribList = outMap.get(wrib_svc_kei_list)"]
    initCnt["cntPackMskm = 0"]
    loopPack{"for each packList item"}
    checkTrn1{"trn_div == 01 (Register)?"}
    incCnt1["cntPackMskm++"]
    checkTrn2{"trn_div == 02 (Cancel)?"}
    decCnt["cntPackMskm--"]
    loopWrib{"for each wribList item"}
    getSvcUseYmd["svcUseStaKiboYmd = wribInfo.get(svc_use_sta_kibo_ymd)"]
    checkOpeDate{"opeDate < svcUseStaKiboYmd?"}
    setError["setErrorField(param, ido_rsv_dtl_cd_err)"]
    throwFuture["throw SCCallException: Service start date in future"]
    checkWribStat{"wrib_svc_kei_stat in WRIB_MUKO?"}
    incCntWrib["cntPackMskm++"]
    checkCnt{"cntPackMskm > 1?"}
    throwDup["throw SCCallException: Duplicate discount error"]
    checkFunc{"func_cd == FUNC_CD_2 (Check)?"}
    loopPack2{"for each packList item"}
    buildParentMap2["Build parentMap from dataMap fields"]
    checkFunc1{"func_cd == FUNC_CD_1?"}
    getDtlNo["set mskm_dtl_no from getBPListValueString"]
    checkTrnReg{"trn_div == 01 (Register)?"}
    setNullSvc["set svc_dlre_cd=null, svc_cancel_rsn_cd=null"]
    setCancelSvc["set svc_dlre_cd=CD00879_01, svc_cancel_rsn_cd=CD01390_06"]
    setFixedValues["set kisan_ymd, use_sta_kibo_ymd, ido_div=CD00576_00031, pack_div, kakin_div=1, pnlty_div=0"]
    checkI0{"i == 0?"}
    setLastDtm1["set kk0081_upd_dtm = lastUpdDtm"]
    checkI1{"i == 1?"}
    setLastDtm2["set kk0081_upd_dtm = OpPackCC.get(upd_dtm)"]
    setData2["param.setData(OpPackCC, parentMap)"]
    callExe2["execute(handle, param, OpPackCC)"]
    outEnd["outDebugLog: End"]

    START --> outStart --> inMap --> checkPackList
    checkPackList -->|Yes| buildParentMap1 --> setData1 --> callExe1 --> getOutMap --> getWribList --> initCnt --> loopPack
    checkPackList -->|No| checkFunc
    loopPack --> checkTrn1
    checkTrn1 -->|Yes| incCnt1 --> checkTrn2
    checkTrn1 -->|No| checkTrn2
    checkTrn2 -->|Yes| decCnt --> loopPack
    checkTrn2 -->|No| loopPack
    loopPack -->|done| loopWrib
    loopWrib --> getSvcUseYmd --> checkOpeDate
    checkOpeDate -->|Yes| setError --> throwFuture --> loopWrib
    checkOpeDate -->|No| checkWribStat
    checkWribStat -->|No| incCntWrib --> loopWrib
    checkWribStat -->|Yes| loopWrib
    loopWrib -->|done| checkCnt
    checkCnt -->|Yes| throwDup
    checkCnt -->|No| checkFunc
    throwFuture --> outEnd
    throwDup --> outEnd
    checkFunc -->|Yes| outEnd
    checkFunc -->|No| loopPack2
    loopPack2 --> buildParentMap2 --> checkFunc1
    checkFunc1 -->|Yes| getDtlNo --> checkTrnReg
    checkFunc1 -->|No| checkTrnReg
    checkTrnReg -->|Yes| setNullSvc --> setFixedValues
    checkTrnReg -->|No| setCancelSvc --> setFixedValues
    setFixedValues --> checkI0
    checkI0 -->|Yes| setLastDtm1 --> setData2
    checkI0 -->|No| checkI1
    checkI1 -->|Yes| setLastDtm2 --> setData2
    checkI1 -->|No| setData2
    setData2 --> callExe2
    callExe2 -->|more items| loopPack2
    loopPack2 -->|done| outEnd
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `handle` | `SessionHandle` | Session handle for the current user session; carries authentication context and database connection used by all service component calls via `execute(handle, param, "OpPackCC")`. |
| 2 | `param` | `IRequestParameterReadWrite` | Request parameter object that holds the in-map (input data from screen), out-map (CC results), and per-template data. Read via `param.getData(fixedText)` to obtain `inMap`; written via `param.setData("OpPackCC", parentMap)` before each CC call; read-back for CC results via `param.getData("OpPackCC")`. |
| 3 | `fixedText` | `String` | Service message key (fixed text identifier) used as the key to retrieve the input data map (`inMap`) from the request parameter. This key corresponds to the screen's service message identifier for mapping data back and forth between the UI and the business logic. |
| 4 | `packList` | `ArrayList` | List of telephone selection option pack entries. Each entry is a `HashMap` containing fields: `trn_div` (transaction division: "01"=register, "02"=cancel), `sysid`, `svc_kei_no`, `svc_kei_ucwk_no`, `pack_div`, and other pack-level attributes. This is the core data structure that drives the operation — each entry triggers one `OpPackCC` execution in non-check mode. For pack replacement scenarios, this list contains both a registration entry (trn_div=01) and a cancellation entry (trn_div=02). |
| 5 | `lastUpdDtm` | `String` | Last update datetime (timestamp) of the most recent modification to the service contract data. Used as `kk0081_upd_dtm` for the first pack item (i==0) to pass the pre-update timestamp to the CC. For the second pack item (i==1), it is replaced by the `upd_dtm` returned from the first `OpPackCC` call, ensuring proper optimistic concurrency control across sequential pack operations. |

**Fields read from instance/external state:**

| Field | Type | Business Description |
|-------|------|---------------------|
| `IN_SYSID` | `String` (constant: `"in_sysid"`) | Map key for retrieving the SYSID (system identifier) from the input data map. |
| `IN_SVC_KEI_NO` | `String` (constant: `"in_svc_kei_no"`) | Map key for the service contract number (service detail line number). |
| `IN_SVC_KEI_UCWK_NO` | `String` (constant: `"in_svc_kei_ucwk_no"`) | Map key for the service contract internal detail number. |
| `IN_FUNC_CD` | `String` (constant: `"func_cd"`) | Map key for the function code distinguishing check mode vs. registration mode. |
| `TEMP_ID_DTL_EKK0011D020` | `String` (constant: `EKK0011D020CBSMsg.EKK0011D020CBSMSG1LIST`) | Template list key for retrieving the service detail number (mskm_dtl_no) when func_cd is FUNC_CD_1. |
| `WRIB_SVC_KEI_STAT_MUKO` | `List<String>` (constant: `[CD00055_910, CD00055_920]`) | List of warranty contract statuses considered "non-applicable" (not eligible for the current discount/service). `CD00055_910` = "Contract cancelled" and `CD00055_920` = "Contract cancelled (with penalty)". If the warranty service contract status is NOT in this list, the pack count is incremented (indicating a net positive subscription). |

## 4. CRUD Operations / Called Services

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

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| C | `execute(handle, param, "OpPackCC")` | OpPackCC (telephone option pack operation CC) | Service contract / option pack entities | Registers or cancels a telephone selection option pack. Called once in pre-check mode (with func_cd=1, trn_div=00) to obtain the warranty contract list, and then once per entry in packList for actual registration/cancellation. |

### Supporting service/component calls (invoked during the call chain, not directly in this method):

The method delegates all database operations through the `OpPackCC` execute call. The `OpPackCC` service component is responsible for:
- **Create (C)**: Registering new option pack subscriptions (for `trn_div="01"` entries).
- **Delete (D)**: Cancelling existing option pack subscriptions (for `trn_div="02"` entries).

No direct CRUD operations are performed in this method — all data persistence is delegated to `execute(handle, param, "OpPackCC")` via the service component request invoker pattern.

## 5. Dependency Trace

### Direct callers:

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Screen:KKSV0004 (implied) | `JFUSetOptPackMskmCC.setSaveData` -> `setTelSelOptPackMapping` | `execute OpPackCC [C/D] option pack entities` |
| 2 | Screen:KKSV0004 (implied) | `JFUTelOptSvcMskmCmpCC.setSaveData` -> `setTelSelOptPackMapping` | `execute OpPackCC [C/D] option pack entities` |

**Caller details:**
- `JFUSetOptPackMskmCC.setSaveData()` (line 580): This is the primary screen handler for the telephone option pack registration/cancellation screen (KKSV0004). After preparing all other service contract data (option service contract registration, cancellation, sub-option registration, sub-option cancellation, SOD mapping), it calls `setTelSelOptPackMapping(handle, param, fixedText, optPackList, lastUpdDtm)` as the final processing step before progress registration.
- `JFUTelOptSvcMskmCmpCC.setSaveData()` (lines 1016, 1047): This is a variant entry point within the same component class that also calls this method during the save data workflow.

## 6. Per-Branch Detail Blocks

### Block 1 — [Start/Debug Log] (L2992)

Initial debug logging.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `outDebugLog("----- setTelSelOptPackMapping Start -----")` // Debug log start marker |

### Block 2 — [Variable Initialization] (L3003)

Retrieve the input data map from the request parameter using the fixedText service message key.

| # | Type | Code |
|---|------|------|
| 1 | SET | `HashMap inMap = (HashMap)param.getData(fixedText)` // Retrieve input data map from request parameter |

### Block 3 — [IF] `packList.size() > 0` (L3006) — Pre-check: Pack replacement validation

When there are pack entries present, this block performs a pre-check CC call to validate the current warranty contract state before processing registration/cancellation. This implements the pack replacement (付け替え — "replacement") scenario where both a subscription and a cancellation must be validated together.

#### Block 3.1 — [Variable Initialization] (L3009-L3017)

Build a parent map with fixed values for the pre-check CC call. The function code is set to FUNC_CD_1 (registration mode), and the transaction division is set to "00" (neutral, not register/cancel) since this is a pre-check.

| # | Type | Code |
|---|------|------|
| 1 | SET | `HashMap<String, Object> parentMap = new HashMap<>()` // Initialize parent map for pre-check |
| 2 | SET | `parentMap.put("func_cd", JPCModelConstant.FUNC_CD_1)` // [-> "1"]: Function code — registration/check mode |
| 3 | SET | `parentMap.put("trn_div", "00")` // [-> "00"]: Transaction division — neutral (pre-check, not register/cancel) |
| 4 | SET | `parentMap.put("sysid", inMap.get(IN_SYSID))` // Retrieve SYSID from input map [-> key: "in_sysid"] |
| 5 | SET | `parentMap.put("svc_kei_no", inMap.get(IN_SVC_KEI_NO))` // Retrieve service contract number [-> key: "in_svc_kei_no"] |
| 6 | SET | `parentMap.put("svc_kei_ucwk_no", inMap.get(IN_SVC_KEI_UCWK_NO))` // Retrieve service contract internal detail number [-> key: "in_svc_kei_ucwk_no"] |

#### Block 3.2 — [Method Call: Pre-check CC] (L3019-L3024)

Store the pre-check map, execute the OpPackCC service component, and retrieve the warranty contract status list.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `param.setData("OpPackCC", parentMap)` // Set pre-check data into request parameter |
| 2 | CALL | `execute(handle, param, "OpPackCC")` // Invoke telephone option pack CC with pre-check params |
| 3 | SET | `HashMap outMap = (HashMap)param.getData("OpPackCC")` // Retrieve CC response |
| 4 | SET | `ArrayList<HashMap<String, String>> wribList = (ArrayList<HashMap<String, String>>)outMap.get("wrib_svc_kei_list")` // Extract warranty service contract list from CC result |

#### Block 3.3 — [Loop: Count pack registrations/cancellations] (L3026-L3037)

Iterate over all pack entries to compute `cntPackMskm`, a counter that tracks the net number of pack subscriptions. Each registration increments the counter, and each cancellation decrements it.

| # | Type | Code |
|---|------|------|
| 1 | SET | `int cntPackMskm = 0` // Initialize net pack count to zero |
| 2 | FOR | `for (int i = 0; i < packList.size(); i++)` // Iterate over each pack entry |
| 3 | SET | `HashMap dataMap = (HashMap)packList.get(i)` // Get current pack entry |

##### Block 3.3.1 — [IF] `trn_div == "01" (Register)` (L3030)

| # | Type | Code |
|---|------|------|
| 1 | SET | `cntPackMskm++` // Increment counter: new pack subscription |

##### Block 3.3.2 — [IF] `trn_div == "02" (Cancel)` (L3034)

| # | Type | Code |
|---|------|------|
| 1 | SET | `cntPackMskm--` // Decrement counter: pack cancellation |

#### Block 3.4 — [Loop: Validate warranty contract results] (L3041-L3067)

Iterate over the warranty service contract list returned by the pre-check CC to validate business rules.

| # | Type | Code |
|---|------|------|
| 1 | FOR | `for (int j = 0; wribList != null && wribList.size() > j; j++)` // Iterate over warranty service contracts |
| 2 | SET | `HashMap<String, String> wribInfo = wribList.get(j)` // Get warranty contract info |
| 3 | SET | `String svcUseStaKiboYmd = (String)wribInfo.get("svc_use_sta_kibo_ymd")` // [-> "svc_use_sta_kibo_ymd"]: Service start date — the date the customer requests the service to begin |

##### Block 3.4.1 — [IF] Service start date is in the future (L3047-L3049)

Validate that the service start date is not after the current operational date.

| # | Type | Code |
|---|------|------|
| 1 | IF | `!JFUBPCommon.isNull(svcUseStaKiboYmd) && Integer.parseInt(JFUBPCommon.getOpeDate(null)) < Integer.parseInt(svcUseStaKiboYmd)` [-> `opeDate < svcUseStaKiboYmd`: Operational date is less than the requested service start date, meaning the start date is in the future] |

###### Block 3.4.1.1 — [Error handling for future start date] (L3048-L3049)

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `setErrorField(param, "ido_rsv_dtl_cd_err")` // Set error flag for service start date reservation |
| 2 | THROW | `throw new SCCallException("オプションパックのサービス開始日が未来日", String.valueOf(0), JPCModelConstant.RELATION_ERR)` // [-> "オプションパックのサービス開始日が未来日" = "Option pack service start date is a future date"; [-> RELATION_ERR]: Throw relation error exception |

##### Block 3.4.2 — [IF] Warranty contract status is not in excluded list (L3052-L3054)

Check if the warranty service contract status indicates the contract is still active (not cancelled/voided). If NOT in `WRIB_SVC_KEI_STAT_MUKO` (excluded statuses: cancelled, cancelled with penalty), the pack count is incremented — indicating an active warranty contract contributes to the net pack count.

| # | Type | Code |
|---|------|------|
| 1 | IF | `!WRIB_SVC_KEI_STAT_MUKO.contains(wribInfo.get("wrib_svc_kei_stat"))` [-> `WRIB_SVC_KEI_STAT_MUKO = ["CD00055_910", "CD00055_920"]` where CD00055_910="Contract cancelled", CD00055_920="Contract cancelled (with penalty)"] |

###### Block 3.4.2.1 — [Increment counter for active warranty] (L3053)

| # | Type | Code |
|---|------|------|
| 1 | SET | `cntPackMskm++` // Active warranty contract contributes to net pack count |

#### Block 3.5 — [IF] Duplicate discount prevention (L3058-L3061)

After counting all registrations and cancellations, verify that no more than one net subscription remains. This prevents applying multiple discount packs simultaneously.

| # | Type | Code |
|---|------|------|
| 1 | IF | `cntPackMskm > 1` // More than one net pack subscription detected |

###### Block 3.5.1 — [Throw duplicate error] (L3060)

| # | Type | Code |
|---|------|------|
| 1 | THROW | `throw new SCCallException("割引重複申請エラー", String.valueOf(0), JPCModelConstant.RELATION_ERR)` // [-> "割引重複申請エラー" = "Discount duplicate application error"; [-> RELATION_ERR]: Throw relation error |

### Block 4 — [IF] `func_cd == FUNC_CD_2` (Check Mode) (L3065-L3067)

When the function code indicates a check-only operation (check mode), return immediately after the pre-check CC. This allows the screen to display current data without creating any side effects (registration/cancellation).

| # | Type | Code |
|---|------|------|
| 1 | IF | `JPCModelConstant.FUNC_CD_2.equals(inMap.get(IN_FUNC_CD))` [-> FUNC_CD_2: "2" = check mode] |

#### Block 4.1 — [RETURN] (L3066)

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return;` // Check mode: return early, no registration/cancellation performed |

### Block 5 — [Loop: Process each pack entry] (L3070-L3152)

Main processing loop: for each pack entry, build the complete parameter map and execute the OpPackCC service component for registration or cancellation.

| # | Type | Code |
|---|------|------|
| 1 | FOR | `for (int i = 0; i < packList.size(); i++)` // Iterate over each pack entry |
| 2 | SET | `HashMap dataMap = (HashMap)packList.get(i)` // Get current pack entry |
| 3 | SET | `HashMap<String, Object> parentMap = new HashMap<>()` // Initialize parent map for this entry |

#### Block 5.1 — [Variable Initialization: Core fields] (L3076-L3087)

Build the parent map with common fields derived from the input data and the current pack entry's attributes.

| # | Type | Code |
|---|------|------|
| 1 | SET | `parentMap.put("func_cd", inMap.get(IN_FUNC_CD))` // Use actual function code from input [-> key: "func_cd"] |
| 2 | SET | `parentMap.put("trn_div", (String)dataMap.get("trn_div"))` // Transaction division from pack entry [-> "01"=register, "02"=cancel] |
| 3 | SET | `parentMap.put("sysid", (String)dataMap.get("sysid"))` // SYSID from pack entry |
| 4 | SET | `parentMap.put("svc_kei_no", (String)dataMap.get("svc_kei_no"))` // Service contract number from pack entry |
| 5 | SET | `parentMap.put("svc_kei_ucwk_no", (String)dataMap.get("svc_kei_ucwk_no"))` // Service contract internal detail number from pack entry |

#### Block 5.2 — [IF] `func_cd == FUNC_CD_1` (Registration) — Set service detail number (L3088-L3090)

When in registration mode (FUNC_CD_1), generate a new service detail number (mskm_dtl_no) from the business key generator.

| # | Type | Code |
|---|------|------|
| 1 | IF | `JPCModelConstant.FUNC_CD_1.equals(inMap.get(IN_FUNC_CD))` [-> FUNC_CD_1: "1" = registration/check mode] |

###### Block 5.2.1 — [Set service detail number] (L3089-L3090)

| # | Type | Code |
|---|------|------|
| 1 | SET | `parentMap.put("mskm_dtl_no", JFUBPCommon.getBPListValueString(param, fixedText, TEMP_ID_DTL_EKK0011D020, 0, EKK0011D020CBSMsg1List.MSKM_DTL_NO))` // [-> TEMP_ID_DTL_EKK0011D020 = EKK0011D020CBSMsg.EKK0011D020CBSMSG1LIST]: Generate service detail number from template list |

#### Block 5.3 — [IF/ELSE] `trn_div == "01" (Register) / else (Cancel)` (L3091-L3102)

Set service cancellation reason codes based on the transaction division. For registration, set both codes to null (not applicable). For cancellation, set the standard cancellation reason codes.

| # | Type | Code |
|---|------|------|
| 1 | IF | `\"01\".equals((String)dataMap.get(\"trn_div\"))` [-> "01" = Register] |

##### Block 5.3.1 — [Register: null reason codes] (L3094-L3096)

Registration does not require cancellation reasons.

| # | Type | Code |
|---|------|------|
| 1 | SET | `parentMap.put("svc_dlre_cd", null)` // [-> "svc_dlre_cd"]: Service contract reason code — set to null for registration |
| 2 | SET | `parentMap.put("svc_cancel_rsn_cd", null)` // [-> "svc_cancel_rsn_cd"]: Service cancellation reason code — set to null for registration |

##### Block 5.3.2 — [Cancel: set standard cancellation reason codes] (L3099-L3102)

For cancellation, set the standard service reason and cancellation reason codes.

| # | Type | Code |
|---|------|------|
| 1 | SET | `parentMap.put("svc_dlre_cd", JFUStrConst.CD00879_01)` // [-> "01"]: Standard cancellation — normal service cancellation |
| 2 | SET | `parentMap.put("svc_cancel_rsn_cd", JFUStrConst.CD01390_06)` // [-> "06"]: Cancellation by contract termination — standard cancellation reason |

#### Block 5.4 — [Set fixed operation values] (L3103-L3114)

Set operation-wide fields that are common to all pack entries regardless of transaction type.

| # | Type | Code |
|---|------|------|
| 1 | SET | `parentMap.put("kisan_ymd", JFUBPCommon.getOpeDate(null))` // [-> "kisan_ymd"]: Billing date — set to current operational date |
| 2 | SET | `parentMap.put("use_sta_kibo_ymd", JFUBPCommon.getOpeDate(null))` // [-> "use_sta_kibo_ymd"]: Service start request date — set to current operational date |
| 3 | SET | `parentMap.put("ido_div", JFUStrConst.CD00576_00031)` // [-> "00031"]: Movement division — option settings |
| 4 | SET | `parentMap.put("pack_div", (String)dataMap.get("pack_div"))` // [-> "pack_div"]: Pack division from pack entry |
| 5 | SET | `parentMap.put("kakin_div", "1")` // [-> "1"]: Billing division — invoicing |
| 6 | SET | `parentMap.put("pnlty_div", "0")` // [-> "0"]: Penalty division — no penalty |
| 7 | SET | `parentMap.put("wrib_svc_kei_no", null)` // [-> "wrib_svc_kei_no"]: Discount service contract number — set to null |

#### Block 5.5 — [IF/ELSE] `i == 0` / `i == 1` — Set update timestamp for concurrency control (L3115-L3127)

Handle the update timestamp differently based on the pack entry index. For the first entry (i==0), use the original last update timestamp. For the second entry (i==1), use the update timestamp returned by the first OpPackCC call to ensure proper optimistic concurrency control across sequential pack operations.

| # | Type | Code |
|---|------|------|
| 1 | IF | `i == 0` // First pack entry |

##### Block 5.5.1 — [First entry: use original timestamp] (L3118-L3119)

| # | Type | Code |
|---|------|------|
| 1 | SET | `parentMap.put("kk0081_upd_dtm", lastUpdDtm)` // [-> "kk0081_upd_dtm"]: Update timestamp — use the original last update datetime passed into this method |

##### Block 5.5.2 — [ELSE IF] `i == 1` — [Second entry: use CC-returned timestamp] (L3121-L3123)

| # | Type | Code |
|---|------|------|
| 1 | SET | `parentMap.put("kk0081_upd_dtm", ((HashMap)param.getData("OpPackCC")).get("upd_dtm"))` // [-> "upd_dtm"]: Update timestamp — use the update datetime returned by the first OpPackCC call |

#### Block 5.6 — [Execute CC for this entry] (L3125-L3130)

Store the parent map and invoke the OpPackCC service component for this pack entry.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `param.setData("OpPackCC", parentMap)` // Set entry data into request parameter |
| 2 | CALL | `execute(handle, param, "OpPackCC")` // Invoke telephone option pack CC for this pack entry |

### Block 6 — [End/Debug Log] (L3152)

Final debug logging.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `outDebugLog("----- setTelSelOptPackMapping End -----")` // Debug log end marker |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `func_cd` | Field | Function code — distinguishes between registration/check mode ("1", FUNC_CD_1) and check-only mode ("2", FUNC_CD_2). Controls whether actual registration/cancellation is performed or if data is merely validated. |
| `trn_div` | Field | Transaction division — indicates the type of operation: "00"=neutral (pre-check), "01"=register (new subscription), "02"=cancel (cancellation). |
| `svc_kei_no` | Field | Service contract number — unique identifier for a service contract line item in the telecom system. |
| `svc_kei_ucwk_no` | Field | Service contract internal detail number — internal work number for service contract line items, used for tracking and reference. |
| `svc_use_sta_kibo_ymd` | Field | Service usage start request year/month/day — the date the customer requests the service to begin. Must not be in the future relative to the operational date. |
| `svc_dlre_cd` | Field | Service contract reason code — code indicating the reason for the service contract (e.g., "01" = normal cancellation). |
| `svc_cancel_rsn_cd` | Field | Service cancellation reason code — code indicating the reason for service cancellation (e.g., "06" = cancellation by contract termination). |
| `kisan_ymd` | Field | Billing date (start date) — the date from which billing begins, typically set to the operational date. |
| `use_sta_kibo_ymd` | Field | Usage start request year/month/day — the requested service start date. |
| `ido_div` | Field | Movement/division code — classifies the type of movement: "00031" = option settings (オプション設定). |
| `pack_div` | Field | Pack division — classifies the type of option pack being registered or cancelled. |
| `kakin_div` | Field | Billing division — "1" indicates this entry is subject to invoicing/billing. |
| `pnlty_div` | Field | Penalty division — "0" indicates no penalty applies. |
| `wrib_svc_kei_no` | Field | Warranty (discount) service contract number — reference to the discount service contract; set to null for standalone option pack operations. |
| `wrib_svc_kei_stat` | Field | Warranty service contract status — status code indicating the state of the warranty/discount contract. Values not in `WRIB_SVC_KEI_STAT_MUKO` indicate an active contract. |
| `wrib_svc_kei_list` | Field | Warranty service contract list — list of warranty/discount service contracts returned by the OpPackCC pre-check call. |
| `kk0081_upd_dtm` | Field | Update year/month/day/time — optimistic concurrency control timestamp for the service contract; set differently for first vs. second pack entries. |
| `mskm_dtl_no` | Field | Registration detail number — generated service detail number for the registration contents recognition registration (EKK0011D020). |
| `in_sysid` | Field | SYSID — system identifier for the customer/account. |
| `op_pack_list` | Field | Option pack list — the list of telephone selection option pack entries to process. |
| `ido_rsv_dtl_cd_err` | Field | Movement reservation detail code error — error flag set when the service start date is in the future. |
| FUNC_CD_1 | Constant | Function code "1" — Registration/Check mode. Triggers actual registration/cancellation operations. |
| FUNC_CD_2 | Constant | Function code "2" — Check mode. Returns early after pre-check validation; no side effects. |
| RELATION_ERR | Constant | Relation error type — used for business validation errors (e.g., duplicate discount, future start date). |
| CD00879_01 | Constant | Standard cancellation code ("01") — normal service cancellation reason. |
| CD01390_06 | Constant | Cancellation by termination code ("06") — standard cancellation reason for contract termination. |
| CD00576_00031 | Constant | Movement division code "00031" — option settings (オプション設定). |
| CD00055_910 | Constant | Warranty service contract status "910" — contract cancelled. |
| CD00055_920 | Constant | Warranty service contract status "920" — contract cancelled (with penalty). |
| WRIB_SVC_KEI_STAT_MUKO | Constant | List of warranty service contract statuses not applicable to the current discount — [CD00055_910, CD00055_920] (cancelled, cancelled with penalty). |
| Temp ID EKK0011D020 | Constant | Template ID for "EKK0011D020 — Registration contents recognition registration" SC. |
| TEMP_ID_DTL_EKK0011D020 | Constant | Template detail key for the EKK0011D020 registration detail list. |
| OpPackCC | Component | Telephone selection option pack operation component — the service component invoked for all option pack registration/cancellation operations. |
| Option Pack | Business term | Option pack (オプションパック) — a bundled set of telecommunication services/options that a customer can subscribe to or cancel. |
| Pack Replacement | Business term | Pack replacement (パックの付け替え) — the operation of cancelling one option pack and subscribing to another, which requires a pre-check CC call and produces both a registration (trn_div="01") and cancellation (trn_div="02") entry. |
| SOD | Acronym | Service Order Data — telecom order fulfillment entity. |
| SCCallException | Technical | Service Component Call Exception — exception thrown when a business validation rule is violated during service component execution (e.g., future start date, duplicate discount). |