# KKW02510SFLogic

## Purpose

`KKW02510SFLogic` is the central business logic controller for the **Multi-Session Update** unit (マルチセッション更新) within the K-Opticom Contract Management System (契約管理システム). It handles the full lifecycle of modifying, cancelling, restoring, or reserving-cancelling subscription contracts for a given operational service. The class acts as a screen-level facade that orchestrates data preparation, backend service invocation, and result mapping for a web-based contract management workflow.

## Design

This class follows the **screen controller** pattern typical of the Fujitsu Futurity / JCC web framework. It extends `JCCWebBusinessLogic` (inherited base class for web business logic) and does not implement any additional interfaces.

Each screen action (init, update-confirm, confirm, restore, cancel, etc.) follows a consistent three-step pattern:

1. **Prepare** — extract data from the form `DataBean`, populate an `inputMap` using a domain-specific DBMapper.
2. **Invoke** — call a backend service via `doService()` (which delegates to `invokeService()` from the parent).
3. **Map** — pull results from the `outputMap` back into the form `DataBean` using the same or a related mapper, then set navigation targets.

The class manages **four operation types** (処理区分 / `TRAN_DIV`):

| `TRAN_DIV` constant | Meaning | Backend Service |
|---|---|---|
| `OP_TRAN_DIV_CHGE` | 変更 (Update / Modify) | `KKSV0072` / `KKSV0072OP` |
| `OP_TRAN_DIV_DSL` | 解約 (Cancel / Terminate) | `KKSV0073` / `KKSV0073OP` |
| `OP_TRAN_DIV_KAIHK` | 回復 (Restore) | `KKSV0074` / `KKSV0074OP` |
| `OP_TRAN_DIV_RSV_CL` | 予約取消 (Reservation Cancel) | `KKSV0075` / `KKSV0075OP` |

A fifth mode — `OP_TRAN_DIV_SHOKAI` (照会 / inquiry) — is treated as read-only (sets `NON_UPD_DSL_FLG`).

## Key Methods

### Action Methods (Public)

These are the entry points called by the web framework for each user interaction.

#### `actionInit()` → `boolean`

**Purpose:** Initial screen display processing.

This is the first method executed when the screen loads. It:

1. Retrieves the screen info from the previous screen via `JCCWebCommon.getScreenInfo()`.
2. Calls `setHktgiBean()` to copy migration source data (SYSID, service contract number, operation service number, processing division, error reasons) into the form `DataBean`.
3. Prepares input data via `setInitsrv()` and invokes the **initial display service** `KKSV0071 / KKSV0071OP`.
4. Maps the service output into the form `DataBean` via `storeDataBeanInitsrv()`.
5. Validates the current **operation service contract status** (`OP_SVC_KEI_STAT`) against the processing division to determine whether updates are allowed:
   - For **update (変更)**: permits update if status is 020 (pending receipt), 030 (pending confirmation), or 100 (in service). Otherwise, disables the update button and shows message `EKB1510_KW`.
   - For **cancel (解約)**: permits cancel if status is 030 (in service), 100 (suspended/interrupted), or 210 (completed). Otherwise, disables update.
   - For **restore (回復)**: shows an info message only if status is 910 (cancellation completed). Otherwise, disables update.
   - For **reservation cancel (予約取消)**: shows an info message if status is 010 (received), 020 (pending), 030 (confirmed), or 100 (in service). Otherwise, disables update.
6. Logs the `DataBean` state.

**Return:** `true` (always returns normally).

---

#### `actionUpdCfm()` → `boolean`

**Purpose:** "Update Confirm" button processing — the first step of a write operation.

This method performs a **preview/confirm** call to the backend. It:

1. Gets the common info `DataBean` (for navigation) and the service form `DataBean`.
2. Determines the processing division (`TRAN_DIV`) from the form `DataBean`.
3. Dispatches to the appropriate service based on `TRAN_DIV`:
   - **Cancel (解約):** calls `setDslsrv()` with `FUNC_CD_2` (confirm mode), then `KKSV0073`, then `storeDataBeanDslsrv()`.
   - **Update (変更):** sets the password initialization flag (`PWD_INIT_FLG_CTRL`), calls `setChgesrv()` with `FUNC_CD_2`, then `KKSV0072`, then `storeDataBeanChgesrv()`.
   - Update (and other types) show a success info message.
4. Checks `RTN_MSG_ID` — if empty/null, sets next screen to **KKW02511** (update confirmation screen) and shows a success message. If `RTN_MSG_ID` is set, it means an error occurred and `displayGyomuErrorMsg()` is called to show the error.

