# DKW01302SFLogic

## Purpose

`DKW01302SFLogic` is the central webview logic class for **shelf-move (stock transfer) operations** in the KoptWebB application. It handles the full lifecycle of shelf-move transactions — from initial list display and detail review, through confirmation and fixation (finalization), to CSV export of move results. In short, it is the orchestrator for moving inventory between locations, factories, or offices, and exposing that movement data to users and external systems.

## Design

`DKW01302SFLogic` follows the **Page Controller / Front Controller** pattern common in the framework. Each public method corresponds to a user action on a specific screen (list view, detail view, confirmation screen, completion screen). It acts as a **facade** over backend services (`DKSV0105`, `DKSV0106`, `DKSV0093`), mapping user requests to service invocations via generated database mappers, and transforming response data into display-ready form beans.

Key design characteristics:

- **Stateless per request**: Each method call operates on the current request context (`X31SDataBeanAccess` beans obtained from the superclass). It does not maintain per-user state beyond the page's data bean arrays.
- **Screen lifecycle management**: The class coordinates navigation across five distinct screens — a list screen (`DKW01301`), a detail screen (`DKW01302`), a confirmation screen (`DKW01303`), a completion screen (`DKW01304`), and two subsidiary screens (`DKW01405`, `DKW01406`).
- **Service mediation**: All database operations are delegated to backend services through the `invokeService()` method inherited from `JCCWebBusinessLogic`. The class sets up input/output mappers, passes page link info, and maps results back to form beans.
- **CSV file generation**: A significant portion of the class (lines 934–1207) is dedicated to building a structured CSV file with header, data, and trailer records for shelf-move result data export.

## Key Methods

### `init()` — Screen Initialization

```java
public boolean init()
```

The entry point for the shelf-move detail screen. It performs full initialization:

1. Retrieves screen info and sets the operation date.
2. Clears the detail list (`SHOSAI_LIST`) and update list (`UPDATE_LIST`) arrays.
3. Determines the calling source screen — if the call comes from `DKW01405` (shelf-move base info) or `DKW01406` (count detail), it passes `transBack=true` to `putServiceDKSV0105` to preserve paging context. Otherwise, it clears paging info first.
4. Calls `putServiceDKSV0105()` to fetch shelf-move list data from the backend service.
5. If no data is returned, redirects to the list screen (`DKW01301`) with an error message.
6. Sets the search command to `L_PAG_DTL` (detail paging VARB) and initializes the row number to `0`.
7. Calls `setGamen()` to configure display settings (move origin/destination names, button enable/disable).

**Returns**: `true` on success.

---

### `showBaseInfo()` — Navigate to Base Info Screen

```java
public boolean showBaseInfo()
```

Handles transition from the detail screen to the shelf-move base info screen (`DKW01405`). It reads the current row number, extracts the shelf-move lot number, and passes this context to the target screen via `JCCWebCommon.setScreenInfo()`. The return map preserves lot number, row number, and paging key so data can be restored when the user returns.

---

### `showCountDetail()` — Navigate to Count Detail Screen

```java
public boolean showCountDetail()
```

Handles transition to the count detail screen (`DKW01406`) for reserved equipment delivery. It reads the current row, extracts the delivery number (`L_YBKIKI_HAISO_NO_01`), sets `MV_SBT` to `"2"` (indicating reserved equipment delivery type), and passes context to the target screen. The return map includes lot number, row number, paging key, and delivery number.

---

### `outputCsv()` — CSV File Export

```java
public boolean outputCsv() throws Exception
```

Generates and triggers a download of a CSV file containing shelf-move result data. This is the most structurally complex method because it orchestrates multiple steps:

1. Resets the `record_count` tracker to zero.
2. Retrieves the shelf-move lot number from the form bean.
3. Calls `putServiceDKSV0093()` to fetch move result data from backend service `DKSV0093`.
4. Builds the CSV filename: `eo_tana4_<lotNo>_<sysDateTime>.csv`.
5. Calls `buildFile(lotNo)` to construct the body content (header records, data records, trailer).
6. Appends the trailer record.
7. Sets the file content as a temporary download via `JCCWebCommon.setTempDownloadFile()`, using `SHIFT_JIS` encoding.
8. Clears the `CSV_LIST` data bean array.

