# KKW12601SFLogic

## Purpose

`KKW12601SFLogic` is the primary business-logic controller for the **Addendary Honorary Letter List** screen (KKW12601) in the KOPT system. It handles the full lifecycle of searching, displaying, editing, and managing bulk-addendary honorary letter records -- including data retrieval, bulk update confirmation, Yamato shipping (dispatch), Yamato receipt of return files, and final confirmation. This appears to be a central orchestration point for administrative staff who manage bulk mailings of honorary letters to customers.

## Design

This class follows a **web action-controller pattern** typical of the JCC Web framework. Each public `actionXxx()` method corresponds to a user action (button click) on the screen, processing the request and returning a boolean success/failure flag. It extends `JCCWebBusinessLogic`, which provides the base infrastructure for screen-info management, service invocation, and common web logic.

The class operates on a **request-response cycle per action**: retrieve the `X31SDataBeanAccess` form bean, perform validation/transformation, optionally call backend AP services via `invokeService()`, populate the bean with results, and return. Search operations follow a three-phase pattern: `beforeSearch()` (clear lists) -> `execSearch()` (call service) -> `afterSearch()` (process results and set display flags).

The class uses **stateful instance fields** (`inputMap`, `outputMap`, `seniFromFin`) that are populated during `invokeService()` calls and consumed by post-processing methods. These are not thread-safe, meaning instances must not be shared across requests.

## Key Methods

### `actionInit() -> boolean` [lines 182–314]

Initial screen display processing. Called when the KKW12601 screen is first loaded.

1. Retrieves screen info and the service form bean.
2. Checks the `SEARCH_FLG` parameter -- if it's "1" (return from a detail/update screen), it runs the search directly without loading pulldown data.
3. On first visit (SEARCH_FLG not "1"):
   - Creates a `KKSV0131_KKSV0131OPDBMapper` to map pulldown list data from the `KKSV0131` service.
   - Invokes the `KKSV0131` service (usecase: `KKSV0131`, operation: `KKSV0131OP`) to populate category/function code pulldowns.
   - Filters out one specific data type (`CD_DIV_CD00585_3 = "3"`: "telephone number advance notice") from the honorary letter type pulldown.
   - Maps the service output back to the DataBean pulldowns for honorary letter type, new addition flag, and send exclusion.
   - If returning from another screen (SEARCH_FLG = "1"), re-executes the search.
4. Determines whether to show the return button based on the previous screen ID.
5. Resets `seniFromFin` flag and logs the final bean state.

Returns `true` on success.

### `actionSearch() -> boolean` [lines 326–451]

Search execution processing. Collects all search criteria from the form bean, converts pulldown selections to their underlying codes, and executes the search.

- Extracts data type, SYSID, service contract number, date range (from/to year/month/day), application form number, customer name (kanji), and same-wiring group number from the bean.
- Converts three pulldown selections (data type, new addition flag, send exclusion) from display index to their string codes.
- Reads the "unshipped" checkbox flag.
- Clears sort fields, honorary letter selection, and page link info.
- Calls `beforeSearch()` to clear result lists.
- Validates that at least one search condition is set via `isSearchInput()` -- if all fields are empty, displays an error. Otherwise, calls `execSearch()` and `afterSearch()`.

### `actionPaging() -> boolean` [lines 462–487]

Pagination handling. Re-executes the current search with sort information preserved (the sort fields are not cleared, unlike `actionSearch()` which clears them). Clears the honorary letter selection and re-runs the search pipeline.

### `actionSortAsc() -> boolean` [lines 498–530]

Ascending sort handling. Gets the sort field number from the bean, sets `ORDER_TYPE` to `"1"` (ascending), clears selection, and re-runs the search.

### `actionSortDesc() -> boolean` [lines 541–573]

Descending sort handling. Same as `actionSortAsc()` but sets `ORDER_TYPE` to `"2"` (descending).

