# Business Logic — KKW02519SFLogic.actionUpdCfm() [316 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `eo.web.webview.KKW02519SF.KKW02519SFLogic` |
| Layer | Web Logic (Controller layer — extends `JCCWebBusinessLogic`, handles web screen business logic for the KKW02519SF screen) |
| Module | `KKW02519SF` (Package: `eo.web.webview.KKW02519SF`) |

## 1. Role

### KKW02519SFLogic.actionUpdCfm()

This method is the **update-confirm button handler** for the "Phone Option Service Contract Update" screen (`KKW02519`). When the user presses the confirm button on the update screen, this method orchestrates the entire confirmation workflow: it routes between two fundamentally different business operations based on the processing division (`tranDiv`) — **service contract modification** (変更) or **service contract cancellation** (解約) — then executes the appropriate backend service, validates dependent/associated options, and displays the appropriate confirmation message.

In the **modification branch** (`tranDiv == OP_TRAN_DIV_CHGE`), the method adjusts the customer's monthly call allowance (multiplying the entered value by 1000 to convert from yen to the internal unit) and delegates to `kksv0516Execute` which processes the modification service through the appropriate service component. It then sets the next screen to `KKW02520` (the update completion screen).

In the **cancellation branch** (any other `tranDiv`), the method parses the user-entered termination date from separate year/month/day fields, delegates to `kksv0370Execute` which processes the cancellation service, then performs **cascading validation** of associated options (sub-options and parent options) to ensure no contracts with active or pending-child relationships will be orphaned. It additionally checks for dependent services (Caller ID display "B025" and Sure Call "B135") that cannot be cancelled while still registered. A future-date overlap check ensures the cancellation date does not conflict with other bundled package services. Finally, it evaluates discount check results and displays the appropriate cancellation confirmation message.

