---

# Business Logic — DKW01302SFLogic.buildFile() [76 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `eo.web.webview.DKW01302SF.DKW01302SFLogic` |
| Layer | Presentation (Web View / Logic Bean) |
| Module | `DKW01302SF` (Package: `eo.web.webview.DKW01302SF`) |

## 1. Role

### DKW01302SFLogic.buildFile()

This method generates the CSV file content for the **shelf transfer result data file** (棚移動結果データファイル), which is exported from the shelf transfer detail screen in the logistics management system (物流管理システム). It transforms in-memory data beans — populated during the `outputCsv` flow via a service call to `DKSV0093` — into a structured CSV output with optional header records and detail records.

The method implements a **conditional builder pattern**: the structure of each CSV row depends on the "specification method" (指定方法) code. When the specification method is `"2"` (manufacturing serial number specification — 製番指定), every row in the output includes a header record, producing a fully itemized CSV where each line is self-describing. When the specification method is anything else (quantity specification — 数量指定), header records are inserted only at group boundaries — i.e., whenever the equipment delivery number (予備機器配送番号) changes between consecutive rows, or at the last row when it differs from the previous one.

Each header record (`buildHeaderRecord`) includes aggregated metadata: order date, lot number, source warehouse/office/society code, model number, manufacturing serial number, goods status code, and a computed item count for the group. Each detail record (`buildDataRecord`) captures the specific line-item data: model number, serial number, and quantity (always `1` for detail lines). The final CSV is assembled into a single `String`, logged for debug, and returned to the caller (`outputCsv`) which wraps it with a trailer record and triggers a file download.

The method plays the role of a **data-to-CSV transformer** within the logistics module, bridging the form-bean data layer and the file-download mechanism. It is not a shared utility; it is a private helper exclusively called by `outputCsv` within the same logic class.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["buildFile lotNo"])
    GET_DATA(["datas = getServiceFormBean.getDataBeanArray CSV_LIST"])

    GET_SHITEI["shiteicd = getData datas.getDataBean 0 SHITEI_WAY_04"]
    CHECK_COUNT{datas.getCount > 0}

    INIT_VARS["bodyRecords = new StringBuffer mvNo = empty"]
    FOR_LOOP["for i = 0 to datas.getCount"]
    CHECK_FIRST{i == 0}
    SET_MVNO["mvNo = getData datas.getDataBean i MOVE_NO_04"]

    CHECK_BODY{bodyRecords.length > 0}
    APPEND_SEP["bodyRecords.append LINE_SEPARATOR"]

    CHECK_SHITEI{shiteicd equals 2}
    HEADER_EVERY["bodyRecords.append buildHeaderRecord lotNo i"]
    APPEND_SEP2["bodyRecords.append LINE_SEPARATOR"]

    CHECK_FIRST_BODY{0 == i}
    HEADER_FIRST["bodyRecords.append buildHeaderRecord lotNo i"]
    APPEND_SEP3["bodyRecords.append LINE_SEPARATOR"]

    CHECK_MVNO_BOUNDARY{i + 1 <= datas.getCount}
    MVNO_CHANGED{mvNo not equals getData current MOVE_NO_04}
    HEADER_CHANGE["bodyRecords.append buildHeaderRecord lotNo i"]
    APPEND_SEP4["bodyRecords.append LINE_SEPARATOR"]

    CHECK_LAST{1 <= i and i + 1 == datas.getCount}
    LAST_MVNO_CHANGED{mvNo not equals getData i-1 MOVE_NO_04}
    HEADER_LAST["bodyRecords.append buildHeaderRecord lotNo i"]
    APPEND_SEP5["bodyRecords.append LINE_SEPARATOR"]

    UPDATE_MVNO["mvNo = getData datas.getDataBean i MOVE_NO_04"]
    APPEND_DATA["bodyRecords.append buildDataRecord datas.getDataBean i lotNo"]
    INCR_COUNT["record_count++"]
    BUILD_FILE["file = bodyRecords.toString"]
    DEBUG_LOG["DEBUG_LOG.debug file"]
    RETURN_FILE(["Return file"])

    START --> GET_DATA --> CHECK_COUNT
    CHECK_COUNT -- true --> GET_SHITEI
    CHECK_COUNT -- false --> INIT_VARS
    GET_SHITEI --> INIT_VARS
    INIT_VARS --> FOR_LOOP --> CHECK_FIRST
    CHECK_FIRST -- true --> SET_MVNO
    SET_MVNO --> CHECK_BODY
    CHECK_FIRST -- false --> CHECK_BODY
    CHECK_BODY -- true --> APPEND_SEP
    APPEND_SEP --> CHECK_SHITEI
    CHECK_BODY -- false --> CHECK_SHITEI
    CHECK_SHITEI -- true HEADER_EVERY --> APPEND_SEP2 --> APPEND_DATA
    CHECK_SHITEI -- false qty specified --> CHECK_FIRST_BODY
    CHECK_FIRST_BODY -- true i==0 --> HEADER_FIRST --> APPEND_SEP3 --> CHECK_MVNO_BOUNDARY
    CHECK_FIRST_BODY -- false i>0 --> CHECK_MVNO_BOUNDARY
    CHECK_MVNO_BOUNDARY -- true --> MVNO_CHANGED
    CHECK_MVNO_BOUNDARY -- false --> APPEND_DATA
    MVNO_CHANGED -- true --> HEADER_CHANGE --> APPEND_SEP4 --> CHECK_LAST
    MVNO_CHANGED -- false --> UPDATE_MVNO --> APPEND_DATA
    CHECK_LAST -- true --> LAST_MVNO_CHANGED
    CHECK_LAST -- false --> UPDATE_MVNO
    LAST_MVNO_CHANGED -- true --> HEADER_LAST --> APPEND_SEP5 --> UPDATE_MVNO
    LAST_MVNO_CHANGED -- false --> UPDATE_MVNO
    UPDATE_MVNO --> APPEND_DATA --> FOR_LOOP
    FOR_LOOP -- done --> BUILD_FILE --> DEBUG_LOG --> RETURN_FILE