### `actionClear() -> boolean` [lines 586–648]

Form reset processing. Clears all search input fields (SYSID, service contract number, date range, application form number, customer name, group number), pulldown selections, sort fields, and clears both the result list (`KANUORESO_LIST`) and its backup list (`KANUORESO_LIST_BF`). Hides the list display area by setting `LIST_DISP_FLG` to `false`.

### `actionUpdIcrn() -> boolean` [lines 663–999]

Bulk update confirmation processing. The most complex method in the class -- prepares data for the bulk update confirmation screen (KKW12605).

1. Clears all update tracking lists (`KANUORESO_LIST_UPD`, `KANUORESO_LIST_INS`, `KANUORESO_LIST_MOD`).
2. Iterates through the result list and compares each row against its "before" snapshot (`KANUORESO_LIST_BF`).
3. Detects changes in the "withdrawal" (hikinuki) checkbox and "send exclusion" (send_jgi) checkbox.
4. **Blocks updates to already-shipped records** -- if `SEND_DTM_02` (send datetime) is set, the row is considered shipped and changes are rejected with an error.
5. For re-issuance (re_hako) rows: if already shipped, both update and insert flags are set. If not shipped, a validation error is shown.
6. Categorizes changed rows into `KANUORESO_LIST_UPD` (for the confirmation screen) and `KANUORESO_LIST_INS` / `KANUORESO_LIST_MOD` (for service-side insert/update tracking).
7. If any changes detected, invokes the `KKSV0142` service to check if a shipping batch is currently running. If a batch is in progress, shows an error. Otherwise, sets the next screen to `KKW12605` (bulk update confirmation) and navigates.
8. Also detects if terminal purchase notification output is required (based on `TNMT_BUY_TCHISHO_OPUT_SKCD`) and sets a special message if so.

Returns `true` on success (navigation to next screen occurs inside).

### `actionShokaiDtl() -> boolean` [lines 1010–1015]

Detail view. Delegates to `setParamAndSeni(KKW12602SFLogic.TRAN_DIV_DTL)` to pass selected row data to the detail screen (KKW12602) for read-only display.

### `actionUpdDtl() -> boolean` [lines 1026–1031]

Detail edit. Delegates to `setParamAndSeni(KKW12602SFLogic.TRAN_DIV_UPD)`. Before navigating, `setParamAndSeni` checks if the record is already shipped (has `SEND_DTM_02` set) and blocks the edit with an error if so.

### `actionDchs() -> boolean` [lines 1042–1091]

Data retrieval processing. Calls the `KKSV0143` service (usecase: `KKSV0143`, operation: `KKSV0143OP`) to fetch addendary honorary letter data for processing. Checks the error flag from the service output -- `"1"` means shipping batch in progress, `"2"` means data extraction batch in progress, otherwise displays a success message.

### `actionSend() -> boolean` [lines 1102–1170]

Yamato shipping processing. Calls the `KKSV0144` service (usecase: `KKSV0144`, operation: `KKSV0144OP`) to ship data to Yamato (shipping partner). After the service call:
- If "1": shipping batch in progress (error).
- If "2": data extraction batch in progress (error).
- Otherwise: maps the service output back to the DataBean and checks if there are any unshipped records. If none found, shows an error; otherwise, displays success message.

### `actionRcv() -> boolean` [lines 1181–1211]

Yamato receipt processing. Calls the `KKSV0145` service (usecase: `KKSV0145`, operation: `KKSV0145OP`) to receive return data from Yamato. This involves three service mapping points: error file receipt, file 1 receipt, and file 2 receipt.

### `actionShusei() -> boolean` [lines 1222–1242]

Correction processing. Simply navigates back to the list screen (KKW12601). Used after correction-related operations to return to the main list.

### `actionFix() -> boolean` [lines 1256–1344]

Final confirmation processing. The confirmation step after bulk update changes are reviewed.

