# KKW03201SFLogic

## Purpose

`KKW03201SFLogic` is the business logic class for the **050 Number Issuance Registration** feature in the K-Opticom customer contract system. It handles the complete workflow of allowing an operator to search for available telephone numbers (050 VoIP numbers), review search results, confirm registration details, and finalize the issuance of a new 050 number service contract. This class serves as the central orchestrator coordinating UI action dispatch, data mapping, backend service invocation, and screen flow navigation across three distinct screens (KKW03201 → KKW03202 → KKW03203).

## Design

This class follows the **Front Controller / Screen Logic** pattern common in the Fujitsu Futurity web framework. It acts as a **screen-level orchestrator** that:

1. **Dispatches user actions** — Each public method (`actionInit`, `actionCfm`, `actionFix`, etc.) corresponds to a specific button or link click on a JSP page.
2. **Orchestrates backend services** — Uses DB mappers to populate input maps, calls `invokeService()` to execute backend business logic, then maps results back to the service form DataBean.
3. **Manages screen navigation** — Sets `NEXT_SCREEN_ID` and `NEXT_SCREEN_NAME` in the shared `CommonInfoBean` to direct the framework to the next screen.
4. **Handles state persistence** — Loads inherited data from the previous screen via `getSessionData()` and prepares the form for submission.

The class extends `JCCWebBusinessLogic`, which provides the base infrastructure for service invocation, DataBean access, and logging.

## Key Methods

### `actionInit()` → boolean [line 55]

The entry point when the screen first loads. It reads the `NEXT_SCREEN_ID` from the shared common info bean and dispatches to screen-specific initialization. Currently only the `KKW03201` (search) path has implementation — the paths for `KKW03202`, `KKW03203`, and `KKW02301` are empty stubs.

- **Side effects**: Delegates to `actionInitKKW03201()`, which populates the form with initial data.
- **Returns**: Always `true` unless an exception occurs.

### `actionInitKKW03201()` → boolean [line 87, private]

Performs the full initialization for the 050 number search screen. This is a heavyweight method that:

1. Sets the `OP_SVC_CD` (operation service code) to `"050"`.
2. Calls `getSessionData()` to load inherited customer contract data (SYSID, service contract number, movement division).
3. Sets the operational date (`RSV_APLY_YMD`).
4. Invokes the **KKSV0099/KKSV0099OP** service (050 number issuance initialization) using a `KKSV0099_KKSV0099OPDBMapper` to map six input/output field groups.
5. Maps dropdown lists via `JKKPulldownUtil.setPulldownList()`.
6. Extracts operational date components (year, month, day) for display fields.
7. Reads the reservation upper limit days (`RSV_UPPL_PRD`) from the first element of `RSV_UPPL_PRD_LIST`.
8. Transfers generation/addition timestamps from the service contract list to formatted datetime fields (`SVC_KEI_GENE_ADD_DTM`, `SVC_KEI_UCHK_GENE_ADD_DTM`).
9. Sets the screen name in the common info bean.

- **Returns**: `true` on success.
- **Note**: Heavy use of `JSYwebLog.println` for DataBean dump logging during development/debugging.

### `actionTelnoHtb()` → boolean [line 225]

Handles the telephone number issuance button click. Acts as a thin dispatcher:

1. Retrieves the service form bean and wraps it in a `paramBean` array.
2. Calls `setTelnoRscSbtList()` to set search conditions based on the pulldown selection.
3. Calls `searchList(paramBean, true)` to perform the actual search (with page reset).

- **Returns**: Always `true`.

### `actionPaging()` → boolean [line 246]

Handles pagination link clicks. Similar to `actionTelnoHtb()` but passes `false` for `pageReset`, preserving the current page number across subsequent searches.

- **Returns**: Always `true`.

### `setTelnoRscSbtList(X31SDataBeanAccess[] paramBean, X31SDataBeanAccess svcFormBean)` → void [line 266, private]

Sets search conditions based on the operator's selection from the **issuance type pulldown** (`HRADSI_SBT_LIST`). This is a critical branching method with four cases indexed by the pulldown selection index:

| Index | Issuance Type | TELNO_RSV_STAT | SYSID | SVC_KEI_NO | TELNO_RSV_SBT_CD |
|-------|--------------|----------------|-------|------------|------------------|
| `"1"` | Regular issuance | `"999"` (no reservation) | `""` (unset) | `""` (unset) | `""` (unset) |
| `"2"` | Regular reservation | `"100"` (reserved) | `""` (unset) | `""` (unset) | `"01"` |
| `"3"` | Specified reservation | `"100"` (reserved) | From custody list | From custody list | `"02"` |
| `"4"` | Inherited reservation | `"100"` (reserved) | From custody list | From custody list | `"03"` |