The method implements a **routing/dispatch pattern**: it selects the correct execution path based on `tranDiv`, delegates to specialized sub-methods (`kksv0516Execute` for modification, `kksv0370Execute` for cancellation), and consolidates results into a single boolean return (`true` for success, `false` for abnormal termination). It serves as the primary entry point for both service contract modification and cancellation confirmation flows on the KKW02519 screen.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["actionUpdCfm"])
    START --> SETUP["Get serviceFormBean, telOpSvcKeiList, telOpSvcKei"]
    SETUP --> LOG1["Log DataBean dump"]
    LOG1 --> BRANCH["tranDiv == OP_TRAN_DIV_CHGE?"]

    BRANCH -->|"Yes: 変更 (Change)"| BR_C["Change branch"]
    BRANCH -->|"No: 解約 (Cancel)"| BR_K["Cancel branch"]

    BR_C --> ADJ["Adjust call allowance: twStiam * 1000"]
    ADJ --> K516["kksv0516Execute"]
    K516 -->|Fail| RF1["Return false"]
    K516 -->|Success| S_NXT["Set nextScreenId/Name = KKW02520"]
    S_NXT --> MSG_C["Set message: 電話オプションサービス契約の情報更新"]
    MSG_C --> LOG2["Log DataBean dump"]
    LOG2 --> RT1["Return true"]

    BR_K --> PARSE["Parse useEndYmd from year/month/day"]
    PARSE --> SET_YMD["Set USE_END_YMD, USE_END_YMD_01"]
    SET_YMD --> K370["kksv0370Execute"]
    K370 -->|Fail| RF2["Return false"]
    K370 -->|Success| S_NXT2["Set nextScreenId/Name = KKW02520"]
    S_NXT2 --> AS_CHK["Check assoc child opSvc status in 100/030/210"]

    AS_CHK -->|Has active child| OP_CD_CHK["opCd == OP_SVC_CD_VALUE_0160?"]
    AS_CHK -->|No active child| ANK_CHK["ANK-3754 release check"]

    OP_CD_CHK -->|Yes| MSG_TS["Set message: 転送電話, 解約, 転送電話選択"]
    MSG_TS --> ANK_CHK
    OP_CD_CHK -->|No| OP_CD_CHK2["opCd == OP_SVC_CD_VALUE_0180?"]
    OP_CD_CHK2 -->|Yes| MSG_FN["Set message: 発信者番号表示, 解約, 非通知着信拒否"]
    MSG_FN --> ANK_CHK
    OP_CD_CHK2 -->|No| ANK_CHK

    ANK_CHK --> B025["opCd == B025?"]
    B025 -->|Yes| R_HSN["isDlsCheckHsnshNoDsp"]
    B025 -->|No| B135["opCd == B135?"]

    R_HSN -->|Fail| MSG_HSN["Set message: あんしん着信, 登録中, 発信者番号表示を解約"]
    MSG_HSN --> RF3["Return false"]
    R_HSN -->|Success| B135

    B135 -->|Yes| R_ANS["isDlsCheckAnsHcs"]
    B135 -->|No| FC_CHK["Future date check"]

    R_ANS -->|Fail| MSG_ANS["Set message: あんしん着信終了日, 発信者番号表示終了日以前"]
    MSG_ANS --> RF4["Return false"]
    R_ANS -->|Success| FC_CHK

    FC_CHK --> GET_LIST["Get opSvcKeiList, op_pack_kousei_list, pack_op_svc_kei_list, getOpeDate"]
    GET_LIST --> PK_NULL["op_pack_kousei_list != null?"]
    PK_NULL -->|No| OT_CHK["Otoku check"]
    PK_NULL -->|Yes| LP1["Loop op_pack_kousei_list i"]

    LP1 --> K_PLAN["kouseiOpPPlanCd == opPplanCd?"]
    K_PLAN -->|No| NEXT_LP1["i++"]
    K_PLAN -->|Yes| CMP_END["useEndYmd > unyo_ymd?"]
    CMP_END -->|No| NEXT_LP1
    CMP_END -->|Yes| SET_FLG["Set pack_mirai_msg_flg = true, break"]
    SET_FLG --> OUT1["break outside"]
    NEXT_LP1 --> CHK_LP1["i < getCount()?"]
    CHK_LP1 -->|Yes| LP1
    CHK_LP1 -->|No| LP2["Loop pack_op_svc_kei_list cnt"]

    LP2 --> K_PLAN2["kouseiOpPPlanCd1 == list_opPplanCd?"]
    K_PLAN2 -->|No| NEXT_I2["j++"]
    K_PLAN2 -->|Yes| CHK_STAT["State != 910/920 AND (startDay>now OR endDay>now)?"]
    CHK_STAT -->|No| NEXT_I2
    CHK_STAT -->|Yes| SET_FLG2["Set pack_mirai_msg_flg = true, break"]
    SET_FLG2 --> OUT2["break inner"]
    NEXT_I2 --> CHK_I2["j < getCount()?"]
    CHK_I2 -->|Yes| LP2_I["Inner loop i"]
    CHK_I2 -->|No| NEXT_LP2["cnt++"]
    NEXT_LP2 --> CHK_LP2["cnt < getCount()?"]
    CHK_LP2 -->|Yes| LP2
    CHK_LP2 -->|No| MSG_FLG["pack_mirai_msg_flg? Show EKBE130_KW"]

    OUT1 --> OT_CHK
    OUT2 --> OT_CHK
    MSG_FLG --> OT_CHK

    OT_CHK --> GET_OTOKU["Get otoku_chk_err_flg, otoku_chk_wrib_svc_cd"]
    GET_OTOKU --> OT1["err_flg == 1?"]
    OT1 -->|No| FINAL_MSG["Set message: 電話オプションサービス契約の解約"]
    OT1 -->|Yes| WRCHECK["WribSvcCd check"]

    WRCHECK -->|W00000007| EC1["errChar = eo光電話パック3"]
    WRCHECK -->|W00000008| EC2["errChar = eo光電話パック7"]
    WRCHECK -->|W00000023| EC3["errChar = あんしん電話パック"]
    WRCHECK -->|Other| EC4["errChar = 単品でお申し込み"]

    EC1 --> OT_MSG["Set message EKBE131-KW"]
    EC2 --> OT_MSG
    EC3 --> OT_MSG
    EC4 --> OT_MSG
    OT_MSG --> FINAL_MSG

    FINAL_MSG --> LOG3["Log DataBean dump"]
    LOG3 --> RT2["Return true"]
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| - | `(none — instance method)` | - | - |
| - | `tranDiv` (instance field) | `String` | Processing division — determines whether the operation is a **service contract modification** (`OP_TRAN_DIV_CHGE`) or a **cancellation**. This is set during screen initialization and controls the entire branching logic of the method. |
| - | `svcFormBean` | `X31SDataBeanAccess` | Service form DataBean — holds all screen input/output data including the termination date fields, call allowance, option codes, and discount check flags. Accessed via `super.getServiceFormBean()`. |
| - | `telOpSvcKeiList` | `X31SDataBeanAccessArray` | Phone option service contract info list — contains the main option service contract data being modified or cancelled (first element at index 0). |
| - | `telOpSvcKei` | `X31SDataBeanAccess` | Single phone option service contract info bean — the current row being processed, extracted from `telOpSvcKeiList` at index 0. |
| - | `commonBean` | `X31SDataBeanAccess` | Common info bean — holds navigation state including the next screen ID (`KKW02520`) and screen name, set in both branches before returning. |
| - | `opSvcKeiList` | `X31SDataBeanAccessArray` | Option service contract confirmation list — used for future date overlap checking against other contracts in the package. |
| - | `op_pack_kousei_list` | `X31SDataBeanAccessArray` | Discount service composition confirmation details (discount type code list) — used for package composition overlap validation. |
| - | `pack_op_svc_kei_list` | `X31SDataBeanAccessArray` | Package-determination option service contract confirmation list — contains other option services in the same package for cross-checking contract status and date ranges. |