**Return:** `true` (always returns normally).

---

#### `actionFix()` → `boolean`

**Purpose:** "Confirm" button processing — commits the changes.

This is the **final write** step. It:

1. Gets the form and common info `DataBean`s.
2. Dispatches to the appropriate service based on `TRAN_DIV`, but this time with `FUNC_CD_1` (execution mode):
   - **Cancel (解約):** `setDslsrv(FUNC_CD_1)` → `KKSV0073` → `storeDataBeanDslsrv()`.
   - **Update (変更):** `setChgesrv(FUNC_CD_1)` → `KKSV0072` → `storeDataBeanChgesrv()`.
   - **Restore (回復):** `setKaihksrv(FUNC_CD_1)` → `KKSV0074` → `storeDataBeanKaihksrv()`.
   - **Reservation Cancel (予約取消):** `setRsvclsrv(FUNC_CD_1)` → `KKSV0075` → `storeDataBeanRsvclsrv()`.
3. Shows the corresponding success info message (e.g., "マルチセッション情報の変更").
4. Checks `RTN_MSG_ID` — if empty/null, navigates to screen **KKW02512** (update completion screen). If set, shows the error via `displayGyomuErrorMsg()`.

**Return:** `true` (always returns normally).

---

#### `actionShusei()` → `boolean`

**Purpose:** "Fix/Correct" button — return to the update screen.

Sets the next screen to **KKW02510** (the original update screen) in the common info `DataBean`, allowing the user to correct their entries.

**Return:** `true`.

---

#### `actionBack()` → `boolean`

**Purpose:** "Back" button — return to the calling screen.

Retrieves the previous screen ID via `JCCWebCommon.getScreenId()` and sets it as the next screen in the common info `DataBean`.

**Return:** `true`.

---

#### `actionFin()` → `boolean`

**Purpose:** "Finish" button — return to the calling screen (same as `actionBack()` but semantically ends the flow).

Sets the previous screen ID as the next screen in the common info `DataBean`.

**Return:** `true`.

---

#### `actionClear()` → `boolean`

**Purpose:** "Clear" button — re-initialize the screen.

Repeats the initialization flow: calls `setInitsrv()`, invokes `KKSV0071 / KKSV0071OP`, and runs `storeDataBeanInitsrv()` to refresh the form `DataBean` with fresh data.

**Return:** `true`.

---

### Service Invocation

#### `doService(String usecase_id, String operation_id, HashMap<String, Object> inputMap, HashMap<String, Object> resultOutputMap)` → `X31CMessageResult`

**Purpose:** Wrapper for backend service invocation.

This private method:
1. Constructs a `paramMap` with `TELEGRAM_INFO_USECASE_ID` and `TELEGRAM_INFO_OPERATION_ID`.
2. Calls the parent class's `invokeService(paramMap, inputMap, resultOutputMap)`.
3. Returns the `X31CMessageResult` (null on success; contains error message details on failure).

The services used are:

| Use Case | Operation | Purpose |
|---|---|---|
| `KKSV0071` | `KKSV0071OP` | Initial display / screen load |
| `KKSV0072` | `KKSV0072OP` | Update (modify session info) |
| `KKSV0073` | `KKSV0073OP` | Cancel (terminate) |
| `KKSV0074` | `KKSV0074OP` | Restore (reactivate) |
| `KKSV0075` | `KKSV0075OP` | Reservation cancel |

---

### Data Preparation Methods (Private)

These methods populate `inputMap` from the `DataBean` before service calls.

#### `setHktgiBean(X31SDataBeanAccess[] paramBean)` → `void`

Copies migration source data from the customer-contract-multi-session list DataBean into the form DataBean. Sets: operation date (`UNYO_YMD`), SYSID, service contract number, processing division, error division, error reason code + memo list, operation service contract number, application number, and application detail number.

#### `setInitsrv(X31SDataBeanAccess[] paramBean, HashMap<String, Object> inputMap)` → `void`

Sets up initial display input data. Sets operation date/timestamp, clears `RTN_MSG_ID`, and sets mode flags based on `TRAN_DIV` (`UPD_MODE_FLG` for update, `NON_UPD_DSL_FLG` for inquiry, `KAIHK_CNSL_FLG` for restore/cancel). Then delegates to `KKSV0071_KKSV0071OPDBMapper` to map six sets of data.

#### `setChgesrv(X31SDataBeanAccess[] paramBean, HashMap<String, Object> inputMap, String func_cd)` → `void`