```

**CRITICAL — Constant Resolution:**

| Constant | Resolved Value | Business Meaning |
|----------|---------------|------------------|
| `CSV_LIST` | `"棚移動結果情報一覧照会明細CSV用リスト"` (Shelf Transfer Result Information Summary Sheet CSV List) | Session list key for transfer result data beans |
| `SHITEI_WAY_04` | `"指定方法"` (Specification Method) | Field key identifying how items are specified |
| `MOVE_NO_04` | `"棚移動番号"` (Transfer Number) | Field key for the equipment delivery/transfer number — used to group rows |

**Branch logic:**
- **`shiteicd == "2"`**: Manufacturing serial number specification (製番指定). Headers attached to every row.
- **`shiteicd != "2"`**: Quantity specification (数量指定). Headers attached only at group boundaries where `MOVE_NO_04` changes or at the last row.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `lotNo` | `String` | **Shelf transfer lot number** (棚移動ロット番号) — A unique identifier for a batch of shelf transfer operations. It is embedded into every header and detail record in the CSV output, allowing the resulting file to be traced back to a specific transfer batch. |

**Instance fields read by this method:**

| Field | Type | Business Description |
|-------|------|---------------------|
| `record_count` | `int` | Running total of records processed. Incremented for each item in the loop (line 1002). Shared across all methods in this logic class that produce CSV output. |

**External state accessed:**

| Source | Access Pattern | Business Description |
|--------|---------------|---------------------|
| `getServiceFormBean()` | Returns `X31SDataBeanAccess`, then `.getDataBeanArray(CSV_LIST)` | Retrieves the session-held list of shelf transfer result data beans, pre-populated by the service call in `outputCsv` via `putServiceDKSV0093` |

## 4. CRUD Operations / Called Services

### Pre-computed evidence from code analysis graph:

The `buildFile` method performs **no direct database queries**. It operates entirely on in-memory data beans already loaded into the session form. All data retrieval comes from the `X31SDataBeanAccessArray` (a session-held list) and private helper methods.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `DKW01302SFLogic.buildDataRecord` | DKW01302SFLogic | - (In-memory bean) | Private method generating a CSV detail line from a single data bean. Reads fields: model codes, serial numbers, goods status code. |
| R | `DKW01302SFLogic.buildHeaderRecord` | DKW01302SFLogic | - (In-memory bean) | Private method generating a CSV header line. Reads: order date, source/destination warehouse codes, model numbers, serial numbers, moves count. Computes item count for quantity specification mode. |
| R | `X31SDataBeanAccessArray.getCount` | - | - (In-memory) | Returns the number of data beans in the session-held CSV list. |
| R | `X31SDataBeanAccessArray.getDataBean(int)` | - | - (In-memory) | Retrieves the data bean at the specified index from the session-held list. |
| R | `X31SDataBeanAccess.getDataBeanArray(String)` | - | - (In-memory) | Retrieves the list by key from the service form bean session. |
| R | `JDKWebCommon.getData(X31SDataBeanAccess, String)` | - | - (In-memory) | Extracts a string value from a data bean by field key. Used to read: `SHITEI_WAY_04`, `MOVE_NO_04`, `SJI_YMD_04`, `GDS_STAT_CD_04`, model codes, serial numbers, etc. |
| - | `JDKCommonUtil.isNull(String)` | - | - | Utility check for null/empty string. |
| - | `JDKCommonUtil.join(String, String...)` | - | - | Utility to join strings with a delimiter (used in `buildHeaderRecord` and `buildDataRecord`). |
| - | `dqot(String)` | - | - | Helper that wraps a value in double quotes for CSV output. |

**How this method fits in the larger data flow:**

1. `outputCsv()` calls `putServiceDKSV0093()` which queries the database (SC: likely `EKK...` series for stock/shelf transfer data) and populates the session `CSV_LIST`.
2. `buildFile()` reads from that session data — **no additional DB access**.
3. `buildHeaderRecord()` iterates the same list a second time (in quantity specification mode) to compute the `idoNo` (item count per group), but this is still purely in-memory.

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Logic:DKW01302SFLogic.outputCsv() | `DKW01302SFLogic.outputCsv()` -> `DKW01302SFLogic.buildFile(lotNo)` | `buildHeaderRecord [R]`, `buildDataRecord [R]` |

**Notes:**
- `outputCsv()` is the sole direct caller of `buildFile()`.
- `outputCsv()` is itself a public method on `DKW01302SFLogic`, likely invoked by the presentation framework when the user requests CSV download on the shelf transfer detail screen (DKW01302SF).
- The method does not have a direct screen entry point (no `KKSV*` class calls it). It is a private helper in a logic bean that is wired to a screen via the framework's method-invocation convention.
- Terminal operations from `buildFile`: all are **Read** from in-memory data beans. No SC codes, CBS, or DB entities are directly accessed from this method.

## 6. Per-Branch Detail Blocks

**Block 1** — [ASSIGN] (L935)
Retrieve the session-held CSV data list.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `datas = getServiceFormBean().getDataBeanArray(CSV_LIST)` |

---

**Block 2** — [ASSIGN] (L938)
Retrieve the specification method code from the first data bean (if any data exists).

| # | Type | Code |
|---|------|------|
| 1 | SET | `shiteicd = ""` |
| 2 | IF | `if (0 < datas.getCount())` |
| 3 | CALL | `shiteicd = getData(datas.getDataBean(0), SHITEI_WAY_04)` |

---

**Block 3** — [INIT] (L943)
Initialize the CSV body buffer and loop variables.

| # | Type | Code |
|---|------|------|
| 1 | SET | `bodyRecords = new StringBuffer()` |
| 2 | SET | `mvNo = ""` |

---

**Block 4** — [FOR LOOP] `(i = 0; i < datas.getCount(); i++)` (L945)
Iterate over each data bean in the session list. For each item, conditionally prepend a header record, then append a detail record.

| # | Type | Code |
|---|------|------|
| 1 | IF | Nested Block 4.1 — check for first iteration |
| 2 | IF | Nested Block 4.2 — check if body separator needed |
| 3 | IF | Nested Block 4.3 — branch on specification method |
| 4 | CALL | `bodyRecords.append(buildDataRecord(...))` |
| 5 | EXEC | `record_count++` |

---

**Block 4.1** — [IF] `(i == 0)` [first iteration] (L947)
On the first row, capture the equipment delivery number for group comparison.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `mvNo = getData(datas.getDataBean(i), MOVE_NO_04)` |

---

**Block 4.2** — [IF] `(bodyRecords.length() > 0)` [not first iteration] (L950)
After the first iteration, prepend a line separator (`\r
`) between records.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `bodyRecords.append(JDKStrConst.LINE_SEPARATOR)` |

---

**Block 4.3** — [IF] `("2".equals(shiteicd))` [shiteicd = "2" (製番指定 / Manufacturing Serial Number Specification)] (L954)
Every row gets a header record because each item is individually specified by serial number.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `bodyRecords.append(buildHeaderRecord(lotNo, i))` |
| 2 | EXEC | `bodyRecords.append(JDKStrConst.LINE_SEPARATOR)` |
| 3 | GOTO | -> Block 4.4 (detail record) |

**Block 4.3.1** — [ELSE] `shiteicd != "2"` [数量指定 / Quantity Specification] (L960)
Headers are inserted at group boundaries based on equipment delivery number changes.

**Block 4.3.1.1** — [IF] `(0 == i)` [first iteration in qty mode] (L963)
Always attach a header before the very first row.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `bodyRecords.append(buildHeaderRecord(lotNo, i))` |
| 2 | EXEC | `bodyRecords.append(JDKStrConst.LINE_SEPARATOR)` |

**Block 4.3.1.2** — [IF] `(i + 1 <= datas.getCount())` (L968)
Check if the current row is not the last — if the transfer number changes, insert a header for the new group.

| # | Type | Code |
|---|------|------|
| 1 | IF | Nested Block 4.3.1.2.1 — check if mvNo changed |
| 2 | GOTO | -> Block 4.3.1.3 |

**Block 4.3.1.2.1** — [IF] `(!mvNo.equals(getData(datas.getDataBean(i), MOVE_NO_04)))` [transfer number changed] (L972)
The equipment delivery number differs from the previous row's — start a new group with a header.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `bodyRecords.append(buildHeaderRecord(lotNo, i))` |
| 2 | EXEC | `bodyRecords.append(JDKStrConst.LINE_SEPARATOR)` |

**Block 4.3.1.3** — [IF] `(1 <= i && i + 1 == datas.getCount())` [last row] (L982)
The final row: if its transfer number differs from the previous row's, append a header to properly close out the previous group.

| # | Type | Code |
|---|------|------|
| 1 | IF | Nested Block 4.3.1.3.1 — check if mvNo changed from previous |
| 2 | GOTO | -> Block 4.3.1.4 |

**Block 4.3.1.3.1** — [IF] `(!mvNo.equals(getData(datas.getDataBean(i - 1), MOVE_NO_04)))` [last row's mvNo differs from previous] (L986)

| # | Type | Code |
|---|------|------|
| 1 | CALL | `bodyRecords.append(buildHeaderRecord(lotNo, i))` |
| 2 | EXEC | `bodyRecords.append(JDKStrConst.LINE_SEPARATOR)` |

**Block 4.3.1.4** — [IF] `(!mvNo.equals(getData(datas.getDataBean(i), MOVE_NO_04)))` [transfer number changed — update tracker] (L992)
Update the cached `mvNo` value for the next iteration's comparison.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `mvNo = getData(datas.getDataBean(i), MOVE_NO_04)` |

---

**Block 4.4** — [CALL] (L999)
Append the detail record for the current row.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `bodyRecords.append(buildDataRecord(datas.getDataBean(i), lotNo))` |
| 2 | EXEC | `record_count++` |

---

**Block 5** — [ASSIGN + RETURN] (L1004)
Convert the `StringBuffer` to a `String`, log it for debug, and return.

| # | Type | Code |
|---|------|------|
| 1 | SET | `file = bodyRecords.toString()` |
| 2 | EXEC | `DEBUG_LOG.debug(String.format("ファイル内容：%s", file))` |
| 3 | RETURN | `return file` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `lotNo` | Field | Shelf transfer lot number (棚移動ロット番号) — unique batch identifier for a shelf transfer operation |
| `shiteicd` | Variable | Specification method code (指定方法コード) — determines whether items are specified by serial number ("2") or by quantity |
| `mvNo` | Variable | Equipment delivery/transfer number (予備機器配送番号/棚移動番号) — used as a grouping key for header insertion in quantity specification mode |
| `SHITEI_WAY_04` | Constant | Field key "指定方法" (Specification Method) — used to extract the specification method from a data bean |
| `MOVE_NO_04` | Constant | Field key "棚移動番号" (Transfer Number) — used to extract the transfer number from a data bean for group boundary detection |
| `CSV_LIST` | Constant | Session key "棚移動結果情報一覧照会明細CSV用リスト" — holds the list of shelf transfer result data beans |
| `RECORD_KIHON` | Constant | Header record type indicator — appears as the first CSV field in header records |
| `RECORD_SHOSAI` | Constant | Detail record type indicator — appears as the first CSV field in detail records |
| `buildHeaderRecord` | Method | Generates a CSV header line containing aggregated transfer metadata (order date, source/destination, model, serial, count) |
| `buildDataRecord` | Method | Generates a CSV detail line containing per-item data (model, serial, quantity) |
| `buildTrailerRecord` | Method | Generates the trailer/final line of the CSV file (count, etc.) — called by `outputCsv` |
| `outputCsv` | Method | Entry point that orchestrates CSV generation: calls service, invokes `buildFile`, wraps with trailer, triggers download |
| `record_count` | Field | Instance counter tracking total records produced across the CSV output lifecycle |
| LINE_SEPARATOR | Constant | `"\r
"` — Windows-style line break used between CSV lines |
| `X31SDataBeanAccess` | Type | Session data bean — a key-value container holding transfer result fields |
| `X31SDataBeanAccessArray` | Type | Session data bean list — a collection wrapper for multiple data beans |
| `getServiceFormBean()` | Method | Returns the current session's form bean containing all screen data |
| `putServiceDKSV0093` | Method | Calls service component DKSV0093 to fetch shelf transfer data and populate the session list |
| `JDKWebCommon.getData` | Utility | Extracts a string value from a data bean by field key |
| `dqot` | Utility | Wraps a string value in double quotes for CSV field escaping |
| `JDKCommonUtil.join` | Utility | Joins multiple strings with a specified delimiter |
| 棚移動 (Tana Idou) | Business term | Shelf transfer — the logistics operation of moving inventory from one storage location to another |
| 製番指定 (Seban Shitei) | Business term | Manufacturing serial number specification — mode where each item is uniquely identified by its serial number |
| 数量指定 (Suryou Shitei) | Business term | Quantity specification — mode where items are grouped by transfer number and counted |
| 予備機器配送番号 (Yobi Kiki Haishin Bangou) | Business term | Equipment delivery number — groups related transfer items together |
| CSV_FILE_NAME | Constant | File name prefix for the output CSV file |
| FILE_CSV | Constant | File extension `.csv` |
| JDKStrConst.CHAR_SET_WIN31J | Constant | Character encoding — Windows CP932 (Microsoft version of Shift-JIS) for Japanese text |

---
