# Business Logic — JFUTelOptSvcMskmCmpCC.checkOpSvcKeiDeleData() [107 LOC]

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

## 1. Role

### JFUTelOptSvcMskmCmpCC.checkOpSvcKeiDeleData()

This method performs **option service contract cancellation validation and processing** (オプションサービス契約データ解約チェック処理) as part of a telecom subscription workflow. It is invoked during the **telephone option pack application and cancellation** (CMP — Common Component) flow within the eo Customer Infrastructure System (eo顧客基幹システム).

The method iterates over a list of option service contract entries (`dataList`) and, for each entry, performs one of three processing paths based on the contract's metadata:

1. **050 Number Preservation Conflict Check** — If the entry is not a standard option service (`mskm_div != "2"` or `svc_div != "1"`), but it involves the 050 number preservation service (code `"910"`), the method cross-references existing contract records to detect conflicting advance reservations. A reservation that has already been applied (stat `"910"`) within the same month as the target cancellation date is rejected as a duplicate re-application attempt.

2. **Approved Contract Handling** — If the option service contract status is `"020"` (Approved / 照栢済), the method invokes **EKK0351C220: Option Service Contract Cancellation Selection** (オプションサービス契約キャンセル), preparing cancellation selection data including the service contract number, detail number, cancellation reason code, migration flag, and previous update timestamp.

3. **Standard Cancellation Processing** — For all other statuses, the method first runs the **non-charge determination** (非課金判定処理) via `jdgHiChrg()` to assess whether charges apply (e.g., after billing start, cancellation may be free). Then it invokes **EKK0351C240: Option Service Contract Cancellation** (オプションサービス契約解約), which performs the actual contract termination, computing the service end date, charge end date, penalty status, and related fields.

As a design pattern, this method implements the **routing/dispatch pattern** — it reads a single parameter (`mskm_div` and `svc_div`) to decide whether to skip processing, run a conflict check, or branch into approved-vs-standard cancellation flows. It is a **shared utility** called by the parent method `execute()` in `JFUTelOptSvcMskmCmpCC`, which orchestrates the full option service contract application and cancellation submission.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START["checkOpSvcKeiDeleData"] --> INIT["outDebugLog Start"]
    INIT --> GET_INMAP["inMap = param.getData(fixedText)"]
    GET_INMAP --> INIT_EKK0371["JFUBPCommon.initData for EKK0371B001"]
    INIT_EKK0371 --> SETMAP_EKK0371["setInMapEKK0371B001"]
    SETMAP_EKK0371 --> EXEC_EKK0371["executeSC EKK0371B001: Option Service Contract Lookup"]
    EXEC_EKK0371 --> GET_LIST["opList = getTemplateList"]
    GET_LIST --> FOR_LOOP["For each dataMap in dataList"]
    FOR_LOOP --> CHECK_DIV{"mskm_div = 2 AND svc_div = 1?"}
    CHECK_DIV -->|No| SKIP_CHECK{"op_sbop_svc_cd = 910?"}
    SKIP_CHECK -->|No| CONTINUE["continue to next iteration"]
    SKIP_CHECK -->|Yes| CHECK_PAST["Loop opList: rsvAplyYmd check"]
    CHECK_PAST --> MATCH_STAT{"op_svc_cd match AND op_svc_kei_stat = 910 AND isPast AND sameMonth?"}
    MATCH_STAT -->|Yes| ERROR_THROW["setErrorField + throw SCCallException"]
    MATCH_STAT -->|No| CONTINUE
    ERROR_THROW --> END_METHOD
    CHECK_DIV -->|Yes| LOOP_OPLIST["Loop opList"]
    LOOP_OPLIST --> MATCH_CONTRACT{"op_svc_kei_no match?"}
    MATCH_CONTRACT -->|Yes| COPY_FIELDS["dataMap.put op_svc_kei_stat and svc_staymd"]
    MATCH_CONTRACT -->|No| NEXT_OPLIST["next opList entry"]
    COPY_FIELDS --> GET_STAT["opSvcKeiStat = dataMap.get op_svc_kei_stat"]
    NEXT_OPLIST --> GET_STAT
    GET_STAT --> CHECK_STAT{"opSvcKeiStat = 020?"}
    CHECK_STAT -->|Yes| APPROVED_FLOW["initData, setInMapEKK0351C220, executeSC EKK0351C220"]
    CHECK_STAT -->|No| NON_APPROVED["jdgHiChrg non-charge determination"]
    NON_APPROVED --> DELE_FLOW["initData, setInMapEKK0351C240, executeSC EKK0351C240"]
    DELE_FLOW --> FOR_LOOP
    APPROVED_FLOW --> FOR_LOOP
    CONTINUE --> FOR_LOOP
    FOR_LOOP --> END_LOG["outDebugLog End"]
    END_LOG --> RETURN["Return lastUpdDtm"]
    RETURN --> END_METHOD["End"]
