# KKW00816SFLogic

## Purpose

`KKW00816SFLogic` is the core business logic class for **multi-session information registration** in the web application. It handles the end-to-end workflow for registering and managing multiple service contracts (multi-session registrations) — the process that allows a customer to register several services at once under a single authentication ID. This appears to be a critical entry point for the "e-hikari net" broadband service setup flow.

## Design

This class follows the **Command pattern** (also known as the Action/Screen Logic pattern) common in this codebase. Each public `action*` method corresponds to a specific user interaction on a multi-step screen flow (initial display, registration, confirmation, edit, completion). It acts as a **facade** over the underlying service invocations, coordinating data mapping, service calls, and navigation between three related screens (KKW00816, KKW00817, KKW00818).

The class extends `JCCWebBusinessLogic`, which provides common infrastructure like `getCommonInfoBean()`, `getServiceFormBean()`, `invokeService()`, and `setMessageInfo()`. This inheritance structure means the logic class is tightly coupled to the web tier and should not be reused in non-web contexts.

## Key Methods

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

**Purpose:** Entry point — dispatches to the correct initialization method based on the target screen ID.

This method retrieves the `NEXT_SCREEN_ID` from the common info bean and delegates based on the destination screen:
- `KKW00816` (multi-session registration form) → calls `actionMltiseInit()`
- `KKW00817` (confirmation) and `KKW00818` (completion) → no-op (empty branches)

**Return:** Always returns `true` (success).

### `actionMltiseInit()` → `boolean`

**Purpose:** Main initialization logic — loads all service contract data needed for the registration form. This is the most complex method and the most important entry point.

**Flow:**
1. Retrieves the service form `X31SDataBeanAccess` bean and wraps it in an array.
2. Calls `setDataBean(bean)` to pull in any inherited screen data.
3. Sets the operation date (`UNYO_YMD`) from the online operation date.
4. Builds a parameter map and populates it by calling a `KKSV0030_KKSV0030OPDBMapper` with numerous service-related setup methods (service contract agreements, customer agreements, session limits, reservation limits, operation services, service content details, payment codes, billing statements).
5. Invokes the backend service via `invokeService(paramMap, inputMap, outputMap)` (UCID: `KKSV0030`, Operation: `KKSV0030OP`).
6. Maps the output back into the DataBean via the mapper's `get*` methods.
7. Calls `getMltiseId(paramBean)` to determine whether the customer has a **fixed Global IP address** contract — this sets several instance fields (`mltise_ninsho_id`, `yokyu_sbt_cd`, `odr_naiyo_cd`, `svc_kei_ucwk_no`, `kk0161_gene_add_dtm`).
8. Populates the DataBean with:
   - Operation date (`UNYO_YMD`) and operation datetime (`UNYO_DTM`)
   - Initial multi-session authentication ID password (`SHK_MLTISE_NINSHO_ID_PWD`) and the authentication ID (`MLTISE_NINSHO_ID`)
   - Request type code (`YOKYU_SBT_CD`), order content code (`ODR_NAIYO_CD`)
   - Service contract internal number (`SVC_KEI_UCWK_NO`)
   - Generation management timestamp (`KK0161_GENE_ADD_DTM`)
   - Start date split into year, month, day components (`USE_STAYMD_YEAR`, `USE_STAYMD_MON`, `USE_STAYMD_DAY`)

**Side effects:** Populates instance fields `mltise_ninsho_id`, `shk_mltise_ninsho_id_pwd`, `yokyu_sbt_cd`, `odr_naiyo_cd`, `svc_kei_ucwk_no`, `kk0161_gene_add_dtm`. Sets numerous fields on the DataBean.

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

**Purpose:** Handles the "Clear" button — resets the form to a fresh state with the current operation date and resets the session count to 1.

After clearing, it redirects back to screen `KKW00816` (the registration form). The session count is initialized to `"1"` and the start date is re-computed from the current operation date.

### `actionAddMltise()` → `boolean`

**Purpose:** Handles the "Register Confirm" (登録確認) button — validates and submits multi-session registration data.

**Flow:**
1. Retrieves the service form bean and performs validation (throws if bean is null).
2. Calls `mappingDataBean(bean)` to compute derived values from user input (see below).
3. Creates a `KKSV0031_KKSV0031OPDBMapper` and configures the parameter map (UCID: `KKSV0031`, Operation: `KKSV0031OP`).
4. Calls `mapper.setAddMltiseInfo(paramBean, inputMap, FUNC_CODE_2, getMltiseId(paramBean))` — this is the key data mapping call for registration.
5. Invokes the backend service via `invokeService()`.
6. Sets an info message `EKB0370--I` ("Multi-session information registered") and navigates to `KKW00817` (confirmation screen).

**Note:** Many commented-out mapper calls suggest this method was previously more complex but has been simplified to a single `setAddMltiseInfo` call.

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

