# Business Logic — KKW01031SF01DBean.storeModelData() [94 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `eo.web.webview.KKW01031SF.KKW01031SF01DBean` |
| Layer | Service Component / Common Component — Web-tier Data Binding Bean |
| Module | `KKW01031SF` (Package: `eo.web.webview.KKW01031SF`) |

## 1. Role

### KKW01031SF01DBean.storeModelData()

This method is a **field-based data binding router** for the `KKW01031SF` screen's data bean. Its business purpose is to accept a field name (`key`), a sub-property specifier (`subkey`), and a value (`in_value`), then dispatch that value to the correct strongly-typed property on the bean based on the field name. It handles the most frequently modified fields on the service contract movement screen: the system identifier (`SYSID`), service contract number (`サービス契約番号`), movement type (`異動区分`), movement reason code (`異動理由コード`), movement reason memo (`異動理由メモ`), application number (`申請番号`), and application detail number (`申請明細番号`).

The method implements a **routing/dispatch pattern**: each key maps to a distinct business entity field. For most fields, dispatching is a simple matter of checking `subkey` against the literal strings `"value"` or `"state"` — `"value"` triggers a setter on the data value, while `"state"` triggers a setter on a state/metadata field. For the `異動理由コード` (movement reason code) field, the method implements **delegation via list traversal**: it parses the key to extract an index, bounds-checks it against the `ido_rsn_cd_list`, and delegates to the `storeModelData` method of the corresponding `X33VDataTypeStringBean` item, enabling fine-grained editing of multi-item reason code entries.

In the larger system, this method serves as the **shared data persistence bridge** between the screen's presentation layer (HTML form data, AJAX payloads) and the typed data bean model. It is called internally from multiple places within `KKW01031SF01DBean` to reconstruct bean state during screen processing, and is also used during client-side save operations to push form field values into the server-side model.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["storeModelData key, subkey, in_value, isSetAsString"])
    START --> CHECK_NULL{key or subkey is null?}
    CHECK_NULL -->|Yes| RETURN_RET["Return early"]
    CHECK_NULL -->|No| FIND_SEP["Find slash in key: indexOf('/')"]
    FIND_SEP --> KEY_SYSID{key equals SYSID?}
    KEY_SYSID -->|Yes| SUB_SYSID{subkey equals value?}
    SUB_SYSID -->|Yes| SET_SVID["setSysid_value"]
    SUB_SYSID -->|No| SET_SVST["setSysid_state"]
    SET_SVID --> NEXT1{key equals service contract number?}
    SET_SVST --> NEXT1
    NEXT1 -->|Yes| SUB_SVC_VAL{subkey equals value?}
    SUB_SVC_VAL -->|Yes| SET_SVCV["setSvc_kei_no_value"]
    SUB_SVC_VAL -->|No| SET_SVCS["setSvc_kei_no_state"]
    SET_SVCV --> NEXT2{key equals movement type?}
    SET_SVCS --> NEXT2
    NEXT2 -->|Yes| SUB_IDO_VAL{subkey equals value?}
    SUB_IDO_VAL -->|Yes| SET_IDOV["setIdo_div_value"]
    SUB_IDO_VAL -->|No| SET_IDOS["setIdo_div_state"]
    SET_IDOV --> NEXT3{key equals movement reason code?}
    SET_IDOS --> NEXT3
    NEXT3 -->|Yes| SUB_IDO_RSN{subkey equals value?}
    SUB_IDO_RSN -->|Yes| SET_IRCV["setIdo_rsn_cd_value"]
    SUB_IDO_RSN -->|No| SET_IRCS["setIdo_rsn_cd_state"]
    SET_IRCV --> NEXT4{key equals movement reason memo?}
    SET_IRCS --> NEXT4
    NEXT4 -->|Yes| SUB_IRM_VAL{subkey equals value?}
    SUB_IRM_VAL -->|Yes| SET_IRMV["setIdo_rsn_memo_value"]
    SUB_IRM_VAL -->|No| SET_IRMS["setIdo_rsn_memo_state"]
    SET_IRMV --> NEXT5{key equals application number?}
    SET_IRMS --> NEXT5
    NEXT5 -->|Yes| SUB_MSN_VAL{subkey equals value?}
    SUB_MSN_VAL -->|Yes| SET_MSNV["setMskm_no_value"]
    SUB_MSN_VAL -->|No| SET_MSNS["setMskm_no_state"]
    SET_MSNV --> NEXT6{key equals application detail number?}
    SET_MSNS --> NEXT6
    NEXT6 -->|Yes| SUB_MSD_VAL{subkey equals value?}
    SUB_MSD_VAL -->|Yes| SET_MSDV["setMskm_dtl_no_value"]
    SUB_MSD_VAL -->|No| SET_MSDS["setMskm_dtl_no_state"]
    SET_MSDV --> END_N(["Return"])
    SET_MSDS --> END_N
    RETURN_RET --> END_N