## 4. CRUD Operations / Called Services

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

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `JCCWebCommon.getOpeDate` | (utility) | - | Calls `getOpeDate` to retrieve the current operation date for future date comparison. |
| - | `JCCWebCommon.setMessageInfo` | (utility) | - | Sets confirmation/error messages displayed to the user. Called for both success and error paths. |
| - | `KKW02519SFLogic.kksv0370Execute` | (internal) | - | Executes the phone option service contract update-cancellation service. Handles the cancellation branch logic. |
| - | `KKW02519SFLogic.kksv0516Execute` | (internal) | - | Executes the phone option service contract update-modification service. Handles the modification branch logic. |
| - | `KKW02519SFLogic.isDlsCheckHsnshNoDsp` | (internal) | - | Checks whether the Caller ID display service can be released (verifies no concurrent Sure Call registrations). |
| - | `KKW02519SFLogic.isDlsCheckAnsHcs` | (internal) | - | Checks whether the Sure Call service can be released (verifies no dependency on Caller ID display). |

**Business Description of Called Methods:**
- `kksv0516Execute`: Executes the backend service for modifying phone option service contract details (call allowance change). Returns `false` if the service fails.
- `kksv0370Execute`: Executes the backend service for cancelling a phone option service contract. Returns `false` if the service fails.
- `isDlsCheckHsnshNoDsp`: Validates whether Caller ID display (発信者番号表示) service can be safely cancelled by checking for concurrent Sure Call (あんしん着信) service registrations.
- `isDlsCheckAnsHcs`: Validates whether Sure Call (あんしん着信) service can be safely cancelled by checking if Caller ID display (発信者番号表示) is still active.

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Screen:KKW02519 | `KKW02519SFLogic.actionConfirm` -> `KKW02519SFLogic.actionUpdCfm` | `kksv0516Execute [U] 電話オプションサービス契約情報` (modification) / `kksv0370Execute [U] 電話オプションサービス契約解約` (cancellation) |

**Notes:** This method is the confirm-button handler for the KKW02519 screen ("Phone Option Service Contract Update"). It is called from the screen's main processing flow after the user has entered update/cancellation details and pressed the confirm button. No other screen or batch directly invokes this method — it is exclusively scoped to the KKW02519 update-confirm flow.

## 6. Per-Branch Detail Blocks

### Block 1 — INIT (data retrieval) (L426-435)

> Initialize the processing by retrieving the service form bean, extracting the phone option service contract list, and logging the DataBean state for debugging.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `svcFormBean = super.getServiceFormBean()` |
| 2 | EXEC | `JSYwebLog.println(JSYwebLog.DataBean_Dump, getClass(), dumpDatabean(), null, null, null)` // Log DataBean dump (出力) |
| 3 | CALL | `telOpSvcKeiList = svcFormBean.getDataBeanArray(KKW02519SFConst.TEL_OP_SVC_KEI_LIST)` |
| 4 | CALL | `telOpSvcKei = telOpSvcKeiList.getDataBean(0)` |

### Block 2 — IF [Condition: tranDiv == OP_TRAN_DIV_CHGE] (Modification branch) (L436-449)

> **OP_TRAN_DIV_CHGE** — Processing division for contract modification (変更). When true, handles call allowance adjustment and modification service execution.

| # | Type | Code |
|---|------|------|
| 1 | SET | `twStiam = telOpSvcKei.sendMessageString(KKW02519SFConst.USE_TW_STIAM_01, X31CWebConst.DATABEAN_GET_VALUE)` // Get call allowance (電話料指定額) |
| 2 | SET | `iTwStiam = Integer.parseInt(twStiam) * 1000` // Convert to internal unit |
| 3 | SET | `[-> USE_TW_STIAM_01 = "電話料指定額"]` |
| 4 | SET | `[-> UPD_TW_STIAM = "更新用通話指定額"]` |
| 5 | CALL | `svcFormBean.sendMessageString(KKW02519SFConst.UPD_TW_STIAM, X31CWebConst.DATABEAN_SET_VALUE, String.valueOf(iTwStiam))` // Set updated call allowance (更新用通話指定額) |
| 6 | EXEC | `if (!kksv0516Execute(svcFormBean, JPCModelConstant.FUNC_CD_2)) return false` // Execute modification service [-> FUNC_CD_2 = "2"] |
| 7 | CALL | `commonBean = super.getCommonInfoBean()` // Get common info bean |
| 8 | SET | `commonBean.sendMessageString(CommonInfoCFConst.NEXT_SCREEN_ID, X31CWebConst.DATABEAN_SET_VALUE, JKKScreenConst.SCREEN_ID_KKW02520)` // Set next screen [-> SCREEN_ID_KKW02520 = "KKW02520"] |
| 9 | SET | `commonBean.sendMessageString(CommonInfoCFConst.NEXT_SCREEN_NAME, X31CWebConst.DATABEAN_SET_VALUE, JKKScreenConst.SCREEN_NAME_KKW02520)` // Set next screen name [-> SCREEN_NAME_KKW02520 = "電話オプションサービス契約更新完了"] |
| 10 | SET | `str = {"電話オプションサービス契約の情報更新"}` // Message array |
| 11 | CALL | `JCCWebCommon.setMessageInfo(this, JPCOnlineMessageConstant.EKB0370__I, str)` // Set info message: "Phone option service contract info update" |
| 12 | EXEC | `JSYwebLog.println(JSYwebLog.DataBean_Dump, getClass(), dumpDatabean(), null, null, null)` // Log DataBean dump |
| 13 | RETURN | `return true` |