**CSV Record Types**: The output file uses three record type codes:
- `7G` — Basic information header (Record Kihon)
- `7H` — Detailed information (Record Shosai)
- `7I` — Trailer with record count (Record Trailer)

---

### `pagingDtl()` / `pagingFix()` / `pagingFin()` — Paging Operations

```java
public boolean pagingDtl()    // detail screen paging
public boolean pagingFix()    // confirmation screen paging
public boolean pagingFin()    // completion screen paging
```

These three methods are thin wrappers around `pagingCommon()`. They differ only in the target screen ID and the VARB constant used:

| Method | Screen ID | VARB |
|--------|-----------|------|
| `pagingDtl` | `DKW01302` | `L_PAG_DTL` |
| `pagingFix` | `DKW01303` | `L_PAG_FIX` |
| `pagingFin` | `DKW01304` | `L_PAG_FIN` |

`pagingFix()` and `pagingFin()` also display informational messages (`EKB0370_I` and `EKB0380_I` respectively) when the service call succeeds.

---

### `confirmCreate()` — Confirmation Processing

```java
public boolean confirmCreate() throws Exception
```

Processes the confirm button action from the detail screen. This is a critical method in the shelf-move workflow:

1. Sets the paging key from the selected row's delivery number.
2. Calls `setGamen()` to update the display settings (validating checkbox states).
3. Calls `putServiceDKSV0106()` with `FUNC_CD_2` (confirmation check mode) — this calls the backend service to validate the shelf-move data without actually updating it.
4. Resets display count, paging info, and both list arrays.
5. Re-fetches list data via `putServiceDKSV0105()`.
6. If no data is returned, redirects to the list screen (`DKW01301`) with an error.
7. Otherwise, sets the search command to `L_PAG_FIX` and displays the confirmation screen (`DKW01303`) with a confirmation message.

---

### `fix()` — Fixation (Finalization) Processing

```java
public boolean fix() throws Exception
```

Processes the fix (finalize) button action from the confirmation screen. This commits the shelf-move operation:

1. Calls `setGamen()` to update display settings.
2. Calls `putServiceDKSV0106()` with `FUNC_CD_1` (fix mode) — this updates the backend data.
3. Resets display count, paging info, and both list arrays.
4. Re-fetches list data via `putServiceDKSV0105()`.
5. If no data, redirects to the list screen.
6. Otherwise, sets the search command to `L_PAG_FIN` and displays the completion screen (`DKW01304`) with a completion message.

---

### `returnList()` / `returnDetail()` / `complete()` — Navigation Actions

```java
public boolean returnList()     // back to list screen
public boolean returnDetail()   // back to detail screen
public boolean complete()       // back to initial state
```

- `returnList()` — Navigates back to the list screen (`DKW01301`).
- `returnDetail()` — Calls `pagingCommon()` to reload the detail screen and navigates back to it.
- `complete()` — Calls `init()` to reset to the initial state and navigates to the completion screen (`DKW01304`).

---

### `pagingCommon()` — Shared Paging Logic

```java
public boolean pagingCommon(String screenId, String screenNm, String varb, boolean transBack)
```

The core paging implementation shared by `pagingDtl()`, `pagingFix()`, and `pagingFin()`. It:

1. Clears the paging key (unless `transBack` is true, meaning the user is returning from a confirm screen).
2. Clears the `SHOSAI_LIST` array.
3. Calls `putServiceDKSV0105()` to re-fetch data.
4. If no data is returned, redirects to the list screen with an error message.
5. Sets the search command, display settings via `setGamen()`, and the next screen.

---

### `putServiceDKSV0105()` — List Data Retrieval (Private)

```java
private boolean putServiceDKSV0105(X31SDataBeanAccess sFormBean, String screenId, boolean transBack)
```