```

> **Note:** The flowchart above uses English approximations for Japanese key strings to ensure Mermaid parser compatibility. The actual keys used in the source code are: `"SYSID"`, `"サービス契約番号"` (service contract number), `"異動区分"` (movement type), `"異動理由コード"` (movement reason code), `"異動理由メモ"` (movement reason memo), `"申請番号"` (application number), and `"申請明細番号"` (application detail number). Each key branches into `"value"` (set data) or `"state"` (set state/metadata).

**Processing description:**

1. **Null guard** — If `key` or `subkey` is `null`, the method returns immediately without modifying any state (early exit).
2. **Separator extraction** — The method locates the first `/` character in `key` (this is relevant for the `異動理由コード` branch where the key carries an index, e.g. `"異動理由コード/0"`).
3. **Key dispatch** — Seven mutually exclusive key values are checked in sequence. For each key, the `subkey` is checked against `"value"` and `"state"` (case-insensitive via `equalsIgnoreCase`). The `"value"` path sets the data value; the `"state"` path sets the state/metadata.
4. **List delegation** — For the `異動理由コード` key, the method extracts an index from the key string (after the `/`), validates it as a numeric value and within bounds of `ido_rsn_cd_list`, then delegates to `storeModelData(subkey, in_value)` on the corresponding `X33VDataTypeStringBean` item.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `key` | `String` | The field name that identifies which bean property to populate. Can be a simple field identifier (e.g., `"SYSID"`) or a compound key with index (e.g., `"異動理由コード/0"` for the first movement reason code entry). Determines which of the seven business fields the value applies to. |
| 2 | `subkey` | `String` | The sub-property specifier. When equal to `"value"` (case-insensitive), sets the actual data value of the field. When equal to `"state"`, sets the state/metadata flag for the field. Controls whether the operation is a write of business data or a write of UI state. |
| 3 | `in_value` | `Object` | The data to be stored. Cast to `String` before assignment to the target property. Carries the actual business value (e.g., system ID string, contract number, movement type code, reason code, memo text). |
| 4 | `isSetAsString` | `boolean` | When `true`, indicates that the value should be set as a String even on Long-type item Value properties. In the current `storeModelData` implementation, this parameter is accepted but not actively used — it is likely passed through during delegation to `X33VDataTypeStringBean.storeModelData`. |

**Instance fields read:**

| Field | Type | Description |
|-------|------|-------------|
| `ido_rsn_cd_list` | `ArrayList<?>` | List of reason code entry beans (`X33VDataTypeStringBean`). Read during the `異動理由コード` branch to validate index bounds and retrieve the target item bean for delegation. |

## 4. CRUD Operations / Called Services

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

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| - | `JKKAdEditCC.substring` | JKKAdEditCC | - | Calls `substring` in `JKKAdEditCC` |
| - | `JKKAdEdit.substring` | JKKAdEdit | - | Calls `substring` in `JKKAdEdit` |
| - | `JKKTelnoInfoAddMapperCC.substring` | JKKTelnoInfoAddMapperCC | - | Calls `substring` in `JKKTelnoInfoAddMapperCC` |
| - | `JDKejbStringEdit.substring` | JDKejbStringEdit | - | Calls `substring` in `JDKejbStringEdit` |
| - | `KKW01031SF01DBean.setIdo_div_state` | KKW01031SF01DBean | - | Calls `setIdo_div_state` in `KKW01031SF01DBean` |
| - | `KKW01031SF01DBean.setIdo_div_value` | KKW01031SF01DBean | - | Calls `setIdo_div_value` in `KKW01031SF01DBean` |
| - | `KKW01031SF01DBean.setIdo_rsn_memo_state` | KKW01031SF01DBean | - | Calls `setIdo_rsn_memo_state` in `KKW01031SF01DBean` |
| - | `KKW01031SF01DBean.setIdo_rsn_memo_value` | KKW01031SF01DBean | - | Calls `setIdo_rsn_memo_value` in `KKW01031SF01DBean` |
| - | `KKW01031SF01DBean.setMskm_dtl_no_state` | KKW01031SF01DBean | - | Calls `setMskm_dtl_no_state` in `KKW01031SF01DBean` |
| - | `KKW01031SF01DBean.setMskm_dtl_no_value` | KKW01031SF01DBean | - | Calls `setMskm_dtl_no_value` in `KKW01031SF01DBean` |
| - | `KKW01031SF01DBean.setMskm_no_state` | KKW01031SF01DBean | - | Calls `setMskm_no_state` in `KKW01031SF01DBean` |
| - | `KKW01031SF01DBean.setMskm_no_value` | KKW01031SF01DBean | - | Calls `setMskm_no_value` in `KKW01031SF01DBean` |
| - | `KKW01031SF01DBean.setSvc_kei_no_state` | KKW01031SF01DBean | - | Calls `setSvc_kei_no_state` in `KKW01031SF01DBean` |
| - | `KKW01031SF01DBean.setSvc_kei_no_value` | KKW01031SF01DBean | - | Calls `setSvc_kei_no_value` in `KKW01031SF01DBean` |
| - | `KKW01031SF01DBean.setSysid_state` | KKW01031SF01DBean | - | Calls `setSysid_state` in `KKW01031SF01DBean` |
| - | `KKW01031SF01DBean.setSysid_value` | KKW01031SF01DBean | - | Calls `setSysid_value` in `KKW01031SF01DBean` |
| - | `KKW01031SF01DBean.storeModelData` | KKW01031SF01DBean | - | Recursive self-call (delegation to item bean) |

This method performs **no direct database operations** (no C/R/U/D on entities or tables). It is a pure in-memory data binding utility. All called methods are internal bean setter methods (`setSysid_value`, `setSvc_kei_no_state`, etc.) or delegation calls to child bean `storeModelData` instances. The `substring` calls appearing in the pre-computed graph originate from other callers within the same class, not from `storeModelData` itself — `storeModelData` only calls `String.indexOf`, `Integer.valueOf`, `ArrayList.get`, and the setter methods listed above.

## 5. Dependency Trace

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

No screen/batch entry points found within 8 hops. Direct callers found: 2 methods.
Terminal operations from this method: `setMskm_dtl_no_state` [-], `setMskm_dtl_no_value` [-], `setMskm_no_state` [-], `setMskm_no_value` [-], `setIdo_rsn_memo_state` [-], `setIdo_rsn_memo_value` [-], `storeModelData` [-], `storeModelData` [-], `storeModelData` [-], `substring` [-], `substring` [-], `substring` [-], `substring` [-], `setIdo_div_state` [-], `setIdo_div_value` [-], `setSvc_kei_no_state` [-], `setSvc_kei_no_value` [-], `setSysid_state` [-], `setSysid_value` [-]

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Internal — KKW01031SF01DBean | `KKW01031SF01DBean.storeModelData(String, String, Object, boolean)` (self-call via delegation) | `setIdo_rsn_cd_value/setIdo_rsn_cd_state [U] in-memory bean property` |
| 2 | Internal — KKW01031SF01DBean | Same class, different overload or invocation site | `setSysid_value [U] in-memory SYSID` |
| 3 | Internal — KKW01031SF01DBean | Same class, different overload or invocation site | `setSvc_kei_no_value [U] in-memory service contract number` |

**Notes:**
- All callers are internal to `KKW01031SF01DBean`. The pre-computed graph reports 2 unique callers (both self-references within the same class), which corresponds to the multiple overloads and delegation calls visible in the source.
- The method has **no external database or SC terminal operations** — all terminal operations write to in-memory bean properties.
- No screen (KKSV*) or batch entry points were found within 8 hops of this method. It is a low-level utility method consumed by other methods within the same bean rather than an entry point itself.

## 6. Per-Branch Detail Blocks

**Block 1** — IF (null guard) `(key == null || subkey == null)` (L389)

> If either the field name or subkey is null, exit immediately. No state is modified. This is a defensive guard against null-pointer exceptions and invalid dispatch.

| # | Type | Code |
|---|------|------|
| 1 | CHECK | `if (key == null || subkey == null)` |
| 2 | RETURN | `return;` // Early exit if either parameter is null |

---

**Block 2** — SET (separator extraction) (L392)

> Extract the position of the first `/` character in `key`. This is used later in the `異動理由コード` branch to parse an index from a compound key string (e.g., `"異動理由コード/0"`).

| # | Type | Code |
|---|------|------|
| 1 | SET | `int separaterPoint = key.indexOf("/");` |

---

**Block 3** — IF-ELSE-IF-CHAIN (key dispatch) `(key.equals("SYSID"))` (L395)

> First branch: handle the SYSID (system ID) field. The key `"SYSID"` (300%5354%5349%44) is the item ID for the system identifier. The subkey determines whether to set the data value or the state/metadata property.

**Block 3.1** — IF `(subkey.equalsIgnoreCase("value"))` (L396)

> Set the SYSID value data property.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `setSysid_value((String)in_value);` // Cast and set SYSID data value |

---

**Block 3.2** — ELSE-IF `(subkey.equalsIgnoreCase("state"))` (L399)

> Set the SYSID state/metadata property.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `setSysid_state((String)in_value);` // Cast and set SYSID state/metadata |

---

**Block 4** — ELSE-IF `(key.equals("サービス契約番号"))` (L405)

> Second branch: handle the service contract number field. The key `"サービス契約番号"` (service contract number) maps to the `svc_kei_no` item ID.

**Block 4.1** — IF `(subkey.equalsIgnoreCase("value"))` (L406)

> Set the service contract number value.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `setSvc_kei_no_value((String)in_value);` // Cast and set service contract number data value |

---

**Block 4.2** — ELSE-IF `(subkey.equalsIgnoreCase("state"))` (L409)

> Set the service contract number state/metadata.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `setSvc_kei_no_state((String)in_value);` // Cast and set service contract number state |

---

**Block 5** — ELSE-IF `(key.equals("異動区分"))` (L415)

> Third branch: handle the movement type field. The key `"異動区分"` (movement type) maps to the `ido_div` item ID. Used to distinguish between different types of contract movements (e.g., transfer, cancellation, suspension).

**Block 5.1** — IF `(subkey.equalsIgnoreCase("value"))` (L416)

> Set the movement type value.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `setIdo_div_value((String)in_value);` // Cast and set movement type data value |

---

**Block 5.2** — ELSE-IF `(subkey.equalsIgnoreCase("state"))` (L419)

> Set the movement type state/metadata.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `setIdo_div_state((String)in_value);` // Cast and set movement type state |

---

**Block 6** — ELSE-IF `(key.equals("異動理由コード"))` (L424)

> Fourth branch: handle the movement reason code field. This is the most complex branch. The key `"異動理由コード"` (movement reason code) maps to the `ido_rsn_cd` item ID. The key is expected to carry an index suffix after a `/` separator (e.g., `"異動理由コード/0"`), and the method delegates to the corresponding `X33VDataTypeStringBean` item in the `ido_rsn_cd_list`.

**Block 6.1** — SET (key extraction) `(L426)`

> Extract the portion of the key after the first `/` character to obtain the index string.

| # | Type | Code |
|---|------|------|
| 1 | SET | `key = key.substring(separaterPoint + 1);` // Get portion after the first "/" from "異動理由コード/0" |

---

**Block 6.2** — SET (index variable initialization) `(L428)`

> Initialize the temporary index variable as `null` before attempting numeric parsing.

| # | Type | Code |
|---|------|------|
| 1 | SET | `Integer tmpIndexInt = null;` // Temporary variable for parsed index |

---

**Block 6.3** — TRY `(Integer.valueOf(key))` (L430)

> Attempt to parse the extracted key string as an integer. If successful, `tmpIndexInt` holds the valid index. If parsing fails, falls through to the catch block.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `tmpIndexInt = Integer.valueOf(key);` // Parse index from extracted key string |

---

**Block 6.4** — CATCH `(NumberFormatException e)` (L434)

> If the key is not a valid numeric string, set `tmpIndexInt` to `null`. This gracefully handles malformed index keys without throwing an exception.

| # | Type | Code |
|---|------|------|
| 1 | SET | `tmpIndexInt = null;` // Index value is not a numeric string, return null |

---

**Block 6.5** — IF `(tmpIndexInt != null)` (L437)

> If the index was successfully parsed as a number, proceed with list access.

**Block 6.5.1** — SET (index extraction) `(L438)`

> Convert the `Integer` to a primitive `int` for comparison.

| # | Type | Code |
|---|------|------|
| 1 | SET | `int tmpIndex = tmpIndexInt.intValue();` // Unbox Integer to int |

---

**Block 6.5.2** — IF `(tmpIndex >= 0 && tmpIndex < ido_rsn_cd_list.size())` (L439)

> Validate that the parsed index is within the bounds of the reason code list.

**Block 6.5.2.1** — EXEC (delegation to item bean) `(L440)`

> Retrieve the item bean at the given index, cast it to `X33VDataTypeStringBean`, and delegate the `storeModelData` call to it. This allows nested data binding on individual list items. The comment explains that depending on the field definition type, the list may contain one of `X33VDataTypeStringBean`, `X33VDataTypeLongBean`, or `X33VDataTypeBooleanBean`, and for `X33VDataTypeLongBean` the `subkey` and `isSetAsString` flags are passed as parameters.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `((X33VDataTypeStringBean)ido_rsn_cd_list.get(tmpIndex)).storeModelData(subkey, in_value);` // Delegate to item bean |
| 2 | COMMENT | `// Cast section — X33VDataTypeStringBean, X33VDataTypeLongBean, or X33VDataTypeBooleanBean depending on field type` |
| 3 | COMMENT | `// X33VDataTypeLongBean passes subkey and isSetAsString flag as parameters` |