### Block 3 — ELSE [Cancel branch] (L450-740)

> When `tranDiv != OP_TRAN_DIV_CHGE`, handles service contract cancellation (解約). Parses the termination date, executes cancellation, validates associated options, and checks for dependent services.

#### Block 3.1 — Date parsing (L453-462)

> Parse the termination date from separate year/month/day string fields and format them for use.

| # | Type | Code |
|---|------|------|
| 1 | SET | `useEndYmdYear = telOpSvcKei.sendMessageString(KKW02519SFConst.USE_END_YMD_YEAR_01, X31CWebConst.DATABEAN_GET_VALUE)` // Year part [-> USE_END_YMD_YEAR_01 = "利用終了日（年）"] |
| 2 | SET | `useEndYmdMon = telOpSvcKei.sendMessageString(KKW02519SFConst.USE_END_YMD_MON_01, X31CWebConst.DATABEAN_GET_VALUE)` // Month part [-> USE_END_YMD_MON_01 = "利用終了日（月）"] |
| 3 | SET | `useEndYmdDay = telOpSvcKei.sendMessageString(KKW02519SFConst.USE_END_YMD_DAY_01, X31CWebConst.DATABEAN_GET_VALUE)` // Day part [-> USE_END_YMD_DAY_01 = "利用終了日（日）"] |
| 4 | SET | `useEndYmd = useEndYmdYear + useEndYmdMon + useEndYmdDay` // Combined: "20260628" |
| 5 | SET | `useEndYmdDate = useEndYmdYear + "/" + useEndYmdMon + "/" + useEndYmdDay` // Display format: "2026/06/28" |
| 6 | SET | `svcFormBean.sendMessageString(KKW02519SFConst.USE_END_YMD, X31CWebConst.DATABEAN_SET_VALUE, useEndYmd)` // Set full date [-> USE_END_YMD = "利用終了年月日"] |
| 7 | SET | `telOpSvcKei.sendMessageString(KKW02519SFConst.USE_END_YMD_01, X31CWebConst.DATABEAN_SET_VALUE, useEndYmdDate)` // Set display date [-> USE_END_YMD_01 = "利用終了日"] |

#### Block 3.2 — Cancellation service execution (L464-472)

> Execute the phone option service contract cancellation service. On failure, return false.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `if (!kksv0370Execute(svcFormBean, JPCModelConstant.FUNC_CD_2)) return false` // Execute cancellation service |
| 2 | CALL | `commonBean = super.getCommonInfoBean()` // Get common bean |
| 3 | SET | `commonBean.sendMessageString(CommonInfoCFConst.NEXT_SCREEN_ID, X31CWebConst.DATABEAN_SET_VALUE, JKKScreenConst.SCREEN_ID_KKW02520)` |
| 4 | SET | `commonBean.sendMessageString(CommonInfoCFConst.NEXT_SCREEN_NAME, X31CWebConst.DATABEAN_SET_VALUE, JKKScreenConst.SCREEN_NAME_KKW02520)` |

#### Block 3.3 — Associated option check (L475-511)

> Check if there are child options that are still active when the parent option is being cancelled. Status codes: 100 (Contract completed/契約済), 030 (Suspended/休止中), 210 (Cancelled/中断中).

| # | Type | Code |
|---|------|------|
| 1 | CALL | `sbopSvcKeiList = svcFormBean.getDataBeanArray(KKW02519SFConst.SBOP_SVC_KEI_LIST)` // Get sub-option list [-> SBOP_SVC_KEI_LIST = "サブオプションサービス契約一覧照会リスト"] |
| 2 | CALL | `sbopSvcKei = sbopSvcKeiList.getDataBean(0)` |
| 3 | SET | `opCd = telOpSvcKei.sendMessageString(KKW02519SFConst.OP_CD_01, X31CWebConst.DATABEAN_GET_VALUE)` // Get option code [-> OP_CD_01 = "オプションコード"] |
| 4 | SET | `sbopSvcKeiNo = svcFormBean.sendMessageString(KKW02519SFConst.SBOP_SVC_KEI_NO, X31CWebConst.DATABEAN_GET_VALUE)` // Get sub-option number [-> SBOP_SVC_KEI_NO = "サブオプションサービス契約番号"] |
| 5 | SET | `sbopSvcKeiStat = sbopSvcKei.sendMessageString(KKW02519SFConst.SBOP_SVC_KEI_STAT_06, X31CWebConst.DATABEAN_GET_VALUE)` // Get sub-option status [-> SBOP_SVC_KEI_STAT_06 = "サブオプションサービス契約ステータス"] |