This method modifies the `paramBean[0]` in-place, setting fields like `TELNO_RSV_STAT`, `SYSID`, `SVC_KEI_NO`, and `TELNO_RSV_SBT_CD` depending on the selected issuance type.

### `searchList(X31SDataBeanAccess[] paramBean, boolean pageReset)` → void [line 407, private]

The core search method. It invokes the **KKSV0100/KKSV0100OP** backend service (050 number list search) and processes the results:

1. Creates parameter, input, and output maps. Sets the UC-ID (`KKSV0099` → `UCID_KKSV0100`) and operation ID (`OPID_KKSV0100OP`).
2. Constructs the `DSP_USE_STAYMD` date from year/month/day fields.
3. Sets the search type, max search count, and display count (rows per page) via constants.
4. Calls `setClear()` to clear the previous list.
5. Maps input fields via `KKSV0100_KKSV0100OPDBMapper`.
6. Resets pagination if `pageReset` is `true`.
7. Maps pagination info and invokes the service.
8. Maps output fields back to the DataBean.
9. Checks the search error flag for three cases: zero results (EKB4330), exceeded max (EKB0340), no data (EKB0350).
10. Processes the result list: assigns sequential row numbers (`NO_02`), sets alternating row display flags (`GYO_DISP_FLG_02` — `"1"` for even, `"2"` for odd), and auto-selects the first row.

- **Side effects**: Populates `LIST_050_NO_INFO` array with search results. Sets first row as default selection (`TELNO_SEL = "0"`, `HRADSI_050_NO`). Sets the search command ID to `"paging"` for the framework.

### `setClear()` → void [line 568, private]

Clears the search result list and the currently selected telephone number. Called before every new search to ensure a clean state.

### `actionCfm()` → boolean [line 588]

Handles the **registration confirmation** button click. This transitions from the search screen (KKW03201) to the confirmation screen (KKW03202):

1. Sets `SYSID` and `SVC_KEI_NO` from the inherited custody list data.
2. Calls `createOpSvcKei(JPCModelConstant.FUNC_CD_2)` — the "func code 2" appears to indicate a validation/confirmation check rather than a final registration.
3. If successful, sets `DSP_USE_STAYMD`, sets the next screen to `KKW03202`, and displays message EKB0370 (registration confirmation displayed).

- **Returns**: Always `true`.

### `actionFix()` → boolean [line 649]

Handles the **final registration** (確定) button click on the confirmation screen. This commits the 050 number registration:

1. Calls `createOpSvcKei(JPCModelConstant.FUNC_CD_1)` — the "func code 1" appears to be the actual registration operation.
2. If successful, sets the display date, sets the next screen to `KKW03203` (completion screen), and displays message EKB4390 (registration complete).

- **Returns**: Always `true`.

### `createOpSvcKei(String funcCode)` → boolean [line 697, private]

The central registration/confirmation service invocation method. It calls the **KKSV0101/KKSV0101OP** backend service (050 number issuance registration OP):

1. Calls `set050InfoBean(paramBean)` to prepare all input fields (see below).
2. Sets the UC-ID (`UCID_KKSV0101`) and operation ID (`OPID_KKSV0101OP`).
3. Uses a `KKSV0101_KKSV0101OPDBMapper` to map **18 input field groups** (KKSV010101SC through KKSV010117SC), passing the `funcCode` parameter to all of them.
4. Invokes the backend service via `invokeService(paramMap, inputMap, outputMap)`.
5. Checks for errors via `setErrorMessageInfo(outputMap)` — if an error exists, returns `false`.
6. Logs the DataBean state.

- **Parameters**: `funcCode` — `FUNC_CD_1` (actual registration) or `FUNC_CD_2` (confirmation/validation).
- **Returns**: `true` on success, `false` if an error was detected.

### `actionClear()` → boolean [line 781]

Handles the **clear** button click. It clears the search result list via `setClear()`, then redirects back to the self-screen (KKW03201) by setting the next screen ID.

- **Side effects**: Resets all search results and the selected number.
- **Returns**: Always `true`.

### `actionBack()` → boolean [line 809]

Handles the **back** button. Returns to the previous screen by reading the screen ID from `JCCWebCommon.getScreenId(this)` and setting it as the next screen.

- **Returns**: Always `true`.

### `actionShusei()` → boolean [line 826]

Handles the **edit/correction** (修正) button click on the confirmation screen. Navigates back to the search screen (KKW03201), allowing the operator to modify the search results or select a different number.