1. Invokes the `KKSV0142` service (usecase: `KKSV0142`, operation: `KKSV0142OP`) with `KanuoresoIktTrkCC` and `KKSV014201SC` mappings to track/confirm changes.
2. If a shipping batch is running, shows an error.
3. Otherwise, maps the update results back to the DataBean:
   - "KOPT delivery" checkbox -> `HIKINUKI_02`
   - "Send exclusion" checkbox -> `SEND_JGI_02`
   - Re-issuance flag set if `SEND_DTM_02` is present
4. Sets the next screen to `KKW12606` (list change completion screen) and displays a success message.

### `actionFin() -> boolean` [lines 1356–1379]

Completion processing. Sets `seniFromFin = true` to indicate navigation from the completion screen, then calls `actionInit()` to re-display the list with the same search conditions (re-search).

### `actionBack() -> boolean` [lines 1388–1401]

Return button processing. Sets the next screen ID from the current screen context and navigates back. Does not re-run searches -- simple navigation.

### `invokeService(String usecase_id, String operation_id) -> X31CMessageResult` [lines 1415–1438]

Private service invocation helper. Creates a parameter map with `usecase_id` and `operation_id`, clears the message result list, and calls the parent class's `invokeService(paramMap, inputMap, outputMap)`. Stores the result in `outputMap` as a side effect. Returns the `X31CMessageResult` from the service call.

### `beforeSearch(X31SDataBeanAccess bean) -> void` [lines 1447–1467]

Pre-search initialization. Sets `LIST_DISP_FLG` to `false` and clears all five result DataBean arrays: `KANUORESO_LIST`, `KANUORESO_LIST_UPD`, `KANUORESO_LIST_INS`, `KANUORESO_LIST_MOD`, and `KANUORESO_LIST_BF`.

### `execSearch(X31SDataBeanAccess bean) -> void` [lines 1480–1504]

Search execution. Sets `SEARCH_FLG` to "1", creates a `KKSV0132` mapper with `KanuoresoReSearchCC` mapping, handles pagination info, calls `invokeService("KKSV0132", "KKSV0132OP")`, and maps the output back to the DataBean.

### `afterSearch(X31SDataBeanAccess bean) -> void` [lines 1516–1609]

Post-search processing. The most detailed result-processing method:

1. Checks for search errors (zero results, over-max results, no data on current page).
2. If there are valid results:
   - Applies pagination info (`downmapperPageLinkInfo`).
   - Sets the search command to `PAGING_CMD`.
   - Enables `LIST_DISP_FLG` to show the list.
   - Iterates through all result rows, converting service-side flags to UI-side checkbox states:
     - `LETTER_SHIWAKE_KOPT` -> withdrawal checkbox
     - `SEND_JGI_JGI` -> send exclusion checkbox
   - Preserves the "before" data for change detection by copying to `KANUORESO_LIST_BF`.
   - Auto-selects the first row, or re-selects the previously-selected row if it still exists.

### `setPulldownSelected(X31SDataBeanAccess bean, String search_flg) -> void` [lines 1618–1694]

Restores pulldown selections from search criteria. When `search_flg` is "1" (re-search), reads the stored search codes from the bean and finds the corresponding indices in each pulldown. When it's "0" (initial display), resets to defaults: first option for data type and new addition, "send target" option for send exclusion, and the "unshipped" checkbox is checked by default.

### `getPulldownSelected(X31SDataBeanAccess bean, String code, ArrayList<String> param) -> void` [lines 1703–1728]

Helper to find a code in a pulldown list. Iterates through all options, comparing `CD_DIV_LIST_01` values against the target code. Returns the matching index and name in the `param` list, or `["0", ""]` if not found.

### `setParamAndSeni(String tran_div) -> boolean` [lines 1738–1889]

Cross-screen parameter passing (intra-session). Used by `actionShokaiDtl()` and `actionUpdDtl()` to pass selected row data and search criteria to the detail screen (KKW12602).