**Purpose:** Handles the "Back" button — returns to the previous screen.

Simply retrieves the current screen ID and sets it as `NEXT_SCREEN_ID`. No data manipulation is performed.

### `actionFixAddMltise()` → `boolean`

**Purpose:** Handles the "Confirm" (確定) button on the confirmation screen — finalizes the multi-session registration.

Very similar to `actionAddMltise()`, but uses `FUNC_CODE_1` instead of `FUNC_CODE_2` in the `setAddMltiseInfo` call, and navigates to `KKW00818` (completion screen) on success. Sets info message `EKB4390--I` ("Multi-session information registered").

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

**Purpose:** Handles the "Edit" (修正) button on the confirmation screen — returns to the registration form for corrections.

Simply sets `NEXT_SCREEN_ID` to `KKW00816`. No data modification is performed.

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

**Purpose:** Handles the "Complete" (完了) button on the completion screen — exits the multi-session registration flow.

Sets `NEXT_SCREEN_ID` to the screen ID of the current controller (typically the operation service contract list screen).

### `setDataBean(X31SDataBeanAccess bean)` → `boolean`

**Purpose:** Private method that retrieves inherited screen data and sets it on the service form bean.

Calls `JCCWebCommon.getScreenInfo(this)` to get the previous screen's data map. Returns `false` if no inherited data is found (though the return value is only checked by throwing a generic `Exception` rather than propagating the boolean).

### `getMltiseId(X31SDataBeanAccess[] paramBean)` → `boolean`

**Purpose:** Determines whether the customer has a **fixed Global IP address** (固定グローバルIPアドレス) option contract. This is a critical business decision because it changes the registration mode.

**Algorithm:**
1. Extracts authentication ID, password, service contract number, and generation timestamp from the DataBean.
2. Iterates over the `OP_SVC_KEI_LIST` array in the DataBean, checking each operation service contract.
3. Looks for an entry where `OP_SVC_CD_02` equals `"0040"` (fixed Global IP address) AND `OP_SVC_KEI_STAT_02` is in states `100` (in service), `030` (suspended), or `020` (pending).
4. **If found (fixed IP customer):**
   - Calls `editIspNinshoId()` to append "P" to the authentication ID (marking it as a fixed-IP customer).
   - Sets `yokyu_sbt_cd = "02"` (new registration).
   - Sets `odr_naiyo_cd = "144"` (multi-session (static) registration).
   - Clears `kk0161_gene_add_dtm`.
   - **Returns `true`.**
5. **If not found (non-fixed IP customer):**
   - Sets `yokyu_sbt_cd = "04"` (change).
   - Sets `odr_naiyo_cd = "142"` (multi-session (dynamic) registration).
   - **Returns `false`.**

**Return:** `true` if the customer has a fixed Global IP option contract; `false` otherwise.

### `editIspNinshoId(String ispNinshoId)` → `String`

**Purpose:** Edits an ISP authentication ID to mark it as belonging to a fixed-IP customer by inserting or appending "P".

**Algorithm:**
- If the ID contains "@", inserts "P" immediately before the "@" (e.g., `"ABC@ISP"` → `"ABCP@ISP"`).
- If the ID does not contain "@", appends "P" at the end (e.g., `"ABC"` → `"ABCP"`).

This appears to distinguish fixed-IP authentication IDs from standard ones.

### `mappingDataBean(X31SDataBeanAccess bean)` → `boolean`

**Purpose:** Private method that computes derived fields from user input that are not automatically mapped by the DataBean framework.

**Computed values:**
1. **Start date (`USE_STAYMD`):** Concatenates `YEAR + MON + DAY` from the user-input date components.
2. **Implementation operation service contract status (`JSSI_OP_SVC_KEI_STAT`):** Set to `"100"` (in service). Future-date handling code is commented out.
3. **Service charge start date (`SVC_CHRG_STAYMD`):** The first day of the month after the start date (computed via `JPCDateUtil.addMonth(staymd + "01", 1)`).
4. **Progress status (`PRG_STAT`):** Set to `"5101"` (operation information application pending).
5. **Development item 1 (`PRG_TKJK_1`):** Set to `"Multi-session information registration"`.
6. **Parent contract category (`OYA_KEI_SKBT_CD`):** Set to `"03"`.
7. **Disconnection datetime (`IDO_DTM`):** Set to the current system timestamp.

Future-date processing logic is entirely commented out, suggesting this functionality is disabled or planned for a future release.

## Relationships

### Who depends on KKW00816SFLogic

```mermaid
flowchart TD
    A["KKW00816SFLogic<br/>Multi-session info registration"] --> B["JCCWebBusinessLogic<br/>Base class"]

    F["KKW00816PJP<br/>Registration screen"] --> A
    G["KKW00817PJP<br/>Confirmation screen"] --> A
    H["KKW00818PJP<br/>Completion screen"] --> A
    I["x31business_logic_KKW00816SF.xml<br/>Config"] --> A
```