```

**Constant Resolution:**
- `mskm_div = "2"` and `svc_div = "1"` — Standard option service classification
- `JFUStrConst.CD00136_B029 = "910"` — 050 Number Preservation service code (050ナンバープリパス)
- `JFUStrConst.CD00037_910 = "910"` — Contract status: "Completed" (解約済)
- `JFUStrConst.CD00037_020 = "020"` — Contract status: "Approved" (照栢済)

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `handle` | `SessionHandle` | Database session handle for executing service component (SC) calls. Provides transactional context for DB operations. |
| 2 | `param` | `IRequestParameterReadWrite` | Request parameter object carrying the input data map and control information. Used to read/write business data between CC and SC layers. |
| 3 | `fixedText` | `String` | Service message identifier / fixed text prefix used as a key for parameter maps. Used to scope `param.getData()`, `initData()`, and `executeSC()` calls — acts as a namespace for data within the request. |
| 4 | `dataList` | `ArrayList` | List of option service contract entries to process. Each entry is a `HashMap` containing fields like `mskm_div` (contract division), `svc_div` (service division), `op_svc_kei_no` (option service contract number), `op_sbop_svc_cd` (option/sub-option service code), etc. Represents the pending cancellation contracts. |
| 5 | `lastUpdDtm` | `String` | Last update date-time (year-month-day-hour-minute-second). Passed through to `setInMapEKK0351C220`/`setInMapEKK0351C240` for audit tracking. Returned as-is at method completion. |

**Instance fields read:**

| Field | Type | Business Description |
|-------|------|---------------------|
| `TEMP_ID_EKK0371B001` | `String` | Template ID "EKK0371B001" — Option Service Contract Lookup template |
| `TEMP_ID_DTL_EKK0371B001` | `String` | Detail template ID for EKK0371B001 — references `EKK0371B001CBSMsg1List` |
| `TEMP_TEMP_KEY_EKK0371B001` | `String` | Template result key prefix "TEMP_TEMPLATE_EKK0371B001_" |
| `IN_COL_LIST_EKK0371B001` | `List<String>` | Input column list for EKK0371B001 — `KEY_SVC_KEI_UCWK_NO` (service contract detail number) |
| `ERR_COL_EKK0371B001` | `String` | Error column — `KEY_SVC_KEI_UCWK_NO_ERR` |

## 4. CRUD Operations / Called Services

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `JFUBPCommon.executeSC` (EKK0371B001) | EKK0371B001SC | KK_T_OPSVKEI_OPT (Option Service Contract Header), KK_T_OPSVKEI_OPT_DTL (Detail) | Lookup option service contracts by service contract detail number (svc_kei_ucwk_no) for the current customer. Returns list of active contracts used for conflict detection and status lookup. |
| R | `JFUBPCommon.getOpeDate` | — | — | Retrieves the current operation date from the system. Used for date comparison in 050 number preservation conflict check (isPastDate and same-month comparison). |
| C | `JFUBPCommon.executeSC` (EKK0351C220) | EKK0351C220SC | KK_T_OPSVKEI_OPT (Option Service Contract) | Option Service Contract Cancellation Selection — invoked for contracts with status "020" (Approved). Prepares cancellation selection data including service contract number, detail number, cancellation reason code, migration flag, and previous update timestamp. |
| C/R | `JFUTelOptSvcMskmCmpCC.jdgHiChrg` | — | — | Non-charge determination method — assesses whether cancellation charges apply. Determines billing status, charge flags, and service charge end date for non-approved contracts. Returns a `HashMap` with charge-related data used in cancellation input. |
| C | `JFUBPCommon.executeSC` (EKK0351C240) | EKK0351C240SC | KK_T_OPSVKEI_OPT (Option Service Contract) | Option Service Contract Cancellation — actual contract termination for non-approved contracts. Inputs include service contract number, detail number, reservation start date, service end date, service charge end date, service delivery code, DSL user ID, penalty issuance code, migration flag, optional package service contract number, and warning flag. |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | `JFUTelOptSvcMskmCmpCC.execute()` | `execute` -> `checkOpSvcKeiDeleData` | EKK0371B001SC [R], EKK0351C220SC [C], EKK0351C240SC [C], jdgHiChrg [R] |

**Call chain context:** The `execute()` method in `JFUTelOptSvcMskmCmpCC` (line ~1007) is the entry point — a common component method that orchestrates the full telephone option pack application and cancellation flow. It processes option service lists via `convOpSvcList()`, then calls `checkOpSvcKeiDeleData()` to validate and process cancellations for each option service contract entry.

**Terminal operations from this method:**
- `outDebugLog` [-] — Debug logging (start/end markers)
- `JFUBPCommon.executeSC` (EKK0371B001) [R] — Option Service Contract Lookup
- `JFUBPCommon.executeSC` (EKK0351C220) [C] — Option Service Contract Cancellation Selection
- `JFUBPCommon.executeSC` (EKK0351C240) [C] — Option Service Contract Cancellation
- `jdgHiChrg` [R] — Non-charge determination
- `setErrorField` [-] — Set error field for UI display
- `SCCallException` [-] — Throw business exception on conflict detection
- `initData` (×3) — Initialize parameter maps for each SC invocation
- `setInMapEKK0371B001` [-] — Populate input map for contract lookup
- `setInMapEKK0351C220` [-] — Populate input map for cancellation selection
- `setInMapEKK0351C240` [-] — Populate input map for cancellation

## 6. Per-Branch Detail Blocks

### Block 1 — Initialization (L4280–L4299)

> Initialize debug log, retrieve data map, and fetch existing option service contracts.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `outDebugLog("----- checkOpSvcKeiDeleData Start -----")` // Start debug log |
| 2 | SET | `inMap = (HashMap) param.getData(fixedText)` // Retrieve parent data map from request [-> fixedText: service message identifier] |
| 3 | SET | `opList = JFUBPCommon.getTemplateList(...)` // Parent contract lookup results |
| 4 | EXEC | `JFUBPCommon.initData(param, fixedText, IN_COL_LIST_EKK0371B001)` // Initialize parameter map for EKK0371B001 [-> IN_COL_LIST_EKK0371B001: [KEY_SVC_KEI_UCWK_NO]] |
| 5 | EXEC | `setInMapEKK0371B001(param, fixedText, inMap)` // Populate input map for contract lookup [-> Sets svc_kei_ucwk_no from parent inMap] |
| 6 | CALL | `JFUBPCommon.executeSC(handle, param, fixedText, TEMP_ID_EKK0371B001, TEMP_ID_DTL_EKK0371B001, IN_COL_LIST_EKK0371B001, ERR_COL_EKK0371B001)` // Execute SC: EKK0371B001 Option Service Contract Lookup (電話)一覧照会 [サービス契約内訳番号] |
| 7 | SET | `opList = JFUBPCommon.getTemplateList(inMap, JFUBPCommon.getMaxTempTempleteKey(inMap, TEMP_TEMP_KEY_EKK0371B001), TEMP_ID_DTL_EKK0371B001)` // Extract detail list from SC result [-> TEMP_TEMP_KEY_EKK0371B001 = "TEMP_TEMPLATE_EKK0371B001_"] |

### Block 2 — For Loop: Iterate Over Data List (L4301–L4380)

> Process each option service contract entry in the input data list.

| # | Type | Code |
|---|------|------|
| 1 | SET | `dataMap = (HashMap) dataList.get(i)` // Get current entry from list |

#### Block 2.1 — Branch Check: Standard Option Service (L4305–L4380)

> Determine if this entry is a standard option service (`mskm_div = "2"` AND `svc_div = "1"`). If not, handle as special case.

| # | Type | Code |
|---|------|------|
| 1 | COND | `if (!"2".equals(dataMap.get("mskm_div")) || !"1".equals(dataMap.get("svc_div")))` // Skip if NOT standard option service [-> mskm_div="2": contract division, svc_div="1": service division] |

##### Block 2.1.1 — Non-Standard Path: 050 Number Preservation Conflict Check (L4309–L4332)

> For non-standard option entries, check if 050 number preservation service has a conflicting advance reservation.

| # | Type | Code |
|---|------|------|
| 1 | COND | `if (JFUStrConst.CD00136_B029.equals(dataMap.get(OP_SBOP_SVC_CD)))` // [-> CD00136_B029 = "910" (050 Number Preservation service code)] [-> OP_SBOP_SVC_CD = "op_sbop_svc_cd"] |

###### Block 2.1.1.1 — Loop Over Existing Contracts: Conflict Detection (L4317–L4331)

> For each existing contract in `opList`, check for conflicting advance reservations.

| # | Type | Code |
|---|------|------|
| 1 | SET | `rsvAplyYmd = (String) dtlMap.get(EKK0371B001CBSMsg1List.RSV_APLY_YMD)` // Reservation application date [-> YYYYMMDD format] |
| 2 | COND | `if (dataMap.get(OP_SBOP_SVC_CD).equals(dtlMap.get("op_svc_cd")) && JFUStrConst.CD00037_910.equals(dtlMap.get("op_svc_kei_stat")) && JPCUtilCommon.isPastDate(rsvAplyYmd, JFUBPCommon.getOpeDate(null), "1") && rsvAplyYmd.startsWith(JFUBPCommon.getOpeDate(null).substring(0, 6)))` |
| 2.1 | [-> CD00037_910 = "910"] | Contract status "910" = Completed (解約済) |
| 2.2 | [-> isPastDate] | Reservation date is past (completed) relative to operation date |
| 2.3 | [-> sameMonth] | `rsvAplyYmd.startsWith(opeDate.substring(0,6))` — same YYYYMM |

| # | Type | Code |
|---|------|------|
| 3 | SET | `setErrorField(param, "rsv_aply_ymd_err")` // Set error field in UI for reservation date |
| 4 | RETURN | `throw new SCCallException("オプション・サブオプションサービスの異動予約が存在", "0", JPCModelConstant.RELATION_ERR)` // Business exception: "Advance reservation for option/sub-option service exists" [-> RELATION_ERR: relational error code] |

##### Block 2.1.2 — Skip Non-Standard Entries (L4333)

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `continue` // Skip remaining processing for this non-standard entry |

#### Block 2.2 — Standard Path: Copy Contract Status (L4337–L4350)

> For standard option service entries, look up and copy contract status and service start date from existing contracts.

| # | Type | Code |
|---|------|------|
| 1 | COND | Loop `for (HashMap dtlMap : opList)` // Iterate existing option service contracts |
| 2 | COND | `if (dtlMap.get("op_svc_kei_no").equals(dataMap.get("op_svc_kei_no")))` // Match by option service contract number |

| # | Type | Code |
|---|------|------|
| 3 | SET | `dataMap.put("op_svc_kei_stat", dtlMap.get("op_svc_kei_stat"))` // Copy contract status from existing record |
| 4 | SET | `dataMap.put("svc_staymd", dtlMap.get("svc_staymd"))` // Copy service start date |
| 5 | SET | `opSvcKeiStat = (String) dataMap.get("op_svc_kei_stat")` // Read the resolved status for branching |

#### Block 2.3 — Branch on Contract Status (L4353–L4377)

> Route to approved cancellation flow or standard cancellation flow based on contract status.

| # | Type | Code |
|---|------|------|
| 1 | COND | `if (JFUStrConst.CD00037_020.equals(opSvcKeiStat))` // [-> CD00037_020 = "020" (Approved / 照栢済)] |

##### Block 2.3.1 — Approved Contract Cancellation Selection (L4357–L4360)

> For "020" (Approved) status contracts, invoke the cancellation selection SC (EKK0351C220).

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `JFUBPCommon.initData(param, fixedText, IN_COL_LIST_EKK0351C220)` // Initialize parameter map [-> IN_COL_LIST_EKK0351C220: [OP_SVC_KEI_NO, MSKM_DTL_NO, SVC_CANCEL_RSN_CD, IDO_DIV, UPD_DTM_BF]] |
| 2 | EXEC | `setInMapEKK0351C220(param, fixedText, dataMap, lastUpdDtm)` // Populate cancellation selection input map [-> Sets option service contract number, detail number, cancellation reason code, migration flag, previous update timestamp] |
| 3 | CALL | `JFUBPCommon.executeSC(handle, param, fixedText, TEMP_ID_EKK0351C220, TEMP_ID_DTL_EKK0351C220, IN_COL_LIST_EKK0351C220, ERR_COL_EKK0351C220)` // Execute SC: EKK0351C220 Option Service Contract Cancellation Selection (キャンセル) |
| 4 | ERR | `ERR_COL_EKK0351C220 = null` // No associated error column defined |

##### Block 2.3.2 — Standard Cancellation (L4363–L4377)

> For non-"020" status contracts, run non-charge determination then execute cancellation SC (EKK0351C240).

| # | Type | Code |
|---|------|------|
| 1 | CALL | `hiChrgMap = jdgHiChrg(handle, param, fixedText, dataMap)` // Non-charge determination [-> Returns HashMap with svcChrgEndYmd, chrgFlg] |

| # | Type | Code |
|---|------|------|
| 2 | EXEC | `JFUBPCommon.initData(param, fixedText, IN_COL_LIST_EKK0351C240)` // Initialize parameter map [-> IN_COL_LIST_EKK0351C240: [OP_SVC_KEI_NO, MSKM_DTL_NO, RSV_TSTA_KIBO_YMD, SVC_ENDYMD, SVC_CHRG_ENDYMD, SVC_DLRE_CD, SVC_DLRE_MEMO, DSL_TNT_USER_ID, PNLTY_HASSEI_CD, IDO_DIV, UPD_DTM_BF, OP_HKTGI_SK_SVC_KEI_NO, WARN_FLG]] |
| 3 | EXEC | `setInMapEKK0351C240(param, fixedText, dataMap, hiChrgMap, lastUpdDtm)` // Populate cancellation input map [-> Sets option service contract number, detail number, reservation start date, service end date, charge end date from jdgHiChrg result, delivery code, user ID, penalty flag, migration flag, optional package service contract number, warning flag] |
| 4 | CALL | `JFUBPCommon.executeSC(handle, param, fixedText, TEMP_ID_EKK0351C240, TEMP_ID_DTL_EKK0351C240, IN_COL_LIST_EKK0351C240, ERR_COL_EKK0351C240)` // Execute SC: EKK0351C240 Option Service Contract Cancellation (解約) |
| 5 | ERR | `ERR_COL_EKK0351C240 = null` // No associated error column defined |

### Block 3 — Cleanup (L4381–L4384)

> End debug log and return last update date-time.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `outDebugLog("----- checkOpSvcKeiDeleData End -----")` // End debug log |
| 2 | RETURN | `return lastUpdDtm` // Return unchanged last update date-time |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `mskm_div` | Field | Contract division flag — distinguishes standard contracts (`"2"`) from special types |
| `svc_div` | Field | Service division flag — `"1"` indicates a standard option service line |
| `op_sbop_svc_cd` | Field | Option/Sub-option service code — classifies the specific service type (e.g., `"910"` = 050 Number Preservation) |
| `op_svc_kei_no` | Field | Option service contract number — unique identifier for an option service contract |
| `op_svc_kei_stat` | Field | Option service contract status — `"020"` = Approved (照栢済), `"910"` = Completed (解約済) |
| `svc_staymd` | Field | Service stay/ start date — when the option service begins |
| `op_svc_kei_ucwk_no` | Field | Option service contract detail number — internal tracking ID for a service contract line item |
| `rsv_aply_ymd` | Field | Reservation application date — date when a service advance reservation was applied (YYYYMMDD) |
| `RSV_TSTA_KIBO_YMD` | Field | Reservation start desired date — customer's requested service start date |
| `SVC_ENDYMD` | Field | Service end date — date when service terminates upon cancellation |
| `SVC_CHRG_ENDYMD` | Field | Service charge end date — date when billing ends (may differ from service end) |
| `SVC_CANCEL_RSN_CD` | Field | Service cancellation reason code — reason code for the cancellation request |
| `MSKM_DTL_NO` | Field | Contract detail number — line item number within a service contract |
| `IDO_DIV` | Field | Migration division flag — indicates whether this is a migration/carry-over operation |
| `UPD_DTM_BF` | Field | Update date-time before — previous version timestamp for optimistic locking / audit |
| `WARN_FLG` | Field | Warning flag — indicates whether a warning should be displayed during cancellation |
| `PNLTY_HASSEI_CD` | Field | Penalty issuance code — code for early termination penalty assessment |
| `DSL_TNT_USER_ID` | Field | DSL tenant user ID — user identifier for DSL service |
| `SVC_DLRE_CD` / `SVC_DLRE_MEMO` | Field | Service delivery code / memo — delivery details for the cancellation |
| `OP_HKTGI_SK_SVC_KEI_NO` | Field | Optional package service contract number — related optional package contract |
| `CHRGFLG` | Field | Charge flag — whether charges apply to this cancellation |
| `050ナンバープリパス` (050 Number Preservation) | Business term | A service allowing customers to retain their phone number when switching providers — a specialized non-standard service type |
| 照栢済 (Shokubaki-zumi) | Business term | Approved/confirmed status — the contract has been reviewed and approved |
| 解約済 (Kaiyaku-zumi) | Business term | Cancelled/completed status — the service contract has been fully cancelled |
| 非課金判定 (Hikakin Handan) | Business term | Non-charge determination — assessment of whether cancellation incurs charges based on billing status |
| オプションサービス | Business term | Option service — add-on services bundled with the main telephone service contract |
| EKK0371B001 | SC Code | Option Service Contract Lookup SC (電話)一覧照会 — retrieves existing option service contracts by service contract detail number |
| EKK0351C220 | SC Code | Option Service Contract Cancellation Selection SC (キャンセル) — prepares cancellation selection data for approved contracts |
| EKK0351C240 | SC Code | Option Service Contract Cancellation SC (解約) — executes the actual contract cancellation |
| SCCallException | Technical | Service Component call exception — thrown for business rule violations |
| JPCModelConstant.RELATION_ERR | Technical | Relational error constant — indicates a conflict with existing data |
| JPCUtilCommon.isPastDate | Technical | Utility method — checks if a given date is in the past relative to the operation date |