##### Block 3.3.1 — IF: Has active child option (L484-511)

> `[-> SBOP_SVC_KEI_STAT_06 values: "100"=契約済, "030"=休止中, "210"=中断中]`
> Parent option is being cancelled while a child option is still active. Display error message based on the parent option type.

| # | Type | Code |
|---|------|------|
| 1 | SET | `if ((null == sbopSvcKeiNo || "".equals(sbopSvcKeiNo)) && (null != sbopSvcKeiStat && ("100".equals(sbopSvcKeiStat) || "030".equals(sbopSvcKeiStat) || "210".equals(sbopSvcKeiStat))))` // Check: child has no number but status is active/pending |
| 2 | SET | `if (JKKCommonConst.OP_SVC_CD_VALUE_0160.equals(opCd))` // [-> OP_SVC_CD_VALUE_0160 = "0160"] Check for transfer phone (転送電話) |
| 3 | SET | `str = {"転送電話","解約","転送電話選択"}` |
| 4 | CALL | `JCCWebCommon.setMessageInfo(this, JPCOnlineMessageConstant.EKB1760__I, str)` |
| 5 | SET | `else if (JKKCommonConst.OP_SVC_CD_VALUE_0180.equals(opCd))` // [-> OP_SVC_CD_VALUE_0180 = "0180"] Check for caller ID display (発信者番号表示) |
| 6 | SET | `str = {"発信者番号表示","解約","非通知着信拒否"}` |
| 7 | CALL | `JCCWebCommon.setMessageInfo(this, JPCOnlineMessageConstant.EKB1760__I, str)` |

#### Block 3.4 — ANK-3754 Release check: Caller ID display B025 (L515-532)

> If the cancelled option is Caller ID display (発信者番号表示, code "B025"), check whether Sure Call (あんしん着信) is still registered.

| # | Type | Code |
|---|------|------|
| 1 | SET | `if ("B025".equals(opCd))` // Caller ID display service |
| 2 | CALL | `opSvcKeiList = svcFormBean.getDataBeanArray(KKW02519SFConst.PACK_OP_SVC_KEI_LIST)` // Get option service contract list |
| 3 | EXEC | `if (!isDlsCheckHsnshNoDsp(opSvcKeiList, useEndYmd)) return false` // Check if Sure Call is still registered |
| 4 | SET | `str = {"あんしん着信サービス","登録中","発信者番号表示を解約"}` // Error message: Sure Call service registered, cannot cancel Caller ID |
| 5 | CALL | `JCCWebCommon.setMessageInfo(this, JPCOnlineMessageConstant.EKB1040_JW, str)` |
| 6 | RETURN | `return false` |

#### Block 3.5 — ANK-3754 Release check: Sure Call B135 (L533-550)

> If the cancelled option is Sure Call (あんしん着信, code "B135"), check whether Caller ID display (発信者番号表示) is still active.

| # | Type | Code |
|---|------|------|
| 1 | SET | `else if ("B135".equals(opCd))` // Sure Call service |
| 2 | CALL | `opSvcKeiList = svcFormBean.getDataBeanArray(KKW02519SFConst.PACK_OP_SVC_KEI_LIST)` // Get option service contract list |
| 3 | EXEC | `if (!isDlsCheckAnsHcs(opSvcKeiList, useEndYmd)) return false` // Check if Caller ID display is still active |
| 4 | SET | `str = {"あんしん着信サービスの利用終了日","発信者番号表示の利用終了日以前"}` // Error message: Sure Call termination date is before Caller ID display termination |
| 5 | CALL | `JCCWebCommon.setMessageInfo(this, JPCOnlineMessageConstant.EKBF460_KW, str)` |
| 6 | RETURN | `return false` |

#### Block 3.6 — Future date check: Phone secure package overlap (L552-649)

> Check whether the cancellation date overlaps with other active package option services. This includes both the modified option and other options in the same package bundle.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `opSvcKeiList = svcFormBean.getDataBeanArray(KKW02519SFConst.OP_SVC_KEI_LIST)` // Get option service list [-> OP_SVC_KEI_LIST = "オプションサービス契約一覧照会リスト"] |
| 2 | CALL | `opSvcKei = opSvcKeiList.getDataBean(0)` |
| 3 | SET | `opPplanCd = opSvcKei.sendMessageString(KKW02519SFConst.PPLAN_CD_05, X31CWebConst.DATABEAN_GET_VALUE)` // Get pricing plan code [-> PPLAN_CD_05 = "料金プランコード"] |
| 4 | SET | `op_pack_kousei_list = svcFormBean.getDataBeanArray(KKW02519SFConst.EKK2071B101CBSMSG1List)` // Get discount service composition [-> EKK2071B101CBSMSG1List = "割引サービス構成一覧照会詳細(割引タイプコード)"] |
| 5 | SET | `pack_op_svc_kei_list = svcFormBean.getDataBeanArray(KKW02519SFConst.PACK_OP_SVC_KEI_LIST)` // Get package option list [-> PACK_OP_SVC_KEI_LIST = "パッケージ判定用オプションサービス契約一覧照会リスト"] |
| 6 | CALL | `unyo_ymd = JCCWebCommon.getOpeDate(this, null)` // Get current operation date |
| 7 | SET | `pack_mirai_flg = svcFormBean.sendMessageString(KKW02519SFConst.PACK_MIRAI_FLG, X31CWebConst.DATABEAN_GET_VALUE)` // [-> PACK_MIRAI_FLG = "未来パック存在フラグ"] Get future package flag |