Prepares update service input data. Sets a progress-specific field (`PRG_TKJK_1`) to "マルチセッション情報" + "変更", then uses `KKSV0072_KKSV0072OPDBMapper` to map six data sets including a SOD (system-of-record) generation call.

#### `setDslsrv(X31SDataBeanAccess[] paramBean, HashMap<String, Object> inputMap, String func_cd)` → `void`

Prepares cancel service input data. In confirm mode (`FUNC_CD_2`), it concatenates year/month/day fields into `USE_ENDYMD`, clears `RTN_MSG_ID`, and sets the progress field. In execute mode (`FUNC_CD_1`), it skips the end-date construction. Uses `KKSV0073_KKSV0073OPDBMapper` with three mappers including SOD generation.

#### `setKaihksrv(X31SDataBeanAccess[] paramBean, HashMap<String, Object> inputMap, String func_cd)` → `void`

Prepares restore service input data. Sets the restore date to the current operation date, clears `RTN_MSG_ID`, sets the progress field, and uses `KKSV0074_KKSV0074OPDBMapper` with three mappers.

#### `setRsvclsrv(X31SDataBeanAccess[] paramBean, HashMap<String, Object> inputMap, String func_cd)` → `void`

Prepares reservation cancel input data. Clears `RTN_MSG_ID`, sets the progress field, and uses `KKSV0075_KKSV0075OPDBMapper` with two mappers (including SOD generation).

---

### Data Result Methods (Private)

These methods map backend output into the form `DataBean`.

#### `storeDataBeanInitsrv(X31SDataBeanAccess[] paramBean, HashMap<String, Object> outputMap)` → `void`

Maps initial display output data. Uses `KKSV0071_KKSV0071OPDBMapper` to retrieve six data sets. Sets the update-possible flag (`CHG_KAHI_FLG`), session count, authentication ID, and initial password. For cancel mode, parses the operation date into year/month/day fields for `USE_ENDYMD`. For update and other modes, copies `SVC_END_YMD` into `USE_ENDYMD`.

#### `storeDataBeanChgesrv(X31SDataBeanAccess[] paramBean, HashMap<String, Object> outputMap)` → `void`

No-op placeholder. Return values from the update service are not used — the screen does not need to reflect any backend output after an update.

#### `storeDataBeanDslsrv(X31SDataBeanAccess[] paramBean, HashMap<String, Object> outputMap)` → `void`

Maps cancel service output via `KKSV0073_KKSV0073OPDBMapper.getOpsvckeiDslCC()`.

#### `storeDataBeanKaihksrv(X31SDataBeanAccess[] paramBean, HashMap<String, Object> outputMap)` → `void`

Maps restore service output via `KKSV0074_KKSV0074OPDBMapper.getOpsvckeiKaihkCC()`, then retrieves discount service change messages via `getWrisvcMsg()`.

#### `storeDataBeanRsvclsrv(X31SDataBeanAccess[] paramBean, HashMap<String, Object> outputMap)` → `void`

Maps reservation cancel output via `KKSV0075_KKSV0075OPDBMapper.getOpsvckeiCnslCC()`, then retrieves discount service change messages via `getWrisvcMsg()`.

---

### Error Handling

#### `displayGyomuErrorMsg(String rtn_msgId, String trans_div)` → `void`

Displays operational error messages with context-specific parameter injection. Based on the error message ID and processing division, it may set replacement parameters:

- For **cancel (解約)** + error `EKB0690_NW`: replaces with "利用終止日" and "過去" (end date must not be in the past).
- For **restore (回復)** + error `EKB5440_JW`: replaces with "回復可能期間外" and "回復は" (outside the restore-possible period).
- For **reservation cancel (予約取消)** + error `EKB5420_JW`: replaces with "オプション" and "予約取消" (option reservation cancel not allowed).

If no parameters are set, it displays the error message as-is. This method handles errors that arise from backend validation during the confirm step.

#### `getWrisvcMsg(String func_code, HashMap<String, Object> outputMap)` → `void`

Retrieves discount service (割引サービス) change messages from the output map. If `func_code` equals `FUNC_CD_1` (execution mode), it extracts the `msg_list` from `WrisvcAutoAplyCC` and sets it into the session via `JKKSetSessionMessage.setSessionMessage()`. This provides the user with messages about automatic discount applications resulting from the operation.

## Relationships