The primary service invocation method for fetching shelf-move list data. It:

1. Creates a `DKSV0105_DKSV0105OPDBMapper` instance.
2. Sets up three mapper sections:
   - `DKSV010501SC` — Shelf-move basic info (FUNC_CD_1)
   - `DKSV010502SC` — Shelf-move lot detail (FUNC_CD_1)
   - `DKSV010503SC` — Shelf-move lot detail (all) (FUNC_CD_2)
3. Updates page link info via `JCCWebCommon.upmapperPageLinkInfo()`.
4. Invokes the service via `invokeService()`.
5. Checks the result — if the `EDK0111B028CBSMsg1List` collection is empty, returns `false` (no data).
6. Maps results back to form beans via the `get*` methods on the mapper.
7. On `transBack=true` (returning from confirm screen), re-sets the row number based on `display_no` from the output. If the display is on page 1 and row 0, it clears and re-sets paging info.

**Returns**: `true` if data was found, `false` otherwise.

---

### `putServiceDKSV0106()` — Confirmation/Fixation Service Call (Private)

```java
private boolean putServiceDKSV0106(X31SDataBeanAccess sFormBean, String func_code)
```

Invokes the backend service `DKSV0106` for confirmation checks or final fixation. It:

1. Creates a `DKSV0106_DKSV0106OPDBMapper` instance.
2. Sets up:
   - `DKSV010601SC` — Reserved equipment delivery completion (via `func_code`)
   - `DKSV010602SC` — Reserved equipment delivery result (FUNC_CD_1)
3. Sets a fixed result code of `"1"` (OK) and an empty result memo.
4. Invokes the service.

**Returns**: Always `true` (no data validation check).

---

### `putServiceDKSV0093()` — Move Result Service Call (Private)

```java
private void putServiceDKSV0093(X31SDataBeanAccess sFormBean)
```

Invokes the backend service `DKSV0093` for retrieving shelf-move result data (used by `outputCsv()`). It sets up the `DKSV0093_DKSV0093OPDBMapper` with section `DKSV009301SC` (FUNC_CD_1 for shelf-move result info) and maps results back.

---

### `setGamen()` — Display Configuration (Private)

```java
private void setGamen(X31SDataBeanAccess serviceFormBean)
```

Configures display settings on the form bean. It:

1. Reads the first basic info record (`KIHON_LIST` at index 0).
2. Constructs display names for move origin and destination by checking warehouse code, factory code, and office code in priority order.
3. Delegates to `setList()` for list item display configuration.
4. Determines button enable/disable states:
   - Disables the confirm-create button if the status code is `"005"` (completed).
   - Disables the count-detail button if the designation method is `"2"` (serial number designation).

---

### `setList()` — List Display Configuration (Private)

```java
private void setList(X31SDataBeanAccess paramBean, X31SDataBeanAccess serviceFormBean)
```

Configures each row in the detail list for display. For each row:

1. Sets alternating background colors (`odd`/`even`).
2. Assigns a line number (`L_NO_01`).
3. Resolves the model number by checking internal equipment code, set product code, and attachment code in priority order.
4. Resolves the product name.
5. Sets short product name (20 chars) and full product name (for tooltip).
6. Handles two designation modes:
   - **Serial number designation** (`shiteiCd == "2"`): Sets serial number, reason, counts to `1`, and attachment remark.
   - **Quantity designation** (else): Sets empty serial number, reason, instruction count, move count (defaults to `"0"` if null), and non-attachment remark.
7. If instruction count equals move count, checks the "move target" checkbox.
8. Sets short remark (10 chars) and full remark.
9. Updates the display count on the form bean.

---

### `buildFile()` — CSV File Content Builder (Private)

```java
private String buildFile(String lotNo)
```

Constructs the body of the CSV file from `CSV_LIST` data bean array. It:

1. Reads the designation method code (`SHITEI_WAY_04`) from the first row.
2. Iterates through all rows, building body records.
3. For **serial number designation** (`"2"`): Inserts a header record before each data row.
4. For **quantity designation**: Inserts a header record for the first row, and before any row where the equipment delivery number changes, and before the last row if its delivery number differs from the previous row.
5. Appends the data record for each row.
6. Increments `record_count` for each data row.

---

### `buildHeaderRecord()` — CSV Header Record Builder (Private)

```java
private String buildHeaderRecord(String lotNo, int rowNo)
```

Builds a single CSV header record (type `7G`) containing:

- Record type (`7G`)
- Instruction date (`SJI_YMD_04`)
- Lot number
- Move origin code (warehouse / factory / office, in priority order)
- Move origin shelf code
- Model number (internal / set / attachment, in priority order)
- Serial number (if serial designation mode)
- Goods status code
- Instruction count
- Move destination code
- Move destination shelf code
- Move count (computed for quantity designation by counting items with the same delivery number)

---

### `buildDataRecord()` — CSV Data Record Builder (Private)

```java
private String buildDataRecord(X31SDataBeanAccess data, String lotNo)
```

Builds a single CSV data record (type `7H`) containing:

- Record type (`7H`)
- Instruction date
- Lot number
- Model number (resolved by priority: internal > set > attachment)
- Serial number
- Goods status code
- Move count (always `"1"` per data row)

---

### `buildTrailerRecord()` — CSV Trailer Record Builder (Private)

```java
private String buildTrailerRecord()
```

Builds the CSV trailer record (type `7I`) containing the total record count accumulated during `buildFile()` and `buildHeaderRecord()`. Increments `record_count` one final time.

---

### `dqot()` — Quote Helper (Private)

```java
private String dqot(String src)
```

Wraps a string in double quotes for CSV output. This is a simple utility that produces `"value"` format.

---

### `setNextScreen()` — Screen Navigation Setter (Private)

```java
private void setNextScreen(String nextScreenId, String nextScreenName)
```

Sets the next screen ID and name in the common info bean. This is called at the end of each action method to determine where the framework should navigate next.

---

## Relationships

### Inbound (Who uses this class)

Four configuration files reference `DKW01302SFLogic`:

```mermaid
flowchart TD
    WEB["WEBGAMEN_DKW01301_PJP.xml"]
    DTK["WEBGAMEN_DKW01302_PJP.xml"]
    DF3["WEBGAMEN_DKW01303_PJP.xml"]
    DF4["WEBGAMEN_DKW01304_PJP.xml"]
    XML["x31business_logic_DKW01302SF.xml"]
    LOGIC["DKW01302SFLogic"]
    JCC["JCCWebBusinessLogic"]

    WEB --> LOGIC
    DTK --> LOGIC
    DF3 --> LOGIC
    DF4 --> LOGIC
    XML --> LOGIC
    LOGIC --> JCC
```

- **`WEBGAMEN_DKW01301_PJP.xml`** — List screen configuration. Routes user actions to this class for subsequent processing.
- **`WEBGAMEN_DKW01302_PJP.xml`** — Detail screen configuration. This is the primary screen where users interact with shelf-move data.
- **`WEBGAMEN_DKW01303_PJP.xml`** — Confirmation screen configuration. Routes confirm/fix actions to this class.
- **`WEBGAMEN_DKW01304_PJP.xml`** — Completion screen configuration. Handles completion navigation.
- **`x31business_logic_DKW01302SF.xml`** — Business logic configuration file that maps screen operations to this class's methods.

### Outbound (What this class depends on)

- **`JCCWebBusinessLogic`** — The abstract base class. Provides `getServiceFormBean()`, `getCommonInfoBean()`, `invokeService()`, and other shared infrastructure methods. `DKW01302SFLogic` is the only concrete subclass in its package, making this relationship central to the design.

## Screen Flow