##### Block 3.6.1 — IF: pack_mirai_flg == "1" (Future package exists) (L572-578)

> `"1"` means a future package exists. Turn on the message flag.

| # | Type | Code |
|---|------|------|
| 1 | SET | `if (pack_mirai_flg != null && !"".equals(pack_mirai_flg))` |
| 2 | SET | `if ("1".equals(pack_mirai_flg))` // Future package exists |
| 3 | SET | `pack_mirai_msg_flg = true` // Turn on message flag |

##### Block 3.6.2 — Loop: op_pack_kousei_list (L580-604)

> Iterate over package composition items to check if any option service has the same pricing plan code as the modified option and has a termination date after the current operation date.

| # | Type | Code |
|---|------|------|
| 1 | SET | `outside: for (int i = 0; i < op_pack_kousei_list.getCount(); i++)` // outer loop |
| 2 | SET | `opPackKouseiInfo = op_pack_kousei_list.getDataBean(i)` |
| 3 | SET | `kouseiOpPPlanCd = opPackKouseiInfo.sendMessageString(KKW02519SFConst.PPLAN_CD17, X31CWebConst.DATABEAN_GET_VALUE)` // [-> PPLAN_CD17 = "料金プランコード"] |
| 4 | SET | `if (kouseiOpPPlanCd.equals(opPplanCd))` // Option composes the package |
| 5 | SET | `if (useEndYmd.compareTo(unyo_ymd) > 0)` // Termination date is in the future |
| 6 | SET | `pack_mirai_msg_flg = true` // Turn on message flag |
| 7 | EXEC | `break outside` // Exit outer loop |

##### Block 3.6.3 — Loop: pack_op_svc_kei_list (L607-645)

> Iterate over other option services in the package and cross-check their pricing plan codes and contract status/date ranges.

| # | Type | Code |
|---|------|------|
| 1 | SET | `for (int cnt = 0; cnt < pack_op_svc_kei_list.getCount(); cnt++)` // outer loop |
| 2 | SET | `svcKeiInfo = pack_op_svc_kei_list.getDataBean(cnt)` |
| 3 | SET | `list_opPplanCd = svcKeiInfo.sendMessageString(KKW02519SFConst.PPLAN_CD_16, X31CWebConst.DATABEAN_GET_VALUE)` // Other option's pricing plan [-> PPLAN_CD_16 = "料金プランコード"] |
| 4 | SET | `list_opSvcKeiState = svcKeiInfo.sendMessageString(KKW02519SFConst.OP_SVC_KEI_STAT_16, X31CWebConst.DATABEAN_GET_VALUE)` // Other option's contract status [-> OP_SVC_KEI_STAT_16 = "オプションサービス契約ステータス"] |
| 5 | SET | `list_op_svc_sta_dtm = svcKeiInfo.sendMessageString(KKW02519SFConst.USE_STA_YMD_16, X31CWebConst.DATABEAN_GET_VALUE)` // Other option's start date [-> USE_STA_YMD_16 = "利用開始日"] |
| 6 | SET | `list_op_svc_end_dtm = svcKeiInfo.sendMessageString(KKW02519SFConst.OPSVC_END_RSV_DTM_16, X31CWebConst.DATABEAN_GET_VALUE)` // Other option's end date [-> OPSVC_END_RSV_DTM_16 = "利用終了予定日"] |
| 7 | SET | `for (int j = 0; j < op_pack_kousei_list.getCount(); j++)` // inner loop |
| 8 | SET | `opPackKouseiInfo1 = op_pack_kousei_list.getDataBean(j)` |
| 9 | SET | `kouseiOpPPlanCd1 = opPackKouseiInfo1.sendMessageString(KKW02519SFConst.PPLAN_CD17, X31CWebConst.DATABEAN_GET_VALUE)` |
| 10 | SET | `if (kouseiOpPPlanCd1.equals(list_opPplanCd))` // Same pricing plan |
| 11 | SET | `if (!"910".equals(list_opSvcKeiState) && !"920".equals(list_opSvcKeiState))` // Status is NOT "910" (Cancellation completed/キャンセル済) or "920" (Terminated/解約済み) |
| 12 | SET | `if (list_op_svc_sta_dtm.compareTo(unyo_ymd) > 0 || list_op_svc_end_dtm.compareTo(unyo_ymd) > 0)` // Start date or end date is in the future |
| 13 | SET | `pack_mirai_msg_flg = true` // Overlap detected |
| 14 | EXEC | `break` // Break inner loop |