```mermaid
flowchart TD
    WEB["WEBGAMEN_KKW025100PJP"] --> KKW["KKW02510SFLogic"]
    WEB2["WEBGAMEN_KKW025110PJP"] --> KKW
    WEB3["WEBGAMEN_KKW025120PJP"] --> KKW
    BL["x31business_logic_KKW02510SF"] --> KKW

    KKW --> JCC["JCCWebBusinessLogic"]

    subgraph Service Calls
        SV0071["KKSV0071 / KKSV0071OP"]
        SV0072["KKSV0072 / KKSV0072OP"]
        SV0073["KKSV0073 / KKSV0073OP"]
        SV0074["KKSV0074 / KKSV0074OP"]
        SV0075["KKSV0075 / KKSV0075OP"]
    end

    KKW --> SV0071
    KKW --> SV0072
    KKW --> SV0073
    KKW --> SV0074
    KKW --> SV0075

    subgraph Mappers
        MAP0071["KKSV0071_KKSV0071OPDBMapper"]
        MAP0072["KKSV0072_KKSV0072OPDBMapper"]
        MAP0073["KKSV0073_KKSV0073OPDBMapper"]
        MAP0074["KKSV0074_KKSV0074OPDBMapper"]
        MAP0075["KKSV0075_KKSV0075OPDBMapper"]
    end

    KKW --> MAP0071
    KKW --> MAP0072
    KKW --> MAP0073
    KKW --> MAP0074
    KKW --> MAP0075
```

### Inbound Dependencies (4 classes)

| Dependent Class | Role |
|---|---|
| `WEBGAMEN_KKW025100PJP.xml` | Initial screen XML definition — triggers `actionInit()` |
| `WEBGAMEN_KKW025110PJP.xml` | Update confirmation screen XML — triggers `actionUpdCfm()` / `actionFix()` |
| `WEBGAMEN_KKW025120PJP.xml` | Update completion screen XML — triggered after `actionFix()` |
| `x31business_logic_KKW02510SF.xml` | Business logic routing configuration — wires the logic class to use cases |

### Outbound Dependencies

| Dependency | Relationship |
|---|---|
| `JCCWebBusinessLogic` | Parent class — provides `invokeService()`, `getServiceFormBean()`, `getCommonInfoBean()`, `dumpDatabean()` |

### Data Mappers (used internally)

| Mapper Class | Purpose |
|---|---|
| `KKSV0071_KKSV0071OPDBMapper` | Initial display data mapping (6 data sets) |
| `KKSV0072_KKSV0072OPDBMapper` | Update data mapping (6 data sets) |
| `KKSV0073_KKSV0073OPDBMapper` | Cancel data mapping (3 data sets) |
| `KKSV0074_KKSV0074OPDBMapper` | Restore data mapping (3 data sets) |
| `KKSV0075_KKSV0075OPDBMapper` | Reservation cancel data mapping (2 data sets) |

## Flow Diagram

```mermaid
sequenceDiagram
    participant UI as Web Screen
    participant CTRL as KKW02510SFLogic
    participant SVC as Backend Service
    participant MAP as DBMapper

    UI->>CTRL: actionInit()
    CTRL->>CTRL: setHktgiBean()
    CTRL->>CTRL: setInitsrv()
    CTRL->>SVC: KKSV0071 / KKSV0071OP
    SVC-->>CTRL: outputMap
    CTRL->>MAP: KKSV0071_KKSV0071OPDBMapper
    MAP-->>CTRL: form DataBean populated
    CTRL-->>UI: return true

    UI->>CTRL: actionUpdCfm() (confirm)
    alt Update mode
        CTRL->>CTRL: setChgesrv(FUNC_CD_2)
    else Cancel mode
        CTRL->>CTRL: setDslsrv(FUNC_CD_2)
    end
    CTRL->>SVC: KKSV0072/KKSV0073 OP
    SVC-->>CTRL: outputMap
    alt RTN_MSG_ID empty
        CTRL-->>UI: navigate to KKW02511
    else RTN_MSG_ID set
        CTRL->>CTRL: displayGyomuErrorMsg()
    end

    UI->>CTRL: actionFix() (commit)
    alt Update mode
        CTRL->>CTRL: setChgesrv(FUNC_CD_1)
    else Cancel mode
        CTRL->>CTRL: setDslsrv(FUNC_CD_1)
    else Restore
        CTRL->>CTRL: setKaihksrv(FUNC_CD_1)
    else Reservation Cancel
        CTRL->>CTRL: setRsvclsrv(FUNC_CD_1)
    end
    CTRL->>SVC: respective OP
    SVC-->>CTRL: outputMap
    alt RTN_MSG_ID empty
        CTRL-->>UI: navigate to KKW02512
    else RTN_MSG_ID set
        CTRL->>CTRL: displayGyomuErrorMsg()
    end
```

