# Business Logic — KKW00147SFLogic.checkSVData() [197 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `eo.web.webview.KKW00147SF.KKW00147SFLogic` |
| Layer | Service / Logic (webview layer — business validation logic) |
| Module | `KKW00147SF` (Package: `eo.web.webview.KKW00147SF`) |

## 1. Role

### KKW00147SFLogic.checkSVData()

This method serves as the **central server-side data validation entry point** for the KKW00147SF screen, which handles telecom service migration operations in the K-Opticom fiber-to-the-home (FTTH) customer portal. It performs **input validation and business rule enforcement** on the service form data before the form is submitted for processing, ensuring data integrity and compliance with domain-specific constraints. The method handles **four distinct migration types** identified by the `ido_div` discriminant: **phone number info change** (番号情報変更), **VA plug-in selection** (VAプラグイン選択), **user name kana validation** (利用者名カナ), and **port number selection** (ポート番号選択). It implements the **guard-clause design pattern**, collecting all validation errors into a single `errorExists` boolean flag rather than returning early, thereby allowing the UI to display a complete set of errors to the operator at once. The method is called as part of the form transition flow (`cfmTran`), acting as a shared validation utility within the KKW00147SF module that processes changes to fiber-optic telecommunications service contracts, including number additions, number changes, and information modifications.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["checkSVData()"])

    START --> GET_BEAN["Get svcFormBean from getServiceFormBean()"]
    GET_BEAN --> INIT["errorExists = false<br/>user_kana = undefined"]

    INIT --> CHECK_BANPO["ido_div equals IDO_DIV_BANPO_HENKO<br/>(00045 - Phone number info change)"]

    CHECK_BANPO -->|No| CHECK_VA["Check VA plug-in selection"]
    CHECK_BANPO -->|Yes| GET_NOW_BMP["Get nowBmp from current form bean<br/>KKW00147SFConst.BMP_UM"]
    GET_NOW_BMP --> GET_BEFORE_BMP["Get beforeBmp from stored data<br/>KKW00147SFConst.EKK0191A010DATA"]
    GET_BEFORE_BMP --> BEFORE_EQUALS_1{"beforeBmp equals 1?"}
    BEFORE_EQUALS_1 -->|Yes| NOW_EQUALS_0{"nowBmp equals 0?"}
    NOW_EQUALS_0 -->|Yes| SET_ERR_1["JCCWebCommon.setMessageInfo<br/>(EKB4210-KW)<br/>errorExists = true"]
    NOW_EQUALS_0 -->|No| CHECK_VA
    BEFORE_EQUALS_1 -->|No| CHECK_VA
    SET_ERR_1 --> CHECK_VA

    CHECK_VA --> VA_CONDITION{"ido_div equals<br/>IDO_DIV_BANGO_TSUIKA or<br/>IDO_DIV_DENWA_HENKO?"}
    VA_CONDITION -->|No| CHECK_KANA["Check user_kana field"]
    VA_CONDITION -->|Yes| GET_VA_NM["getPulldownNm(svcFormBean, VA_CHOICE)"]
    GET_VA_NM --> NOT_ROUTER{vaChoiceNm.trim equals<br/>TKNRT_TAKNKIKI_MODEL_NM?}
    NOT_ROUTER -->|No| CHECK_KANA
    NOT_ROUTER -->|Yes| GET_VA_CD["getPulldownCd(svcFormBean, VA_CHOICE)"]
    GET_VA_CD --> IS_NULL{"isNull(vaChoiceCd)?"}
    IS_NULL -->|Yes| SET_ERR_VA["JCCWebCommon.setMessageInfo<br/>(EKB1320-NW, VA)<br/>errorExists = true"]
    IS_NULL -->|No| CHECK_KANA
    SET_ERR_VA --> CHECK_KANA

    CHECK_KANA --> KANA_CONDITION{"ido_div equals<br/>BANGO_TSUIKA or DENWA_HENKO or BANPO_HENKO?"}
    KANA_CONDITION -->|No| CHECK_PORT["Check port number selection"]
    KANA_CONDITION -->|Yes| GET_USER_KANA["Get user_kana from form bean"]
    GET_USER_KANA --> CONVERT["JPCConvertString.convFullToHalfByKata<br/>(convert full-width katakana to half-width)"]
    CONVERT --> KANA_LENGTH{"user_kana.length > 36?"}
    KANA_LENGTH -->|Yes| SET_ERR_KANA["JCCWebCommon.setMessageInfo<br/>(EKB0040-TW, user name kana)<br/>errorExists = true"]
    KANA_LENGTH -->|No| CHECK_PORT
    SET_ERR_KANA --> CHECK_PORT

    CHECK_PORT --> PORT_CONDITION{"ido_div equals<br/>IDO_DIV_BANGO_TSUIKA?"}
    PORT_CONDITION -->|No| CHECK_ONU["Check ONU exchange work"]
    PORT_CONDITION -->|Yes| GET_PORT_BEAN["Get port number bean from form"]
    GET_PORT_BEAN --> PORT_EXISTS{"bean != null?"}
    PORT_EXISTS -->|Yes| GET_PORT_INDEX["Get portChoiceIndex from bean"]
    GET_PORT_INDEX --> PORT_VALID{"portChoiceIndex not null<br/>and not 0?"}
    PORT_VALID -->|Yes| SET_PORT_EXISTS["portChoiceExists = true"]
    PORT_VALID -->|No| PORT_NO_SELECT
    PORT_EXISTS -->|No| PORT_NO_SELECT
    SET_PORT_EXISTS --> PORT_CHECK{"!portChoiceExists?"}
    PORT_NO_SELECT --> PORT_CHECK
    PORT_CHECK -->|Yes| SET_ERR_PORT["JCCWebCommon.setMessageInfo<br/>(EKB1320-NW, port number)<br/>errorExists = true"]
    PORT_CHECK -->|No| CHECK_ONU
    SET_ERR_PORT --> CHECK_ONU

    CHECK_ONU --> ONU_CHECK{"onuKokanKojiFlg equals 1<br/>AND KojikahikojiakNo not blank?"}
    ONU_CHECK -->|Yes| SET_ERR_ONU["JCCWebCommon.setMessageInfo<br/>(EKB1040-JW, ONU exchange)<br/>errorExists = true"]
    ONU_CHECK -->|No| RETURN_VAL
    SET_ERR_ONU --> RETURN_VAL["Return !errorExists"]

    RETURN_VAL --> END(["End"])