##### Block 3.6.4 — Message display (L647-650)

> If any future overlap was detected, display the warning message.

| # | Type | Code |
|---|------|------|
| 1 | SET | `if (pack_mirai_msg_flg)` // Message flag set |
| 2 | CALL | `JCCWebCommon.setMessageInfo(this, JPCOnlineMessageConstant.EKBE130_KW)` // Warning: future package overlap |

#### Block 3.7 — Otoku (discount) check (L653-700)

> Check the discount check error flag. If an error was detected, determine the discount service type and display the appropriate warning message.

| # | Type | Code |
|---|------|------|
| 1 | SET | `otoku_chk_err_flg = svcFormBean.sendMessageString(KKW02519SFConst.OTOKU_CHK_ERR_FLG, X31CWebConst.DATABEAN_GET_VALUE)` // [-> OTOKU_CHK_ERR_FLG = "お得チェックエラーフラグ"] |
| 2 | SET | `otoku_chk_wrib_svc_cd = svcFormBean.sendMessageString(KKW02519SFConst.OTOKU_WRIB_SVC_CD, X31CWebConst.DATABEAN_GET_VALUE)` // [-> OTOKU_WRIB_SVC_CD = "お得チェック割引サービスコード"] |
| 3 | SET | `otoku_chk_err_char = ""` // Initialize error text |
| 4 | SET | `if (otoku_chk_err_flg != null && !"".equals(otoku_chk_err_flg))` // Check if error flag is set |
| 5 | SET | `if ("1".equals(otoku_chk_err_flg))` // [-> OTOKU_CHK_RESULT_ERR = 1] Discount check error detected |
| 6 | SET | `if ("W00000007".equals(otoku_chk_wrib_svc_cd))` // [-> WRIB_SVC_CD_PACK3 = "W00000007"] eo光電話パック3 |
| 7 | SET | `otoku_chk_err_char = "eo光電話パック３"` |
| 8 | SET | `else if ("W00000008".equals(otoku_chk_wrib_svc_cd))` // [-> WRIB_SVC_CD_PACK7 = "W00000008"] eo光電話パック7 |
| 9 | SET | `otoku_chk_err_char = "eo光電話パック７"` |
| 10 | SET | `else if ("W00000023".equals(otoku_chk_wrib_svc_cd))` // あんしん電話パック |
| 11 | SET | `otoku_chk_err_char = "あんしん電話パック"` |
| 12 | SET | `else` // [OM-2020-0001366] Single service |
| 13 | SET | `otoku_chk_err_char = "単品でお申し込みいただいていた方"` |
| 14 | SET | `str = {"", otoku_chk_err_char}` |
| 15 | CALL | `JCCWebCommon.setMessageInfo(this, "EKBE131-KW", str)` // Warning: discount check error |

#### Block 3.8 — Final cancellation message and return (L702-710)

> Display the standard cancellation confirmation message and log the DataBean state before returning true.

