# KKW14901SFLogic

## Purpose

`KKW14901SFLogic` is the view-level business logic class for the **"Non-posing Number Advance Notification" list screen** within the K-Opticom Contract Management System (契約管理システム). It provides a search-and-display interface for advance notification documents associated with non-posing numbers (番포なし番番号 — line numbers that have no physical posing/terminal), supporting filtering by system ID, service type, date range, customer name, and send-exclusion flags. From this screen, users can drill into detail screens, trigger data extraction jobs, queue Yamato delivery dispatch, register stop numbers, and re-send previously issued notifications.

This appears to be a Japanese carrier/telecom billing workflow where advance notification letters (advance warning documents) are sent to customers about upcoming service changes, and this screen is the operational hub for managing those letters.

## Design

`KKW14901SFLogic` extends `JCCWebBusinessLogic`, a framework base class from the Fujitsu Futurity web framework (`com.futurity.web.x31`). It follows the **screen controller** pattern: each public `actionXxx()` method maps to a user action triggered by a page button or link, reads/modifies an `X31SDataBeanAccess` (the framework's form-backing data object), delegates to backend services via `invokeService()`, and returns a boolean status flag.

The class is tightly coupled to four backend microservices:

| Service ID | Operation ID | Purpose |
|---|---|---|
| `KKSV0694` | `KKSV0694OP` | Initial list display — fetches dropdown options and optionally the initial search results |
| `KKSV0695` | `KKSV0695OP` | Search — executes the main list query with filter parameters |
| `KKSV0696` | `KKSV0696OP` | Data extraction — pulls advance notification data (asynchronous, uses `REQ_JOB_ID_DATA_CHSHT`) |
| `KKSV0697` | `KKSV0697OP` | Yamato delivery send — dispatches notification letters via Yamato courier (asynchronous, uses `REQ_JOB_ID_YAMATO_SEND`) |

Screen navigation between this screen (`KKW14901`, `JKKScreenConst.SCREEN_ID_KKW14901`) and detail screens (`KKW14902`, `KKW14904`, `KKW14905`, `KKW14907`) is managed through `JCCWebCommon.setScreenInfo()` and `JCCWebCommon.setScreenId()`, passing serialized state in `HashMap<String, Object>` objects.

## Relationships

```mermaid
flowchart TD
    WEB["WEBGAMEN_KKW149010PJP.xml<br/>Page definition"]
    X31BL["x31business_logic_KKW14901SF.xml<br/>Business logic config"]

    KKW14901SFLogic["KKW14901SFLogic<br/>View Logic<br/>Non-posing number advance<br/>notification list screen"]

    KKW14901SFLogic -- "extends" --> JCCBL["JCCWebBusinessLogic<br/>Framework base class"]

    KKW14901SFLogic -- "navigates to" --> KKW14902SF["KKW14902SFLogic<br/>Detail screen"]
    KKW14901SFLogic -- "navigates to" --> KKW14905SF["KKW14905SFLogic<br/>Stop number registration"]
    KKW14901SFLogic -- "navigates to" --> KKW14907SF["KKW14907SFLogic<br/>Stop number registration"]
    KKW14901SFLogic -- "returns to" --> KKW14902SF_R["KKW14902SFLogic (after edit)"]
    KKW14901SFLogic -- "returns to" --> KKW14904SF["KKW14904SFLogic (after edit)"]

    WEB --> KKW14901SFLogic
    X31BL --> KKW14901SFLogic

    subgraph Services
        KKSV0694["KKSV0694<br/>Initial list display"]
        KKSV0695["KKSV0695<br/>List search"]
        KKSV0696["KKSV0696<br/>Data extraction"]
        KKSV0697["KKSV0697<br/>Yamato delivery send"]
    end

    KKW14901SFLogic --> KKSV0694
    KKW14901SFLogic --> KKSV0695
    KKW14901SFLogic --> KKSV0696
    KKW14901SFLogic --> KKSV0697
```

**Who depends on this class (2 inbound connections):**

- **`WEBGAMEN_KKW149010PJP.xml`** — The page definition XML that wires this logic class to the HTML template for screen `KKW14901`. Button/link events in the page map to `actionXxx()` methods.
- **`x31business_logic_KKW14901SF.xml`** — The X31 business logic configuration that registers this class as the handler for the `KKW14901` screen ID.

## Key Methods

### `actionInit()` — Initial Display

Initializes the screen on first load or when returning from a downstream screen with a search flag set.

1. Calls `JCCWebCommon.getScreenInfo()` to retrieve screen metadata from the framework.
2. Gets the `ServiceFormBean` (`X31SDataBeanAccess`), clears search items (empties the result list and sets `LIST_DISP_FLG` to false), and reads the `SEARCH_FLG` field from the bean.
3. If `SEARCH_FLG` equals `"1"` (search required — meaning the user came back from a downstream screen after performing a search), it builds the input mapping for service `KKSV0694`:
   - Uses `KKSV0694_KKSV0694OPDBMapper` to set up search-condition creation (`setKKSV069401SC`) and batch non-posing advance notification search condition (`setBmpNonNoPreTchiReSearchCC`).
   - Calls `JCCWebCommon.upmapperPageLinkInfo()` to capture pagination state.
4. Invokes service `KKSV0694` / `KKSV0694OP`.
5. Post-processes: sets pulldown lists from output via `JKKWebCommon.setPulldownList()`, and if the search flag was set, maps the search results back into the bean and calls `afterSearch()` to finalize the result display.
6. Sets the next screen name on the common info bean.
7. Calls `setPulldownChkboxSelected()` to restore UI selection state.
8. Determines whether to show a "back" button based on the previous screen ID (if coming from the menu or `ZMW06901`, the back button is hidden; otherwise it is shown).
9. Returns `true` on success.

### `actionSearch()` — Search Execution

Runs the user's search query.

1. Extracts all search criteria from the bean:
   - System ID (`SEARCH_SYSID`)
   - Service type number (`SEARCH_SVC_KEI_NO`)
   - Data extraction date range from/to (concatenated year+month+day: `SEARCH_DATA_CHSHTYMD_FROM`, `SEARCH_DATA_CHSHTYMD_TO`)
   - Application document number (`SEARCH_MSKMSHO_NO`)
   - Customer name kanji (`SEARCH_CUST_NM`)
   - Send exclusion flag (`SEARCH_SEND_JGI_FLG`) — extracted from the pulldown index
   - Unsent flag (`SEARCH_MI_SEND`) — if the checkbox is checked, sets `"1"`, otherwise `""`
2. Resets sort fields, selected row, and issuance number.
3. Clears pagination info via `JCCWebCommon.clearPageLinkInfo()`.
4. Delegates to `execSearch(bean)`.

### `actionPaging()` — Pagination

Handles page navigation in the search results list. Resets the selected row and issuance number, then calls `execSearch()` to re-fetch the current page of results while preserving sort state.

### `actionSortAsc()` / `actionSortDesc()` — Sort Operations

Both methods fetch the current `SORT_NUM` (sort field index), set `ORDER_NUM` and `ORDER_TYPE` (`"1"` for ascending, `"2"` for descending), clear the selected row and issuance number, and call `execSearch()`. This re-executes the search with the sort parameters, returning results ordered by the selected column.

### `actionClear()` — Clear Search Fields

Resets the entire form:
- Resets pulldown/checkbox selections via `setPulldownChkboxSelected(bean, "0")` (default/"send" mode).
- Clears all input fields: system ID, service type, date range (from/to), application document number, customer name.
- Clears all search fields: `SEARCH_SYSID`, `SEARCH_SVC_KEI_NO`, date ranges, document number, customer name, send exclusion flag, unsent flag.
- Clears sort fields: `SORT_NUM`, `ORDER_NUM`, `ORDER_TYPE`.
- Sets `LIST_DISP_FLG` to false (hides the result list).
- Clears the selected row and the entire result array (`BMPNONNOPRETCHI_LIST.clearArray()`).

### `actionReHakkoCopy()` — Re-issue (Copy)

Creates a copy of a notification document for re-issue.

1. Gets the currently selected row index via `getTchiListSelectIndex()`.
2. Reads the `SEND_DTM_02` (send date/time) from the selected row. If it is blank/null, throws an error: "Unsent data — re-issue" (`EKB0930_NW`) and returns without proceeding.
3. Calls `setParamAndSeniKKW14902(KKW14902SFLogic.SENI_MODE_REHAKKO)` to set up navigation parameters and redirect to the detail screen (`KKW14902`) in re-issue copy mode.

### `actionShokaiDtl()` — View Detail

Opens the notification document detail screen in **view mode** (`SENII_MODE_SHOKAI`). Simply delegates to `setParamAndSeniKKW14902()` with the view mode constant, setting up screen info and redirecting to `KKW14902`.

### `actionUpdDtl()` — Update Detail

Opens the notification document detail screen in **edit mode** (`SENII_MODE_UPD`).

1. Validates that the selected row has a non-blank `SEND_DTM_02` (send date/time). If it IS set (meaning the notification was already sent), throws error: "Already sent — cannot update" (`EKB0930_NW`) and returns.
2. If valid, calls `setParamAndSeniKKW14902(KKW14902SFLogic.SENI_MODE_UPD)` to navigate to the detail screen in update mode.

### `actionDchs()` — Data Extraction

Triggers an asynchronous data extraction job for non-posing number advance notification data.

1. Builds input mapping using three mappers: `KKSV069601SC`, `KKSV069602SC`, `KKSV069603SC` (all with `JPCModelConstant.FUNC_CD_2/3`).
2. Invokes service `KKSV0696` / `KKSV0696OP`.
3. Evaluates the result via `getKKSV0696Result()`:
   - `"0"` (OK): Sets info message "Non-posing number advance notification data extraction completed" (`EKB7950__I`).
   - `"1"` (NG1 — extraction batch in progress): Sets warning "Extraction batch is running — cannot execute" (`EKB0930_NW`).
   - `"2"` (NG2 — send batch in progress): Sets warning "Send batch is running — cannot execute" (`EKB0930_NW`).

### `actionSend()` — Yamato Delivery Send

Dispatches notification letters via Yamato courier for unsent records.

1. Builds input mapping using four mappers: `KKSV069701SC` through `KKSV069704SC`.
2. Invokes service `KKSV0697` / `KKSV0697OP`.
3. Evaluates via `getKKSV0697Result()`:
   - `"0"` (OK): Sets info "Yamato delivery sent" (`EKB7950__I`).
   - `"1"` (NG1 — no unsent data): Warning "No unsent data — send cannot execute".
   - `"2"` (NG2 — extraction batch in progress): Warning "Extraction batch is running — cannot execute".
   - `"3"` (NG3 — send batch in progress): Warning "Send batch is running — cannot execute".

### `actionYoksiAdd()` — Stop Number Registration

Navigates to the stop number registration screen (`KKW14905`).

1. Creates self-screen inheritance info via `getMyHktgiInfo()`.
2. Sets screen info for the current screen and sets return destinations for `KKW14905` and `KKW14907`.
3. Sets `NEXT_SCREEN_ID` on the common info bean to `KKW14905`.

### `actionBack()` — Return to Previous Screen

Sets `NEXT_SCREEN_ID` on the common info bean to the value of the current screen ID (obtained via `JCCWebCommon.getScreenId()`), effectively navigating back to the source screen.

### `setParamAndSeniKKW14902(String seniMode)` — Navigate to Detail Screen

Internal method that prepares and executes navigation to the detail screen (`KKW14902`).

1. Gets the selected row's `KANUORESO_HAKKO_NO` (issuance number).
2. Creates self-screen info via `getMyHktgiInfo()` for return-state preservation.
3. Creates next-screen info with `SENII_MODE` and `KANUORESO_HAKKO_NO`.
4. Sets screen info for both current screen (`KKW14901`) and next screen (`KKW14902`).
5. Sets return destinations: `KKW14902` always returns to `KKW14901`; `KKW14904` returns to `KKW14901` only when mode is re-issue or update.
6. Sets `NEXT_SCREEN_ID` to `KKW14902`.

### `isSearchInput(X31SDataBeanAccess bean)` — Validate Search Criteria

Concatenates all eight search fields into a single `StringBuffer`. Returns `true` if any field has content (the buffer length is non-zero after concatenation), meaning the user has entered at least one search condition. Returns `false` if all fields are blank. This is used by `execSearch()` to prevent executing a search with no criteria.

### `invokeService(String usecase_id, String operation_id, HashMap<String, Object> inputMap)` — Service Invocation Wrapper

Framework-agnostic service invocation:

1. Builds a `paramMap` with `TELEGRAM_INFO_USECASE_ID` and `TELEGRAM_INFO_OPERATION_ID`.
2. Clears any pending message results via `clearMessageResultList()`.
3. Logs the pre-invoke bean state.
4. Calls `invokeService(paramMap, inputMap, outputMap)` — inherited from `JCCWebBusinessLogic` — which dispatches to the AP (application) service layer.
5. Logs the post-invoke bean state.
6. Returns the `outputMap`.

### `clearSearchItem(X31SDataBeanAccess bean)` — Reset Search State

Sets `LIST_DISP_FLG` to false (hide result list) and clears the `BMPNONNOPRETCHI_LIST` array. Called at the start of `actionInit()` and `execSearch()`.

### `execSearch(X31SDataBeanAccess bean)` — Execute Search

Core search execution:

1. Clears search items via `clearSearchItem()`.
2. Checks `isSearchInput()` — if no criteria entered, sets error "No search conditions" (`EKB0410_NW`) and returns early.
3. Sets `SEARCH_FLG` to `"1"`.
4. Builds input mapping via `KKSV0695_KKSV0695OPDBMapper` (search condition creation and batch search condition).
5. Captures pagination state via `upmapperPageLinkInfo()`.
6. Invokes service `KKSV0695` / `KKSV0695OP` to perform the actual query.
7. Maps results back into the bean via `mapper.getBmpNonNoPreTchiReSearchCC()`.
8. Calls `afterSearch(bean, outputMap)` to process results.

### `afterSearch(X31SDataBeanAccess bean, HashMap<String, Object> outputMap)` — Post-Search Processing

Handles post-search logic after `KKSV0695` returns:

1. Reads `search_err_flg` from output.
   - `"0"` (zero results): Sets info "No search results" (`EKB0330__I`) and returns.
   - `"1"` (over max results): Sets info "Exceeds maximum search results: [count]" (`EKB0340__I`) and returns.
   - `"2"` (no data on display page): Sets info (but continues processing).
2. Restores pagination state via `downmapperPageLinkInfo()`.
3. Sets the paging command to `"paging"` on the common info bean.
4. Sets `LIST_DISP_FLG` to true (show result list).
5. Sets default row selection to `"0"`.
6. Iterates over all result rows:
   - If a previously selected issuance number (`KANUORESO_HAKKO_NO`) exists and matches the current row, updates `BMPNONNOPRETCHI_CHOICE` to select that row (preserving user selection across search).
   - Sets alternating row styles (`"odd"` / `"even"`) based on index parity.

### `setPulldownChkboxSelected(X31SDataBeanAccess bean, String search_flg)` — Restore UI State

Sets pulldown and checkbox selections for display:

- If `search_flg` is `"1"` (search mode): reads the saved `SEND_JGI_CD` and `MI_SEND` values, finds the corresponding pulldown index via `getPulldownSelectedIndex()`, and updates the UI state to match.
- If `search_flg` is `"0"` (initial display): sets the send exclusion pulldown to the default "send" value (`JKKCommonConst.SEND_JGI_SEND`) and enables the "unsent" checkbox.

### `getPulldownSelectedIndex(X31SDataBeanAccess bean, String selectCd)` — Find Pulldown Index

Iterates over all entries in the `CD_DIV_LIST_01` pulldown array, comparing each `cd` value against `selectCd`. Returns the index of the matching entry, or `0` if no match is found.

### `getMyHktgiInfo(X31SDataBeanAccess bean)` — Capture Screen State

Builds a `HashMap<String, Object>` containing all screen state needed for navigation back to this screen. Copies:
- System ID, service type number, date range (from/to for year/month/day), application document number, customer name.
- Send exclusion code, unsent flag.
- All search fields (SYSID, SVC_KEI_NO, date ranges, document number, customer name, send exclusion flag, unsent flag).
- Sort fields (ORDER_NUM, ORDER_TYPE).
- Search flag, issuance number.
- Return button display flag (added in v4.01).

The selected row's issuance number is included if a row is selected; otherwise it is `""`.

### `getTchiListSelectIndex(X31SDataBeanAccess bean)` — Get Selected Row Index

Returns the integer value of `BMPNONNOPRETCHI_CHOICE` from the bean. Returns `-1` if the value is blank/null, indicating no row is selected.

### `getKKSV0696Result(HashMap<String, Object> outputMap)` — Evaluate Data Extraction Result

Parses the output map from the `KKSV0696` service:
- Checks `KKSV069602SC` contains `ECC0111B010CBSMsg1List` (extraction batch check). If missing, returns `"1"` (extraction batch in progress).
- Checks `KKSV069603SC` contains `trn_req_no` (send batch check). If missing, returns `"2"` (send batch in progress).
- If both checks pass, returns `"0"` (success).

### `getKKSV0697Result(HashMap<String, Object> outputMap)` — Evaluate Yamato Send Result

Parses the output map from the `KKSV0697` service (similar pattern to `getKKSV0696Result` but with three error paths):
- Checks `KKSV069702SC` for unsent data existence → `"1"` if none.
- Checks `KKSV069703SC` for extraction batch status → `"2"` if running.
- Checks `KKSV069704SC` for send batch status → `"3"` if running.
- Returns `"0"` if all checks pass.

### `printLog(int type, HashMap target, String msg)` / `debugLog(String msg)` — Logging

- `printLog()`: Logs a HashMap as debug output with a type level and prefix message.
- `debugLog()`: Wraps a message with `[START]` / `[END]` markers for method entry/exit tracing.

## Usage Example

The typical lifecycle of this class follows a request-response pattern managed by the X31 framework:

```mermaid
sequenceDiagram
    participant Web as Web Page
    participant Logic as KKW14901SFLogic
    participant Bean as ServiceFormBean
    participant SVC as KKSV0694 Service

    Web->>Logic: actionInit()
    Logic->>Bean: getScreenInfo()
    Logic->>Bean: getServiceFormBean()
    Logic->>Bean: clearSearchItem()
    Logic->>Bean: get SEARCH_FLG value
    Logic->>Bean: get SYSID, SVC_KEI_NO
    Logic->>Bean: get date range, customer info
    Logic->>SVC: invokeService("KKSV0694")
    SVC-->>Logic: outputMap
    Logic->>Bean: setPulldownChkboxSelected()
    Logic->>Bean: set next screen name
    Logic->>Bean: set RTN_BTN_DISP_FLG
    Logic-->>Web: return true
```

A typical user workflow:

1. **Screen load** — `actionInit()` is called. If this is the initial load (no `SEARCH_FLG` set), the screen displays with populated dropdowns (send exclusion options) and an empty result list.
2. **Search** — User enters criteria and clicks Search. `actionSearch()` collects all fields, resets pagination, and calls `execSearch()`, which invokes `KKSV0695` to fetch matching records. Results are populated into `BMPNONNOPRETCHI_LIST` with alternating row styles.
3. **Sort** — User clicks a column header. `actionSortAsc()` or `actionSortDesc()` captures the sort field index, sets the sort direction, and calls `execSearch()` to re-display results in the chosen order.
4. **Pagination** — User navigates pages. `actionPaging()` preserves sort state and re-executes the search with updated pagination.
5. **View detail** — User selects a row and clicks "View". `actionShokaiDtl()` sets up navigation parameters (issuance number, send mode) and redirects to screen `KKW14902`.
6. **Edit** — User selects a row (that has not been sent) and clicks "Edit". `actionUpdDtl()` validates the row hasn't been sent, then navigates to `KKW14902` in update mode.
7. **Re-issue** — User selects a sent row and clicks "Re-issue". `actionReHakkoCopy()` validates the row has a send timestamp, then navigates to `KKW14902` in copy mode.
8. **Data extraction** — User clicks "Data extraction". `actionDchs()` invokes `KKSV0696` which starts an asynchronous batch job. Error messages inform the user if a batch is already running.
9. **Yamato send** — User clicks "Yamato send". `actionSend()` invokes `KKSV0697` which queues unsent notifications for delivery.
10. **Stop number registration** — User clicks "Stop number registration". `actionYoksiAdd()` navigates to `KKW14905`.
11. **Back** — User clicks "Back". `actionBack()` navigates to the previous screen.

## Notes for Developers

- **Not thread-safe**: Like most webview logic classes, instances are created per-request and are not designed for concurrent access. The framework manages instance lifecycle.
- **All methods throw `Exception`**: Every `actionXxx()` method declares `throws Exception`. The framework intercepts and handles exceptions, mapping them to error pages or messages.
- **State management via bean**: All UI state is stored in `X31SDataBeanAccess` objects. The `BMPNONNOPRETCHI_LIST` array holds the result rows; `BMPNONNOPRETCHI_CHOICE` tracks the selected row index; `LIST_DISP_FLG` controls whether the result list is visible.
- **Search flag semantics**: `SEARCH_FLG` equals `"1"` when the user is returning to this screen from a downstream screen after performing a search (e.g., from the detail screen). This triggers re-execution of the initial service call (`KKSV0694`) with the search conditions.
- **Validation guards**: `actionUpdDtl()` prevents editing already-sent notifications by checking `SEND_DTM_02`. `actionReHakkoCopy()` prevents re-issuing notifications that were never sent. `execSearch()` prevents search execution with no criteria.
- **Row styling**: The `ROW_STYLE_02` field is set to `"odd"` or `"even"` for every result row in `afterSearch()`, enabling CSS-based alternating row colors on the display screen.
- **Pagination persistence**: `JCCWebCommon.upmapperPageLinkInfo()` / `downmapperPageLinkInfo()` handle serialization/deserialization of pagination state across requests, keyed by the data bean path `"BmpNonNoPreTchiReSearchCC"`.
- **Constant references**: The class references constants from `KKW14901SFConst` (screen-specific), `KKW14902SFConst` (detail screen), `JKKScreenConst`, `JPCModelConstant`, `JPCOnlineMessageConstant`, and the framework's `X31CWebConst`. Modifying these constants in isolation may break this class.
- **Version history**: The class was created in v4.00 (2012-09-11) and received a screen navigation fix in v4.01 (2012-10-05) that added logic to conditionally show/hide the "back" button based on the originating screen.
- **Logging**: Extensive debug logging is present — each action method wraps its body with `debugLog("-- actionXxx[START] --")` and `debugLog("-- actionXxx[END] --")`, and DataBean dumps are logged at each action. This is valuable for troubleshooting but has performance implications in high-throughput scenarios.