---

**Block 7** — ELSE-IF `(key.equals("異動理由メモ"))` (L449)

> Fifth branch: handle the movement reason memo field. The key `"異動理由メモ"` (movement reason memo) maps to the `ido_rsn_memo` item ID. This is a simple string field that stores free-text notes about the reason for the contract movement.

**Block 7.1** — IF `(subkey.equalsIgnoreCase("value"))` (L450)

> Set the movement reason memo value.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `setIdo_rsn_memo_value((String)in_value);` // Cast and set movement reason memo data value |

---

**Block 7.2** — ELSE-IF `(subkey.equalsIgnoreCase("state"))` (L453)

> Set the movement reason memo state/metadata.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `setIdo_rsn_memo_state((String)in_value);` // Cast and set movement reason memo state |

---

**Block 8** — ELSE-IF `(key.equals("申請番号"))` (L459)

> Sixth branch: handle the application number field. The key `"申請番号"` (application number) maps to the `mskm_no` item ID. This identifies the overall application/claim number.

**Block 8.1** — IF `(subkey.equalsIgnoreCase("value"))` (L460)

> Set the application number value.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `setMskm_no_value((String)in_value);` // Cast and set application number data value |

---

**Block 8.2** — ELSE-IF `(subkey.equalsIgnoreCase("state"))` (L463)