- **Returns**: Always `true`.

### `actionFin()` → boolean [line 845]

Handles the **complete** (完了) button click on the final completion screen (KKW03203). Returns to the screen that preceded the registration flow by reading the previous screen ID.

- **Returns**: Always `true`.

### `getSessionData(X31SDataBeanAccess svcFormBean)` → boolean [line 864]

Loads inherited data from the previous screen. This is called during initialization to populate the form with customer context:

1. Retrieves the screen info map via `JCCWebCommon.getScreenInfo(this)`.
2. Extracts customer custody list data (second-tier level) and copies fields to first-tier level fields:
   - `SYSID` from `SYSID_04`
   - `SVC_KEI_NO` from `SVC_KEI_NO_04`
   - `IDO_DIV` (movement division) from `IDO_DIV_04`
   - `IDO_RSN_CD` / `IDO_RSN_MEMO` (movement reason) — iterates over an array to copy reason codes and memos.
   - `SVC_KEI_UCWK_NO` from `SVC_KEI_UCWK_NO_04`
3. Sets the operational date.
4. Sets the telephone tab operation control code based on `TELNO_JUN_04` (telephone sequence: `"1"` = first tab, `"2"` = second tab).

- **Returns**: `true` on success, `false` if the screen info map is null.

### `actionRadioClick()` → boolean [line 965]

Handles the selection of a row from the search results table (radio button click). Updates the form with the selected telephone number:

1. Gets the selected row index from `TELNO_SEL`.
2. Retrieves the corresponding row from `LIST_050_NO_INFO`.
3. Extracts the telephone number (`TELNO_02`), reservation number (`TELNO_RSV_NO_02`), and update datetime (`ZM0181_UPD_DTM_02`).
4. Sets `HRADSI_050_NO`, `KK0181_TELNO_RSV_NO`, and `KK0181_UPD_DTM`.
5. Sets next screen to self (KKW03201).

- **Side effects**: Updates the selected telephone number display fields.

### `set050InfoBean(X31SDataBeanAccess[] paramBean)` → void [line 1016, private]

Prepares all input fields for the registration/confirmation service call (KKSV0101OP). This method configures:

1. **Usage start date** — Concatenates year/month/day into a single string.
2. **Price code** (`PCRS_CD`) — Hardcoded to `"B33"`.
3. **Price plan** (`PPLAN_CD`) — Hardcoded to `"PB3301"`.
4. **Billing contract number** (`SEIKY_KEI_NO`) — Retrieved from `SEIKY_KEI_LIST[0]` if it exists.
5. **Parent contract identifier** (`OYA_KEI_SKBT_CD`) — Hardcoded to `"03"`.
6. **Application type** (`MSKM_SBT_CD`) — `"00026"` for operation settings, `"00001"` for new contracts (determined by `IDO_DIV` comparison).
7. **Progress status** (`PRG_STAT`) — `"5102"` (immediate application) if the usage start date equals the operational date; `"5101"` (scheduled) otherwise.
8. **Operational date/time** — Sets both `UNYO_YMD` and `UNYO_DTM` to the current operational date.

### `setErrorMessageInfo(HashMap<String, Object> outputMap)` → boolean [line 1098, private]

Checks the output map from the registration service for error conditions. Specifically looks at the `KKSV010117SC` key for a `chk_kbn` field:

- If `chk_kbn` equals `"1"`, displays message `EKBE020_KW` (indicating a post-processing operation error, such as a SIP release/cancellation order being sent after a number change).
- Returns `true` if an error was found (causing `createOpSvcKei` to return `false`).
- Returns `false` otherwise.

## Relationships

### Class Dependencies

```mermaid
flowchart LR
    Caller1["WEBGAMEN_KKW032010PJP"] --> KKW["KKW03201SFLogic"]
    Caller2["WEBGAMEN_KKW032020PJP"] --> KKW
    Caller3["WEBGAMEN_KKW032030PJP"] --> KKW
    Caller4["x31business_logic_KKW03201SF"] --> KKW

    KKW --> Parent["JCCWebBusinessLogic"]
    KKW --> Mapper1["KKSV0099 Mapper
(initialization)"]
    KKW --> Mapper2["KKSV0100 Mapper
(list search)"]
    KKW --> Mapper3["KKSV0101 Mapper
(050 issuance OP)"]
```

**Inbound (4 callers):**

- **WEBGAMEN_KKW032010PJP.xml** — The search screen (KKW03201) logic handler.
- **WEBGAMEN_KKW032020PJP.xml** — The confirmation screen (KKW03202) logic handler.
- **WEBGAMEN_KKW032030PJP.xml** — The completion screen (KKW03203) logic handler.
- **x31business_logic_KKW03201SF.xml** — The business logic layer XML configuration.