1. Gets the currently selected row from the list.
2. If tran_div is `TRAN_DIV_UPD`, validates the record is not already shipped (has no `SEND_DTM_02`).
3. Creates two maps:
   - `dataMapMe`: all search criteria fields for self-persistence (return navigation).
   - `dataMapNext`: tran_div, honorary letter number, and terminal purchase notification code for the detail screen.
4. Calls `JCCWebCommon.setScreenInfo()` for both the current screen (self) and the next screen (KKW12602).
5. Sets up return screen tracking: KKW12601 -> KKW12602 (or KKW12604 for updates).
6. Sets the next screen ID in the common info bean.

### `isSearchInput() -> boolean` [lines 1896–1925]

Validation helper. Concatenates all 11 search criterion fields into a single string. If the resulting string is non-empty, returns `false` (there is input). Returns `true` if all fields are empty (no search input provided). Note: the return value is inverted from what the method name suggests -- it returns `true` when NO input is present (i.e., the search should be blocked).

### `getKKSV0142Result(HashMap<String, Object> outputMap) -> String` [lines 1935–1944]

Extracts the error flag from the `KKSV0142` service output's `KanuoresoIktTrkCC` field. Returns `"0"` for success, `"1"` for shipping batch in progress error.

### `getErrFlg(HashMap<String, Object> outputMap, String fieldText) -> String` [lines 1955–1964]

Extracts the error flag from any service output's specified field. Returns `"0"` for success, `"1"` for shipping batch in progress, `"2"` for data extraction batch in progress.

### `printLog(int type, HashMap target, String msg) -> void` [lines 1976–1989]

Utility for logging a HashMap's contents. Iterates over all key-value pairs and writes them to the log with a message prefix and delimiter lines.

## Relationships

```mermaid
flowchart TD
    subgraph Controllers["Controllers"]
        XML1["WEBGAMEN_KKW126010PJP"]
        XML2["WEBGAMEN_KKW126050PJP"]
        XML3["WEBGAMEN_KKW126060PJP"]
        XML4["x31business_logic_KKW12601SF"]
    end

    subgraph Core["Core Logic"]
        KKW["KKW12601SFLogic"]
    end

    subgraph Base["Base Framework"]
        JCC["JCCWebBusinessLogic"]
    end

    subgraph DependentScreens["Dependent Screens"]
        KKW12602["KKW12602 - Detail Screen"]
    end

    XML1 --> KKW
    XML2 --> KKW
    XML3 --> KKW
    XML4 --> KKW
    KKW --> JCC
    KKW --> KKW12602
```

**Inbound dependencies (4 classes reference KKW12601SFLogic):**

| Class | Relationship |
|-------|-------------|
| `WEBGAMEN_KKW126010PJP.xml` | Primary controller for the KKW12601 list screen itself |
| `WEBGAMEN_KKW126050PJP.xml` | Controller for the bulk update confirmation screen (KKW12605), navigated to from KKW12601 |
| `WEBGAMEN_KKW126060PJP.xml` | Controller for the list change completion screen (KKW12606), navigated to from KKW12601 after `actionFix()` |
| `x31business_logic_KKW12601SF.xml` | Business logic wiring/registration descriptor |

**Outbound dependencies:**

| Class | Relationship |
|-------|-------------|
| `JCCWebBusinessLogic` | Parent class -- provides `invokeService()`, `getServiceFormBean()`, `getCommonInfoBean()`, `dumpDatabean()`, and common web infrastructure |

## Usage Example

The typical user flow on the KKW12601 screen is:

1. **Initial display** (`actionInit`): The screen loads, the `KKSV0131` service is called to populate pulldown menus (honorary letter types, new addition flags, send exclusion flags). If the page is re-entered from a completion screen, the prior search is re-executed.