## Usage Example

A typical request flow looks like this:

1. **User navigates** to the Multi-Session Update screen from the operation service contract list. The web framework instantiates `KKW02510SFLogic` and calls `actionInit()`.
2. **`actionInit()`** loads the current state of the selected contract into the form `DataBean`, calling the `KKSV0071` service to fetch multi-session details. The screen renders with all current values displayed.
3. **User modifies** one or more fields (e.g., changes a session's end date) and clicks "Update Confirm". This triggers `actionUpdCfm()`, which sends the modified data to the `KKSV0072` service in confirm mode (`FUNC_CD_2`). If no errors, the user is forwarded to the confirmation screen (KKW02511).
4. **User reviews** the changes and clicks "Confirm". This triggers `actionFix()`, which sends the data to the service in execute mode (`FUNC_CD_1`). If successful, the user is forwarded to the completion screen (KKW02512).
5. **If an error occurs** at step 3 or 4 (e.g., end date in the past, outside restore period), the backend sets `RTN_MSG_ID` in the output, and `displayGyomuErrorMsg()` injects appropriate parameters and returns the user to the appropriate correction screen.

## Notes for Developers

- **Thread safety:** Each request creates a new instance of `KKW02510SFLogic`. The class holds no mutable instance state beyond what is passed through method parameters. It is effectively stateless between requests, but the `DataBean` objects are request-scoped and should not be shared.

- **Always returns `true`:** All public action methods (`actionInit`, `actionUpdCfm`, `actionFix`, `actionShusei`, `actionBack`, `actionFin`, `actionClear`) return `true`. The boolean return value appears to indicate "this method executed without throwing an exception" rather than business success/failure. Business errors are communicated via `RTN_MSG_ID` in the `DataBean`.

- **`RTN_MSG_ID` as error signal:** The presence of a non-empty `RTN_MSG_ID` in the form `DataBean` after a confirm/fix operation is the primary mechanism for indicating that the backend detected an error. The action methods check this field and branch between normal navigation and error display accordingly.

- **`FUNC_CD_1` vs `FUNC_CD_2`:** In this codebase, `FUNC_CD_2` consistently means "confirm mode" (preview/validation only), while `FUNC_CD_1` means "execute mode" (actual data modification). The same service and mapper methods are called in both modes, but the mapper's behavior differs based on this flag.

- **Screen navigation:** Navigation targets are set on the `CommonInfoCF` form bean, not returned as strings. The constants `SCREEN_ID_KKW02510`, `SCREEN_ID_KKW02511`, and `SCREEN_ID_KKW02512` are used for the update screen, confirmation screen, and completion screen, respectively.

- **Password initialization for updates:** When the processing division is "update" (変更), the `PWD_INIT_FLG` is carried through to the confirm step and copied to `PWD_INIT_FLG_CTRL`, suggesting that password initialization may be required or suppressed based on the initial screen state.

- **Hardcoded message strings:** The `INFO_MSGSTRING` array contains Japanese strings for info messages corresponding to the four operation types. These are displayed via `JCCWebCommon.setMessageInfo()`.

- **The `CHG_KAHI_FLG` flag:** This flag controls whether update operations are enabled on the screen. It is set to `false` when the contract status does not permit the current operation type, effectively graying out buttons. It is set back to `true` after successful initialization.

- **Discount messages:** After restore and reservation cancel operations, `getWrisvcMsg()` is called to display any discount service change messages that arose from the operation. This is a secondary concern separate from the primary contract operation result.

- **Debug logging:** All action methods end with `JSYwebLog.println(JSYwebLog.DataBean_Dump, getClass(), dumpDatabean(), ...)` to log the full state of the form `DataBean`. This is useful for troubleshooting but should be considered for removal or rate-limiting in production.

- **Legacy code in comments:** The class contains several commented-out code blocks (e.g., the original error reason code loop, the dynamic/static determination logic, the discount auto-apply mapper call). These represent historical iterations and may contain useful context for understanding past design decisions, but they are no longer active.

- **Constants class:** This class references `KKW02510SFConst` for field keys. The actual constant definitions (e.g., `TRAN_DIV`, `OP_SVC_KEI_STAT`, `CHG_KAHI_FLG`) are defined separately. Any changes to field names should also update that constants class.