**Outbound (dependencies):**

- **JCCWebBusinessLogic** — Parent class providing base infrastructure.
- **KKSV0099_KKSV0099OPDBMapper** — Maps fields for the initialization service.
- **KKSV0100_KKSV0100OPDBMapper** — Maps fields for the list search service.
- **KKSV0101_KKSV0101OPDBMapper** — Maps fields for the registration OP service.

### Screen Flow

```mermaid
flowchart TD
    subgraph Screens["KKW03201 Screen Family"]
        A["KKW03201
050 Number Search"] --> B["KKW03202
Confirmation"]
        B --> C["KKW03203
Completion"]
        B -.-> B["KKW03202
Confirmation"]
        A -.-> A["KKW03201
Search"]
    end

    A -->|actionTelnoHtb / actionPaging| Search["searchList"]
    Search -->|invoke KKSV0100| SearchSvc["050 Number List Service"]
    A -->|actionRadioClick| SelectRow["Select row"]

    B -->|actionCfm| CfmSvc["createOpSvcKei func 2
KKSV0101 service"]
    C -->|actionFix| FixSvc["createOpSvcKei func 1
KKSV0101 service"]

    CfmSvc -->|set NEXT_SCREEN_ID| B
    FixSvc -->|set NEXT_SCREEN_ID| C

    A -->|actionBack| Prev["Previous screen"]
    B -->|actionShusei| A
    C -->|actionFin| Prev

    A -->|actionClear| Clear["setClear + redirect to self"]
    A -->|actionInit| Init["actionInitKKW03201
KKSV0099 service + session load"]
    Init --> A
```

### Sequence Flow

```mermaid
sequenceDiagram
    participant Browser
    participant SVC as ServiceForm
    participant Logic as KKW03201SFLogic
    participant Mapper1 as KKSV0099 Mapper
    participant Mapper2 as KKSV0100 Mapper
    participant Mapper3 as KKSV0101 Mapper
    participant DB as Backend Service

    Browser->>Logic: actionInit()
    Logic->>Logic: determine screen KKW03201
    Logic->>Logic: actionInitKKW03201()
    Logic->>Logic: getSessionData(svcFormBean)
    Logic->>SVC: set OP_SVC_CD = 050
    Logic->>Mapper1: map input fields
    Logic->>DB: invoke KKSV0099 service
    DB-->>Mapper2: return output
    Mapper2->>SVC: map output to DataBean
    Logic->>SVC: set date, pulldown, service list
    Logic-->>Browser: return true

    Browser->>Logic: actionTelnoHtb()
    Logic->>Logic: setTelnoRscSbtList(paramBean)
    Logic->>Mapper2: map search input
    Logic->>DB: invoke KKSV0100 service
    DB-->>Mapper2: return search results
    Mapper2->>SVC: populate LIST_050_NO_INFO
    Logic->>Logic: set row numbers, alternating flags
    Logic-->>Browser: return true

    Browser->>Logic: actionCfm()
    Logic->>SVC: set SYSID, SVC_KEI_NO from custody list
    Logic->>Mapper3: map registration input
    Logic->>DB: invoke KKSV0101 service (func 2)
    DB-->>Mapper3: return result
    Logic->>Logic: setErrorMessageInfo(outputMap)
    Logic->>SVC: set NEXT_SCREEN_ID = KKW03202
    Logic-->>Browser: return true

    Browser->>Logic: actionFix()
    Logic->>Mapper3: map registration input (func 1)
    Logic->>DB: invoke KKSV0101 service
    DB-->>Mapper3: return result
    Logic->>SVC: set NEXT_SCREEN_ID = KKW03203
    Logic-->>Browser: return true
```

## Usage Example

A typical flow for registering a new 050 number proceeds as follows:

**1. Initial Load (actionInit)**
```
Screen load → actionInit()
  → Reads NEXT_SCREEN_ID = KKW03201
  → actionInitKKW03201()
    → getSessionData() — loads customer context from previous screen
    → Sets OP_SVC_CD = "050"
    → Invokes KKSV0099 service (initialization service)
    → Populates dropdowns (issuance type pulldown)
    → Sets operational date components
  → Renders KKW03201 search form
```

**2. Search (actionTelnoHtb)**
```
Operator selects issuance type from pulldown → Clicks "Search" button
  → actionTelnoHtb()
    → setTelnoRscSbtList() — configures search conditions based on type
    → searchList(paramBean, true)
      → Clears previous results
      → Maps search parameters
      → Invokes KKSV0100 service (050 number list search)
      → Processes results: assigns row numbers, alternating row flags
      → Auto-selects first row
  → Renders search results table
```