```mermaid
flowchart LR
    List["DKW01301 - List Screen"]
    Detail["DKW01302 - Detail Screen"]
    Confirm["DKW01303 - Confirm Screen"]
    Complete["DKW01304 - Complete Screen"]
    BaseInfo["DKW01405 - Base Info"]
    CountDtl["DKW01406 - Count Detail"]

    List --> Detail
    Detail --> Confirm
    Confirm --> Complete
    Detail --> BaseInfo
    Detail --> CountDtl
```

The typical user journey flows through four main screens:

1. **List** (`DKW01301`): User selects a shelf-move lot to view.
2. **Detail** (`DKW01302`): User reviews the list of items to be moved. From here, they can navigate to base info or count detail screens.
3. **Confirm** (`DKW01303`): User reviews changes and clicks Fix to finalize.
4. **Complete** (`DKW01304`): Shows completion message. User can export CSV results or return to the list.

## Usage Example

A typical interaction with this class follows this sequence:

```
1. User opens the shelf-move list screen.
   -> Controller calls init()
   -> init() calls putServiceDKSV0105() to fetch list
   -> setGamen() configures display (origin/dest names, button states)
   -> Detail screen (DKW01302) is displayed

2. User clicks "Confirm" on a row.
   -> Controller calls confirmCreate()
   -> confirmCreate() calls putServiceDKSV0106(FUNC_CD_2) for check-only
   -> List is re-fetched and confirmation screen (DKW01303) is displayed

3. User clicks "Fix" to finalize.
   -> Controller calls fix()
   -> fix() calls putServiceDKSV0106(FUNC_CD_1) for actual update
   -> List is re-fetched and completion screen (DKW01304) is displayed

4. User clicks "CSV Export" from the detail or completion screen.
   -> Controller calls outputCsv()
   -> outputCsv() calls putServiceDKSV0093() for result data
   -> buildFile() + buildHeaderRecord() + buildDataRecord() + buildTrailerRecord() build CSV
   -> File is triggered as a browser download
```

## Notes for Developers

- **Single responsibility**: This class handles exactly one business process — shelf-move (stock transfer). Do not add logic for unrelated operations.
- **Paging VARB constants**: Three distinct VARB strings (`L_PAG_DTL`, `L_PAG_FIX`, `L_PAG_FIN`) are used to maintain separate paging context per screen. Do not confuse them — they are used in `JCCWebCommon.setSearchCommand()` calls.
- **Error handling on service failure**: When `putServiceDKSV0105()` returns `false` (no data), the class forces navigation back to the list screen (`DKW01301`) and sets error message `EKB0320_KW`. The calling methods (`confirmCreate`, `fix`) always return `true` in this case to avoid error propagation.
- **Designation mode affects data format**: The designation method code (`SHITEI_WAY_CD_02` / `"2"`) fundamentally changes how the class behaves — it disables the count-detail button and changes how CSV header/data records are constructed (serial designation produces a header per row; quantity designation batches rows by delivery number).
- **`record_count` is a mutable field**: Shared across `buildHeaderRecord()`, `buildDataRecord()`, and `buildTrailerRecord()`. It is reset to `0` at the start of `outputCsv()`. Be careful if this method is ever refactored to support concurrent or batch operations.
- **Character encoding**: CSV export uses `SHIFT_JIS` (`CHAR_SET_WIN31J`). If the system character set changes, this method must be updated.
- **Thread safety**: This class is not thread-safe. Each request creates a new instance (as is standard in the framework), but the instance's fields (`record_count`) are mutated during processing. Never share instances across threads.
- **The `transBack` flag** in `putServiceDKSV0105()` has subtle behavior: when `true`, it prevents clearing the paging key and adjusts the row number based on `display_no` from the service response. This is critical for maintaining state when returning from the confirmation screen.
- **CSV format is a three-record-type protocol**: `7G` (header), `7H` (data), `7I` (trailer). The trailer record contains the total count of all records written. This format appears to be a standardized interface for downstream systems to consume shelf-move results.
- **`dqot()` does not escape internal quotes**: If any field value contains a double-quote character, the CSV output will be malformed. This appears to be an accepted limitation given the expected data domain (machine codes, location names, etc. typically do not contain quotes).