> Set the application number state/metadata.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `setMskm_no_state((String)in_value);` // Cast and set application number state |

---

**Block 9** — ELSE-IF `(key.equals("申請明細番号"))` (L469)

> Seventh and final branch: handle the application detail number field. The key `"申請明細番号"` (application detail number) maps to the `mskm_dtl_no` item ID. This identifies a line item within an application.

**Block 9.1** — IF `(subkey.equalsIgnoreCase("value"))` (L470)

> Set the application detail number value.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `setMskm_dtl_no_value((String)in_value);` // Cast and set application detail number data value |

---

**Block 9.2** — ELSE-IF `(subkey.equalsIgnoreCase("state"))` (L473)

> Set the application detail number state/metadata.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `setMskm_dtl_no_state((String)in_value);` // Cast and set application detail number state |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `SYSID` | Field | System Identifier — unique identifier for the system record in the service contract management data model |
| `サービス契約番号` | Field | Service Contract Number — the primary key identifier for a telecom service contract line item |
| `異動区分` | Field | Movement Type — classification of the type of contract change (e.g., transfer, cancellation, suspension, addition). Maps to internal item ID `ido_div`. |
| `異動理由コード` | Field | Movement Reason Code — codes explaining why a contract movement was performed. Stored as a list (`ido_rsn_cd_list`) of typed beans, supporting multiple reason code entries per movement. Maps to internal item ID `ido_rsn_cd`. |
| `異動理由メモ` | Field | Movement Reason Memo — free-text notes accompanying a movement reason code. Maps to internal item ID `ido_rsn_memo`. |
| `申請番号` | Field | Application Number — the primary identifier for a service application/claim. Maps to internal item ID `mskm_no`. |
| `申請明細番号` | Field | Application Detail Number — line-item identifier within an application, identifying a specific chargeable unit. Maps to internal item ID `mskm_dtl_no`. |
| `value` | Subkey | Sub-property specifier indicating that the data value of a field should be set |
| `state` | Subkey | Sub-property specifier indicating that the state/metadata flag of a field should be set (typically used for UI state tracking such as "modified," "validated," or "locked") |
| `isSetAsString` | Parameter | Flag indicating whether a value should be stored as a String even on Long-type item Value properties. Used in delegation to child typed beans. |
| `X33VDataTypeStringBean` | Class | Typed data bean for string-type form fields. Supports `storeModelData` delegation for nested data binding on list items. |
| `X33VDataTypeLongBean` | Class | Typed data bean for Long-type form fields. Receives `subkey` and `isSetAsString` parameters during delegation. |
| `X33VDataTypeBooleanBean` | Class | Typed data bean for Boolean-type form fields. |
| `ido_rsn_cd_list` | Field | ArrayList of reason code entry beans. Used to store and manage multiple movement reason code entries in the service contract movement screen. |
| `storeModelData` | Method | Field-based data binding router that dispatches incoming key/subkey/value triples to the correct typed property on the bean. |
| KKSV* | Screen | Screen class naming convention (e.g., KKSV0004) — the presentation layer classes that invoke this data bean |
| KKW01031SF | Module | Service contract movement screen module — the screen handling contract movement operations (異動処理) in the telecom service management system |