- **KKW00816PJP**: The registration form screen. Calls `actionInit()`, `actionMltiseInit()`, `actionClear()`, and `actionAddMltise()`.
- **KKW00817PJP**: The confirmation screen. Calls `actionBack()`, `actionFixAddMltise()`, and `actionShusei()`.
- **KKW00818PJP**: The completion screen. Calls `actionBack()` and `actionFin()`.
- **x31business_logic_KKW00816SF.xml**: Configuration file referencing this logic class.

### What KKW00816SFLogic depends on

```mermaid
flowchart TD
    A["KKW00816SFLogic"] --> B["JCCWebBusinessLogic<br/>Base class"]
    A --> C["KKSV0030_KKSV0030OPDBMapper<br/>Service form mapper"]
    A --> D["KKSV0031_KKSV0031OPDBMapper<br/>Registration mapper"]
    A --> E["X31SDataBeanAccess<br/>Data bean"]
    A --> F["KKW00816SFConst<br/>Constants"]
    A --> G["JCCWebCommon<br/>Common utilities"]
```

- **JCCWebBusinessLogic** (extends): Provides infrastructure for screen navigation, bean access, and service invocation.
- **KKSV0030_KKSV0030OPDBMapper**: Used in `actionMltiseInit()` to map and invoke the service form data retrieval service.
- **KKSV0031_KKSV0031OPDBMapper**: Used in `actionAddMltise()` and `actionFixAddMltise()` to map and invoke the multi-session registration service.
- **X31SDataBeanAccess**: The primary data carrier between the view and business logic layers.
- **KKW00816SFConst**: Class-level constants for field names.
- **JCCWebCommon**: Utility class for screen info, date handling, and message setting.

## Usage Flow

The class is used across a three-screen wizard:

```mermaid
sequenceDiagram
    participant CL as Client
    participant C as Controller<br/>KKW00816PJP

    CL->>C: Request actionInit
    C->>A: KKW00816SFLogic
    A->>A: actionMltiseInit
    A->>A: invokeService KKSV0030
    A->>A: getMltiseId
    A->>A: mappingDataBean
    A-->>A: Set DataBean fields
    A-->>C: Return true
    C-->>CL: Forward to KKW00816
```

1. **Screen 1 — KKW00816 (Registration form):** `actionMltiseInit()` loads all available service contracts via the KKSV0030 service, determines whether the user has a fixed Global IP option, and displays the registration form.
2. **Screen 2 — KKW00817 (Confirmation):** `actionAddMltise()` submits the registration data via the KKSV0031 service and shows a confirmation page. From here the user can "Back" (re-edit), "Confirm" (finalize), or "Edit".
3. **Screen 3 — KKW00818 (Completion):** `actionFixAddMltise()` finalizes the registration. The user can then "Back" or "Complete" (return to the service list).

## Notes for Developers

- **Exception handling is minimal:** Methods throw bare `new Exception()` on errors rather than providing contextual error messages. This makes debugging harder.
- **Stateful instance fields:** The class stores `mltise_ninsho_id`, `shk_mltise_ninsho_id_pwd`, `yokyu_sbt_cd`, `odr_naiyo_cd`, `svc_kei_ucwk_no`, and `kk0161_gene_add_dtm` as instance fields. If this class is not thread-safe (each request gets a new instance, which is typical for web controllers), this should be fine — but it means the class cannot be shared across concurrent requests.
- **Hard-coded constant lookups:** The fixed Global IP check uses string literal `"0040"` for `opSvcCd` and state codes `"100"`, `"030"`, `"020"` for `opSvcKeiStat`. These correspond to `JKKCommonConst` values but are checked via string comparison rather than the constants.
- **Commented-out code:** Large sections of code are commented out (future date processing in `mappingDataBean`, multiple mapper calls in `actionAddMltise` and `actionFixAddMltise`). This suggests either deprecated features or features on hold. Consider cleaning up to reduce confusion.
- **Generic exception:** `setDataBean()` returns a boolean indicating success/failure, but callers check it by throwing a bare `Exception` — no error context is passed.
- **`FUNC_CODE_1` vs `FUNC_CODE_2`:** `actionAddMltise()` uses `FUNC_CODE_2` (likely "display/input" mode) while `actionFixAddMltise()` uses `FUNC_CODE_1` (likely "execute/confirm" mode). This pattern is common in this codebase for distinguishing read-only from write operations.
- **`getMltiseId` return value change:** The method originally returned `void` but was changed to return `boolean` (OM-2013-0002398, 2013/10/18) to allow the caller to know whether the customer has a fixed Global IP option.
- **Date handling:** The class manually concatenates year/month/day strings to form dates (e.g., `staymd = year + mon + day`), which is fragile. Use date parsing/validation in any modifications.