2. **Search** (`actionSearch`): User enters criteria (e.g., SYSID, date range) and clicks search. Criteria are converted from pulldown display indices to codes, the `KKSV0132` service is called, and results are populated in the list with checkboxes for withdrawal and send exclusion.

3. **Bulk update** (`actionUpdIcrn`): User modifies checkboxes on result rows and clicks bulk update. Changes are detected by comparing against "before" snapshots, shipped records are blocked from modification, and changed rows are categorized as insert/update. If the shipping batch is not running, navigation to the confirmation screen (KKW12605) occurs.

4. **Data operations** (`actionDchs`, `actionSend`, `actionRcv`): User can extract honorary letter data, ship via Yamato, or receive return data through dedicated service calls. Each method validates that no conflicting batch is running before proceeding.

5. **Confirmation** (`actionFix`): After reviewing changes on the confirmation screen, the `KKSV0142` service is called to track and apply all changes. Updated checkbox states are mapped back to the DataBean, and the user is navigated to the completion screen (KKW12606).

## Notes for Developers

- **Not thread-safe**: The instance fields `inputMap`, `outputMap`, and `seniFromFin` are shared state within each request cycle. Do not reuse `KKW12601SFLogic` instances across concurrent requests.

- **Batch conflict handling**: Several operations (`actionUpdIcrn`, `actionDchs`, `actionSend`, `actionFix`) check for running shipping/Extraction batches via the `err_flg` field in the service output. The error codes are: `"0"` = normal, `"1"` = shipping batch in progress, `"2"` = data extraction batch in progress.

- **Shipped records are immutable**: If a row has `SEND_DTM_02` (send datetime) set, it is considered already shipped. Neither `actionUpdIcrn()` (bulk update) nor `actionUpdDtl()` (detail edit) will allow changes to shipped records -- both methods display an error and abort.

- **Search validation logic is inverted**: `isSearchInput()` returns `true` when NO search conditions are set, and `false` when conditions are present. This is used in `actionSearch()` as: `if (isSearchInput())` -> show error, `else` -> execute search.

- **Return button visibility**: The return button is conditionally shown based on the previous screen ID. If the previous screen was `ZMW06901` (or null/empty), the return button is hidden. This appears to handle a screen grouping change introduced in v4.01.

- **Pulldown data filtering**: The honorary letter type pulldown explicitly filters out `CD_DIV_CD00585_3` ("telephone number advance notice") from the service output. This was a targeted fix for a specific business requirement (OT-2013-0000163).

- **Pagination state**: The class maintains pagination state via `JCCWebCommon.upmapperPageLinkInfo` / `downmapperPageLinkInfo` calls with the `SCREENID` constant and a `"paging"` command identifier. `actionPaging()`, `actionSortAsc()`, and `actionSortDesc()` all preserve sort state while `actionSearch()` clears it.

- **Service IDs**: The class uses four distinct AP service usecases:
  - `KKSV0131` / `KKSV0131OP` -- Pulldown data initialization
  - `KKSV0132` / `KKSV0132OP` -- List search/research
  - `KKSV0142` / `KKSV0142OP` -- Change tracking and bulk update
  - `KKSV0143` / `KKSV0143OP` -- Data extraction
  - `KKSV0144` / `KKSV0144OP` -- Yamato shipping
  - `KKSV0145` / `KKSV0145OP` -- Yamato receipt

- **Logging**: All action methods call `JSYwebLog.println(JSYwebLog.DataBean_Dump, ...)` at the end to log the final bean state. Cross-screen parameter passing also logs to `JSYwebLog.DEBUG` via the `printLog()` helper.

- **Constants**: The class defines numerous constants for screen IDs (`KKW12601`, `KKW12602`, etc.), service job IDs (`EO2050110J0`, etc.), and UI flags. Most values are referenced via `KKW12601SFConst`, `JKKScreenConst`, `JPCModelConstant`, and similar shared constant classes.