```

**Constant Resolution Notes:**
- `IDO_DIV_BANPO_HENKO = "00045"` (光電話・番号情報変更 — Fiber phone, number info change)
- `IDO_DIV_BANGO_TSUIKA = "00041"` (光電話・番号追加 — Fiber phone, number addition)
- `IDO_DIV_DENWA_HENKO = "00048"` (光電話・電話番号情報変更 — Fiber phone, telephone number info change)
- `TKNRT_TAKNKIKI_MODEL_NM = "eo光多機能ルーター"` (eo light multi-functional router)

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| - | (none) | - | This method takes no explicit parameters. All input data is accessed via the form bean obtained from the service context. |
| - | `ido_div` | `String` (instance field) | Migration type discriminator — indicates the specific service migration operation being performed. Possible values include `"00041"` (number addition), `"00042"` (number change), `"00045"` (number info change), `"00048"` (telephone number info change). Controls which validation branches are activated. |
| - | `svcFormBean` | `X31SDataBeanAccess` (retrieved via `getServiceFormBean()`) | The current form bean holding all user-input data for the service migration screen. Accessed via `getDataBeanArray()`, `getDataBean()`, and `sendMessageString()` calls to extract field values. |

## 4. CRUD Operations / Called Services

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

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `KKW00147SFLogic.getServiceFormBean` | - | - | Retrieves the form bean for the current screen context |
| R | `OneStopDataBeanAccess.getDataBeanArray` | - | - | Reads phone presence (BMP_UM) from current form bean |
| R | `OneStopDataBeanAccess.getDataBeanArray` | - | - | Reads stored/former phone presence (beforeBmp) from `EKK0191A010DATA` bean array |
| R | `OneStopDataBeanAccess.getDataBean` | - | - | Gets specific data bean element from the bean array |
| R | `OneStopDataBeanAccess.sendMessageString` | - | - | Gets field values from form beans (BMP_UM, INDEX_01, BMP_UM_06, USER_KANA, ONU_KOKAN_KOJI_FLG, ONU_KOKAN_KOJIAK_NO) |
| R | `KKW00147SFLogic.getPulldownNm` | - | - | Gets display name from VA (Virtual Access?) pulldown selection |
| R | `KKW00147SFLogic.getPulldownCd` | - | - | Gets the selected code value from VA pulldown selection |
| - | `KKW00147SFLogic.isNull` | - | - | Checks if a string value is null or blank |
| - | `JPCConvertString.convFullToHalfByKata` | - | - | Converts full-width katakana characters to half-width (Japanese character normalization) |
| - | `JCCWebCommon.setMessageInfo` | - | - | Sets error message to display on the form |
| - | `JKKStringUtil.isNullBlank` | - | - | Checks if a string is null or empty |

This method does not perform any Create, Update, or Delete operations on databases. It is a **pure validation/read method** that reads from the form bean and compares against business rules, then sets error messages.

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | `KKW00147SFLogic.cfmTran()` | `cfmTran()` → `checkSVData()` | `setMessageInfo [R] EKB4210-KW, EKB1320-NW, EKB0040-TW, EKB1040-JW` |

**Note:** The direct caller is `KKW00147SFLogic.cfmTran()`, which handles the form transition for the KKW00147SF screen. No intermediate screens or CBS layers were found in the 8-hop caller graph. This method is called exclusively from the same class's form transition method.

The terminal operations reachable from this method consist entirely of error message setting (`setMessageInfo`) calls — there are no database writes or service component calls that produce CRUD side effects. The error message codes are:
- `EKB4210-KW` — Phone presence status invalid change detected
- `EKB1320-NW` — Required selection item not chosen (VA or port number)
- `EKB0040-TW` — Field value exceeds maximum character length (user name kana)
- `EKB1040-JW` — ONU exchange work conflict (work in progress)

## 6. Per-Branch Detail Blocks

**Block 1** — [IF] `(ido_div.equals(IDO_DIV_BANPO_HENKO))` [IDO_DIV_BANPO_HENKO="00045"] (L2217)
> Phone number info change validation: checks if phone presence (BMP) status changed from "present" (1) to "absent" (0), which is an invalid transition.

| # | Type | Code |
|---|------|------|
| 1 | SET | `nowBmp` = uninitialized |
| 2 | SET | `beforeBmp` = uninitialized |
| 3 | SET | `beanArray` = uninitialized |
| 4 | SET | `bean` = uninitialized |
| 5 | CALL | `getServiceFormBean()` → `svcFormBean` |
| 6 | SET | `errorExists = false` |

**Block 1.1** — [CALL] `Get nowBmp from current form bean` (L2231)
> Retrieves the current phone presence status from the active form.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `svcFormBean.getDataBeanArray(KKW00147SFConst.BMP_UM)` |
| 2 | EXEC | `.getDataBean(0)` → `bean` |
| 3 | EXEC | `bean.sendMessageString(KKW00147SFConst.CD_DIV_LIST_01, X31CWebConst.DATABEAN_GET_VALUE, Integer.parseInt(bean.sendMessageString(KKW00147SFConst.INDEX_01, X31CWebConst.DATABEAN_GET_VALUE)))` → `nowBmp` |

**Block 1.2** — [CALL] `Get beforeBmp from stored data` (L2235)
> Retrieves the phone presence status before the change from stored data.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `svcFormBean.getDataBeanArray(KKW00147SFConst.EKK0191A010DATA)` → `beanArray` |
| 2 | EXEC | `beanArray.getDataBean(0)` → `bean` |
| 3 | EXEC | `bean.sendMessageString(KKW00147SFConst.BMP_UM_06, X31CWebConst.DATABEAN_GET_VALUE)` → `beforeBmp` |

**Block 1.3** — [IF] `(beforeBmp.equals("1"))` (L2239)
> The phone presence status before the change was "present" (1). Check if it is being changed to "absent".

| # | Type | Code |
|---|------|------|
| 1 | SET | `beforeBmp` holds previous phone presence status ("1" = present, "0" = absent) |

**Block 1.3.1** — [IF] `(nowBmp.equals("0"))` (L2241)
> The phone presence status after change is "absent" (0), while before it was "present" (1). This is an invalid transition (error EKB4210-KW).

| # | Type | Code |
|---|------|------|
| 1 | CALL | `JCCWebCommon.setMessageInfo(this, "EKB4210-KW")` |
| 2 | SET | `errorExists = true` |

**Block 2** — [IF] `(ido_div.equals(IDO_DIV_BANGO_TSUIKA) || ido_div.equals(IDO_DIV_DENWA_HENKO))` [IDO_DIV_BANGO_TSUIKA="00041", IDO_DIV_DENWA_HENKO="00048"] (L2288)
> VA (Virtual Access) plug-in selection validation. For number addition and telephone number info change operations, validates that a valid VA device is selected when the selected device is not the "eo light multi-functional router" (eo光多機能ルーター), since the router is a special case that doesn't require VA selection.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `getPulldownNm(svcFormBean, KKW00147SFConst.VA_CHOICE)` → `vaChoiceNm` |
| 2 | EXEC | `vaChoiceNm.trim()` |

**Block 2.1** — [IF] `(!TKNRT_TAKNKIKI_MODEL_NM.equals(vaChoiceNm.trim()))` [TKNRT_TAKNKIKI_MODEL_NM="eo光多機能ルーター"] (L2316)
> The selected VA device is NOT the eo light multi-functional router, so a valid VA selection is required.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `getPulldownCd(svcFormBean, KKW00147SFConst.VA_CHOICE)` → `vaChoiceCd` |

**Block 2.1.1** — [IF] `(isNull(vaChoiceCd))` (L2318)
> The VA code is null/blank, meaning no VA item was selected.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `JCCWebCommon.setMessageInfo(this, "EKB1320-NW", new String[]{"VA"}, "va_choice")` |
| 2 | SET | `errorExists = true` |

**Block 3** — [IF] `(ido_div.equals(IDO_DIV_BANGO_TSUIKA) || ido_div.equals(IDO_DIV_DENWA_HENKO) || ido_div.equals(IDO_DIV_BANGO_HENKO))` [IDO_DIV_BANGO_TSUIKA="00041", IDO_DIV_DENWA_HENKO="00048", IDO_DIV_BANGO_HENKO="00042"] (L2333)
> User name kana validation: for number addition, telephone number info change, and number info change operations. The user name kana field must not exceed 36 characters after converting full-width katakana to half-width.

| # | Type | Code |
|---|------|------|
| 1 | SET | `user_kana` = uninitialized |

**Block 3.1** — [CALL] `Get user_kana from form bean` (L2337)
> Retrieves the user name kana field value from the form.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `svcFormBean.sendMessageString(KKW00147SFConst.USER_KANA, X31CWebConst.DATABEAN_GET_VALUE)` → `user_kana` |

**Block 3.2** — [IF] `(user_kana != null)` (L2340)

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `JPCConvertString.convFullToHalfByKata(user_kana)` → `user_kana` // converts full-width katakana to half-width |

**Block 3.2.1** — [IF] `(user_kana.length() > 36)` (L2347)
> The user name kana field exceeds the maximum allowed length of 36 characters after half-width conversion.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `JCCWebCommon.setMessageInfo(this, "EKB0040-TW", new String[]{"利用者名（カナ"),"1","36"},"user_kana")` |
| 2 | SET | `errorExists = true` |

**Block 4** — [IF] `(ido_div.equals(IDO_DIV_BANGO_TSUIKA))` [IDO_DIV_BANGO_TSUIKA="00041"] (L2353)
> Port number selection validation and ONU exchange work conflict check. For number addition operations, validates that a port number is selected and that there is no active ONU exchange work pending.

| # | Type | Code |
|---|------|------|
| 1 | SET | `bean` = null |
| 2 | SET | `portChoiceExists` = false |
| 3 | SET | `portChoiceIndex` = null |

**Block 4.1** — [CALL] `Get port number bean from form` (L2358)
> Retrieves the port number pulldown selection bean.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `svcFormBean.getDataBeanArray(KKW00147SFConst.PORT_NO)` |
| 2 | EXEC | `.getDataBean(0)` → `bean` |

**Block 4.2** — [IF] `(bean != null)` (L2360)

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `bean.sendMessageString(KKW00147SFConst.INDEX_01, X31CWebConst.DATABEAN_GET_VALUE)` → `portChoiceIndex` |

**Block 4.2.1** — [IF] `(portChoiceIndex != null)` (L2362)
> The port choice index exists.

**Block 4.2.1.1** — [IF] `(!"0".equals(portChoiceIndex))` (L2365)
> The selected port index is not 0 (the empty placeholder item), meaning a valid port number was selected.

| # | Type | Code |
|---|------|------|
| 1 | SET | `portChoiceExists = true` |

**Block 4.3** — [IF] `(!portChoiceExists)` (L2372)
> No port number was selected (bean was null, index was null, or index was 0).

| # | Type | Code |
|---|------|------|
| 1 | CALL | `JCCWebCommon.setMessageInfo(this, "EKB1320-NW", new String[]{"ポート番号"},"port_no")` |
| 2 | SET | `errorExists = true` |

**Block 4.4** — [IF] — ONU exchange work conflict check (ANK-4315-00-00) (L2380)
> After port number validation, also checks for ONU exchange work conflicts. If ONU exchange work is active (flag = "1") and there is a work item number in progress (new construction, plan change for reception substitution, or removal), the operation must be rejected.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `svcFormBean.sendMessageString(KKW00147SFConst.ONU_KOKAN_KOJI_FLG, X31CWebConst.DATABEAN_GET_VALUE)` → `onuKokanKojiFlg` // ONU exchange work status flag |
| 2 | EXEC | `svcFormBean.sendMessageString(KKW00147SFConst.ONU_KOKAN_KOJIAK_NO, X31CWebConst.DATABEAN_GET_VALUE)` → `KojikahikojiakNo` // ONU exchange work item number (in-progress work ticket) |

**Block 4.4.1** — [IF] `("1".equals(onuKokanKojiFlg) && !JKKStringUtil.isNullBlank(KojikahikojiakNo))` (L2385)
> ONU exchange work flag is active (1) and there is a work item number in progress (new construction, plan change, or removal).

| # | Type | Code |
|---|------|------|
| 1 | CALL | `JCCWebCommon.setMessageInfo(this, "EKB1040-JW", new String[]{"ONU交換工事","立ち上がる状態","登録は"},"port_no")` // "ONU exchange work", "in progress state", "registration is..." |
| 2 | SET | `errorExists = true` |

**Block 5** — [RETURN] (L2397)

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return !errorExists` // true if no errors, false if any validation failed |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `ido_div` | Field | Migration type discriminator — identifies the type of telecom service change operation being performed (number addition, number change, number info change, etc.) |
| `BMP_UM` | Field | Phone presence status — indicates whether a phone number is present ("1") or absent ("0") for the service contract |
| `VA_CHOICE` | Field | VA plug-in selection — the Virtual Access device model selected by the user from a pulldown menu |
| `VA_MODEL_CD` | Field | VA device model code — the selected VA device's product code |
| `PORT_NO` | Field | Port number — the port number selected for the service |
| `USER_KANA` | Field | User name (kana) — the customer's name in Japanese katakana characters |
| `ONU_KOKAN_KOJI_FLG` | Field | ONU exchange work flag — indicates whether ONU (Optical Network Unit) hardware exchange work is active ("1") or not |
| `ONU_KOKAN_KOJIAK_NO` | Field | ONU exchange work item number — the work ticket number for an in-progress ONU exchange operation (new construction, plan change, or removal) |
| `KOJIAK_NO` | Field | Work item number — a reference to an ongoing construction/maintenance work ticket |
| IDO_DIV_BANGO_TSUIKA | Constant | Migration type: 光電話・番号追加 — Fiber-optic telephone, number addition (value: "00041") |
| IDO_DIV_BANGO_HENKO | Constant | Migration type: 光電話・番号変更 — Fiber-optic telephone, number change (value: "00042") |
| IDO_DIV_BANPO_HENKO | Constant | Migration type: 光電話・番号情報変更 — Fiber-optic telephone, number info change (value: "00045") |
| IDO_DIV_DENWA_HENKO | Constant | Migration type: 光電話・電話番号情報変更 — Fiber-optic telephone, telephone number info change (value: "00048") |
| TKNRT_TAKNKIKI_MODEL_NM | Constant | eo light multi-functional router — the eo光多機能ルーター product model name, a special-case device that does not require VA selection |
| FTTH | Business term | Fiber To The Home — fiber-optic broadband internet service provided by K-Opticom |
| ONU | Acronym | Optical Network Unit — the fiber-optic termination device installed at the customer's premises |
| VA | Acronym | Virtual Access — a value-added telecom service/feature (contextually, a VA device/plug-in selection) |
| KKW00147SF | Module | The K-Opticom screen module for telecom service migration operations (変更/遷移) |
| `cfmTran()` | Method | Form transition method — the entry point that triggers validation and navigates between screen states |
| EKB4210-KW | Error code | Error: Phone presence status change detected (e.g., from present to absent) |
| EKB1320-NW | Error code | Error: Required selection item not chosen (VA or port number) |
| EKB0040-TW | Error code | Error: Field value exceeds maximum character length |
| EKB1040-JW | Error code | Error: ONU exchange work conflict — work item already in progress |
| `JPCConvertString.convFullToHalfByKata` | Method | Converts full-width Japanese katakana characters to half-width (normalization) |
| `getServiceFormBean()` | Method | Retrieves the current form bean containing all user input data |
| `EKK0191A010DATA` | Constant | Form bean identifier for storing pre-change data (before state snapshot) |
| `CD_DIV_LIST_01` | Constant | Column/division list identifier for pulldown data retrieval |
| `INDEX_01` | Constant | Index identifier for selecting the first element in a bean list |