| # | Type | Code |
|---|------|------|
| 1 | SET | `str = {"電話オプションサービス契約の解約"}` // "Phone option service contract cancellation" |
| 2 | CALL | `JCCWebCommon.setMessageInfo(this, JPCOnlineMessageConstant.EKB0370__I, str)` |
| 3 | EXEC | `JSYwebLog.println(JSYwebLog.DataBean_Dump, getClass(), dumpDatabean(), null, null, null)` // Log DataBean dump |
| 4 | RETURN | `return true` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `tranDiv` | Field | Processing division — determines whether the operation is a modification (変更) or cancellation (解約) |
| `OP_TRAN_DIV_CHGE` | Constant | Processing division value for contract modification (変更) |
| `useEndYmd` | Field | Termination date as a continuous string (e.g., "20260628") — used for date comparisons |
| `useEndYmdDate` | Field | Termination date in display format (e.g., "2026/06/28") |
| `opCd` | Field | Option service code — identifies the type of option service (e.g., "B025"=Caller ID display, "B135"=Sure Call, "0160"=Transfer phone, "0180"=Caller ID display) |
| `sbopSvcKeiNo` | Field | Sub-option service contract number — the internal ID of a child/sub-option contract |
| `sbopSvcKeiStat` | Field | Sub-option service contract status — "100"=Contract completed (契約済), "030"=Suspended (休止中), "210"=Cancelled (中断中), "910"=Cancellation completed (キャンセル済), "920"=Terminated (解約済み) |
| `opPplanCd` | Field | Pricing plan code — identifies the billing plan for an option service |
| `kouseiOpPPlanCd` | Field | Composition pricing plan code — the pricing plan code of a package composition item |
| `list_opPplanCd` | Field | Other option service's pricing plan code — used for cross-package matching |
| `list_opSvcKeiState` | Field | Other option's contract status code (910=Cancelled, 920=Terminated) |
| `list_op_svc_sta_dtm` | Field | Other option's service start date — used for overlap detection |
| `list_op_svc_end_dtm` | Field | Other option's planned end date — used for overlap detection |
| `unyo_ymd` | Field | Operation date — current business date retrieved from system |
| `pack_mirai_msg_flg` | Field | Future package message flag — set to true when a future date overlap is detected, triggering a warning message |
| `pack_mirai_flg` | Field | Future package existence flag — "1" means a future package exists |
| `otoku_chk_err_flg` | Field | Discount check error flag — "1" means a discount check error was detected |
| `otoku_chk_wrib_svc_cd` | Field | Discount check discount service code — identifies which discount package is involved |
| `OTOKU_CHK_ERR_FLG` | Constant | "お得チェックエラーフラグ" — discount check error flag DataBean key |
| `OTOKU_WRIB_SVC_CD` | Constant | "お得チェック割引サービスコード" — discount check discount service code DataBean key |
| `TEL_OP_SVC_KEI_LIST` | Constant | "電話オプションサービス契約情報" — phone option service contract info DataBean key |
| `SBOP_SVC_KEI_LIST` | Constant | "サブオプションサービス契約一覧照会リスト" — sub-option service contract confirmation list |
| `PACK_OP_SVC_KEI_LIST` | Constant | "パッケージ判定用オプションサービス契約一覧照会リスト" — package-determination option service contract list |
| `OP_SVC_KEI_LIST` | Constant | "オプションサービス契約一覧照会リスト" — option service contract confirmation list |
| `EKK2071B101CBSMSG1List` | Constant | "割引サービス構成一覧照会詳細(割引タイプコード)" — discount service composition details |
| `USE_TW_STIAM_01` | Constant | "電話料指定額" — call allowance entered by user |
| `UPD_TW_STIAM` | Constant | "更新用通話指定額" — updated call allowance for the form |
| `USE_END_YMD_YEAR_01` | Constant | "利用終了日（年）" — termination year field |
| `USE_END_YMD_MON_01` | Constant | "利用終了日（月）" — termination month field |
| `USE_END_YMD_DAY_01` | Constant | "利用終了日（日）" — termination day field |
| `OTOKU_CHK_RESULT_OK` | Constant | `0` — discount check result: OK |
| `OTOKU_CHK_RESULT_ERR` | Constant | `1` — discount check result: error |
| `WRIB_SVC_CD_PACK3` | Constant | "W00000007" — eo光電話パック3 discount service code |
| `WRIB_SVC_CD_PACK7` | Constant | "W00000008" — eo光電話パック7 discount service code |
| OP_SVC_CD_VALUE_0160 | Constant | "0160" — Transfer phone (転送電話) service code |
| OP_SVC_CD_VALUE_0180 | Constant | "0180" — Caller ID display (発信者番号表示) service code |
| SCREEN_ID_KKW02520 | Constant | "KKW02520" — Next screen ID (update completion screen) |
| SCREEN_NAME_KKW02520 | Constant | "電話オプションサービス契約更新完了" — Next screen name |
| `kksv0516Execute` | Method | Phone option service contract update-modification service execution (変更処理) |
| `kksv0370Execute` | Method | Phone option service contract update-cancellation service execution (解約処理) |
| `isDlsCheckHsnshNoDsp` | Method | Check if Caller ID display can be released (発信者番号表示解約可否判定) |
| `isDlsCheckAnsHcs` | Method | Check if Sure Call can be released (あんしん着信解約可否判定) |
| B025 | Value | Caller ID display service (発信者番号表示) — cancelling this while Sure Call is registered triggers validation |
| B135 | Value | Sure Call service (あんしん着信) — cancelling this while Caller ID display is active triggers validation |
| 転送電話 | Value | Transfer phone — a phone option service that forwards calls |
| eo光電話パック3 | Business term | eo Fiber Phone Pack 3 — a bundled service package |
| eo光電話パック7 | Business term | eo Fiber Phone Pack 7 — a bundled service package |
| あんしん電話パック | Business term | Sure Call Phone Pack — a bundled phone package with Sure Call service |
| 単品でお申し込みいただいていた方 | Business term | Customers who previously subscribed to a single service — the fallback discount error message |
| KKW02519 | Screen | Phone Option Service Contract Update screen (電話オプションサービス契約更新) |
| KKW02520 | Screen | Phone Option Service Contract Update Completion screen (電話オプションサービス契約更新完了) |
| ANK-3754 | Change request | TOBRA migration support — release validation between Caller ID display and Sure Call services |
| FTTH | Business term | Fiber To The Home — fiber-optic internet service (referenced in screen name context) |
| SOD | Acronym | Service Order Data — telecom order fulfillment entity |
| DATA_BEAN_GET_VALUE | Constant | "DataBeanGetValue" — flag to retrieve a value from a DataBean |
| DATA_BEAN_SET_VALUE | Constant | "DataBeanSetValue" — flag to set a value in a DataBean |