**3. Row Selection (actionRadioClick)**
```
Operator selects a different row from results
  → actionRadioClick()
    → Reads selected row index from TELNO_SEL
    → Extracts phone number, reservation info from LIST_050_NO_INFO[row]
    → Updates HRADSI_050_NO, KK0181_TELNO_RSV_NO, KK0181_UPD_DTM
```

**4. Confirmation (actionCfm)**
```
Operator clicks "Confirm" on search results
  → actionCfm()
    → Sets SYSID, SVC_KEI_NO from custody list
    → createOpSvcKei(FUNC_CD_2) — calls KKSV0101 service with "confirm" mode
    → setErrorMessageInfo() — checks for post-processing errors
    → Sets NEXT_SCREEN_ID = KKW03202
  → Renders KKW03202 confirmation screen
```

**5. Final Registration (actionFix)**
```
Operator clicks "Confirm/Finalize" on confirmation screen
  → actionFix()
    → createOpSvcKei(FUNC_CD_1) — calls KKSV0101 service with "register" mode
    → Sets NEXT_SCREEN_ID = KKW03203
  → Renders KKW03203 completion screen
```

**6. Completion (actionFin)**
```
Operator clicks "Complete" button
  → actionFin()
    → Returns to previous screen
```

## Notes for Developers

### Thread Safety
The class stores no mutable instance state beyond what is inherited from `JCCWebBusinessLogic`. All data flows through the `X31SDataBeanAccess` objects passed as parameters, which are framework-managed per-request objects. The class should be safe for singleton instantiation under concurrent web requests, provided the framework guarantees one instance per request.

### Service IDs
Three backend services are used, each with distinct UC-ID and OP-ID pairs:
| Service | UC-ID | OP-ID | Purpose |
|---------|-------|-------|---------|
| KKSV0099/KKSV0099OP | `UCID_KKSV0099` | `OPID_KKSV0099OP` | 050 number issuance initialization |
| KKSV0100/KKSV0100OP | `UCID_KKSV0100` | `OPID_KKSV0100OP` | 050 number list search |
| KKSV0101/KKSV0101OP | `UCID_KKSV0101` | `OPID_KKSV0101OP` | 050 number issuance registration OP |

### Func Code Distinction
`createOpSvcKei()` accepts a `funcCode` parameter that controls the operation:
- `FUNC_CD_1` — Actual registration (used by `actionFix`).
- `FUNC_CD_2` — Confirmation/validation check (used by `actionCfm`).

This is a common pattern in this framework: the same service endpoint performs different operations based on the function code.

### Pagination
The search list uses a configurable maximum search result count (`KKW03201_MAX_SHOW_CNT`) and rows per page (`KKW03201_ROW_PER_PAGE`), both retrieved via `JCCWebCommon.getSearchConst()`. The `KKW03201` key is used as the page link identifier for pagination state.

### Error Handling
Search results use error flags (`SEARCH_ERR_FLG_ZERO`, `SEARCH_ERR_FLG_OVERMAX`, `SEARCH_ERR_FLG_NODATA`) mapped to user-facing messages. Registration errors are handled via the `KKSV010117SC` output key, which can indicate a post-processing error (e.g., SIP release order sent after number change) — this was introduced in version 20.00.00 (OM-2015-0000564).

### Screen Navigation
The class exclusively uses the shared `CommonInfoBean` for navigation control, setting `NEXT_SCREEN_ID` and `NEXT_SCREEN_NAME`. The action methods always return `true`, suggesting the framework considers success as the default path and uses exceptions for failure.

### Japanese Comments and Identifiers
Most source comments are in Japanese and the codebase uses Japanese business terminology throughout (050 numbers are VoIP telephone numbers issued by K-Opticom, the service provider). The class header and the `actionInitKKW03201()` method reference customer contract ("顧客契約") as the broader module context.

### Legacy Patterns
The codebase exhibits some legacy patterns worth noting:
- `paramBean` arrays are always length 1, containing a single `X31SDataBeanAccess` — the array pattern is unused.
- Extensive use of `JSYwebLog.println(JSYwebLog.DataBean_Dump, ...)` for debugging — these may have performance implications in production.
- The `setTelnoRscSbtList()` method contains commented-out code blocks (original `if/else if` structure using `HRADSI_SBT_CD` constants) — these appear to be migration artifacts.
- The `actionInit()` method has three empty branches (`KKW03202`, `KKW03203`, `KKW02301`) that could indicate future planned screens or unused navigation paths.
