# Business Logic — JBSbatKKCourseChgFileBnkt.execute() [142 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `eo.business.service.JBSbatKKCourseChgFileBnkt` |
| Layer | Batch (koptBatch module) |
| Module | `service` (Package: `eo.business.service`) |

## 1. Role

### JBSbatKKCourseChgFileBnkt.execute()

This batch method is the main processing entry point for the **Course Change File Split** product (コース変更ファイル分割部品), a K-Opticom customer backbone system batch component. It reads a single CSV input file containing course change (service contract modification) records produced by upstream processing — and partitions each record into one of three output files based on the **work result code** (工事結果, koji_result) stored at index 11 of each CSV row. This is a classic file-routing/dispatch pattern with delegation to builder-style helper methods that assemble the output CSV rows.

The method implements a **dispatch-by-work-result-code** design pattern. When a record's work result is "1" (Work Completed), "2" (Work Postponed), "6" (Mobile), or "0" (No Work), the record is routed to the **Work Completion** output file via the `setKjFinStr()` builder. When the work result is "3" (Work Completion Cancelled), it is routed to the **Work Completion Cancel** output file via `setKjFinClStr()`. When the work result is "4" (Work Cancelled), it is routed to the **Work Cancel** output file via `setKjClStr()`. Records that do not match any of these codes are silently skipped.

This method serves as a **shared batch utility** invoked directly by the batch infrastructure (not by any screen controller or CBS) as part of the post-processing stage for service contract course changes. It is purely I/O-oriented — no database or remote SC calls are made.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["execute_start"])
    START --> INIT["Initialize 3 BufferedWriters: kjFinWr, kjFinClWr, kjClWr"]
    INIT --> READ["readFile in_file_path -> courseChgeList"]
    READ --> CHECK{"courseChgeList != null and size != 0"}
    CHECK --> true_label["List Valid"]
    CHECK --> false_label["List Empty or Null"]
    true_label --> LOOP["for each record in courseChgeList"]
    false_label --> FLUSH["Flush all writers"]
    LOOP --> RESET["fileName = empty string, data = record.split comma"]
    RESET --> DATACHK{"data != null"}
    DATACHK --> dataOk["Data Valid"]
    DATACHK --> dataNull["Data Null"]
    dataOk --> EXTRACT["Extract data[11] as kojiRslt"]
    dataNull --> LOOP
    EXTRACT --> DEBUGCHK{"logLevel == DEBUG"}
    DEBUGCHK --> debugYes["printDebugLog work result"]
    DEBUGCHK --> debugNo["Continue processing"]
    debugYes --> KONDICONDIT{"kojiRslt condition"}
    debugNo --> KONDICONDIT
    KONDICONDIT --> kondi1["1, 2, 6, or 0"]
    KONDICONDIT --> kondi3["3"]
    KONDICONDIT --> kondi4["4"]
    KONDICONDIT --> kondiDefault["Default"]
    kondi1 --> FIN["fileName = kjFinFile, setKjFinStr, write to kjFinWr"]
    kondi3 --> FINCL["fileName = kjFinClFile, setKjFinClStr, write to kjFinClWr"]
    kondi4 --> CL["fileName = kjClFile, setKjClStr, write to kjClWr"]
    kondiDefault --> LOOP
    FIN --> LOOP
    FINCL --> LOOP
    CL --> LOOP
    FLUSH --> FINALLY["Close all BufferedWriter in finally block"]
    FINALLY --> END["printDebugLog execute_END, return null"]
```

**Processing Flow:**

1. **Initialize output streams**: Creates three `BufferedWriter` instances for output files — `kjFinWr` (Work Completion), `kjFinClWr` (Work Completion Cancel), and `kjClWr` (Work Cancel). All use SJIS encoding (`JKKBatConst.SJIS`).
2. **Read input file**: Calls the private `readFile(in_file_path)` helper to load all lines from the CSV input file into an `ArrayList<String>`.
3. **List validation**: If the list is non-null and non-empty, iterates over each record; otherwise skips directly to flush/close.
4. **Per-record processing**: For each record, splits the CSV line on comma (`,`) with `split(",", -1)` to preserve trailing empty fields. Extracts the work result code from `data[11]`.
5. **Conditional dispatch**: Routes the record to the appropriate output file based on the work result code (constants resolved from `JBSbatKKConst`):
   - `KKIFM151_KOJI_RSLT_1 = "1"` / `KKIFM151_KOJI_RSLT_2 = "2"` / `KKIFM151_KOJI_RSLT_6 = "6"` / `KKIFM151_KOJI_RSLT_0 = "0"`: Work Completion file.
   - `KKIFM151_KOJI_RSLT_3 = "3"`: Work Completion Cancel file.
   - `KKIFM151_KOJI_RSLT_4 = "4"`: Work Cancel file.
6. **Flush and close**: Flushes all three writers, then closes them in the `finally` block. Returns `null`.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| - | `(none)` | - | This method takes no parameters. File paths are supplied via instance fields set during `initial()`. |

**Instance Fields Read by This Method:**

| Field Name | Type | Business Description |
|-----------|------|---------------------|
| `in_file_path` | `String` | Input file path — the full file system path to the CSV course change file to be split |
| `kj_fin_file_path` | `String` | Work Completion output file path — where records with work result 1/2/6/0 are written |
| `kj_fin_cl_file_path` | `String` | Work Completion Cancel output file path — where records with work result 3 are written |
| `kj_cl_file_path` | `String` | Work Cancel output file path — where records with work result 4 are written |

**Static Constants Referenced:**

| Constant | Value | Business Description |
|---------|-------|---------------------|
| `CONMA` | `","` | Comma delimiter used to split CSV records |
| `KARAMOJI` | `""` | Empty string — placeholder for "Work Case Cell Material Presence/Absence" (工事案件セル料有無) field 13 in the completion output, output as blank |

## 4. CRUD Operations / Called Services

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

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| - | `JBSbatKKCourseChgFileBnkt.readFile` | JBSbatKKCourseChgFileBnkt | - | Reads all lines from the input CSV file into an `ArrayList<String>` (File Read, no DB) |
| - | `JBSbatKKCourseChgFileBnkt.setKjFinStr` | JBSbatKKCourseChgFileBnkt | - | Assembles output CSV row for Work Completion records (1/2/6/0) by appending 23 data fields |
| - | `JBSbatKKCourseChgFileBnkt.setKjFinClStr` | JBSbatKKCourseChgFileBnkt | - | Assembles output CSV row for Work Completion Cancel records (3) by appending 14 data fields |
| - | `JBSbatKKCourseChgFileBnkt.setKjClStr` | JBSbatKKCourseChgFileBnkt | - | Assembles output CSV row for Work Cancel records (4) by appending 15 data fields |
| - | `JBSbatLogUtil.printDebugLog` | JBSbatLogUtil | - | Writes debug log messages at START, per-record work result, and END |
| - | `JBSbatLogUtil.chkLogLevel` | JBSbatLogUtil | - | Checks whether debug logging mode is enabled |

This method performs **no database CRUD operations**. It is a pure file-processing batch unit: it reads one input CSV file and writes three output CSV files, partitioning records by work result code. All called methods are internal helpers or logging utilities.

## 5. Dependency Trace

This method is a **batch entry point** invoked directly by the batch processing infrastructure (not called by any screen or CBS). No callers were found in the codebase that reference `JBSbatKKCourseChgFileBnkt.execute`. It is launched as an independent batch step — likely scheduled via cron or a batch scheduler such as Spring Batch.

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Batch: JBSbatKKCourseChgFileBnkt (Batch Entry) | Batch Scheduler -> JBSbatKKCourseChgFileBnkt.execute | File Read (input) + File Write (kjFinFile, kjFinClFile, kjClFile) |

## 6. Per-Branch Detail Blocks

**Block 1** — [TRY-CATCH-FINALLY] `(try block)` (L125)

> Opens the try block. Initializes three `BufferedWriter` output streams and reads the input file.

| # | Type | Code |
|---|------|------|
| 1 | SET | `kjFinWr = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(kj_fin_file_path), SJIS))` // Initialize Work Completion file writer (工事完了ファイル出力用BufferedWriter生成) |
| 2 | SET | `kjFinClWr = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(kj_fin_cl_file_path), SJIS))` // Initialize Work Completion Cancel file writer (工事完了取消ファイル出力用BufferedWriter生成) |
| 3 | SET | `kjClWr = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(kj_cl_file_path), SJIS))` // Initialize Work Cancel file writer (工事取消ファイル出力用BufferedWriter生成) |
| 4 | SET | `courseChgeList = new ArrayList<String>()` // Initialize course change record list (コース変更適応日更新中間ファイル読み込み) |
| 5 | CALL | `courseChgeList = readFile(in_file_path)` // Read all lines from input CSV file |
| 6 | EXEC | `if (courseChgeList != null && courseChgeList.size() != 0)` // Validate input list is non-null and non-empty |

**Block 1.1** — [IF-BRANCH] `(courseChgeList != null && courseChgeList.size() != 0)` (L136)

> Process each record in the input file. Iterates over all course change records.

| # | Type | Code |
|---|------|------|
| 1 | LOOP | `for(int i = 0; i < courseChgeList.size(); i++)` // Iterate over each record (入力リストのデータの分だけ繰り返す) |
| 2 | SET | `fileName = ""` // Reset filename per iteration (ファイル名初期化) |
| 3 | SET | `String[] data = new String[17]` // Allocate array for CSV fields |
| 4 | SET | `data = courseChgeList.get(i).split(",", -1)` // Split CSV line on comma, preserving trailing empty fields (レコードを取得) |
| 5 | EXEC | `if (data != null)` // Validate split result |

**Block 1.1.1** — [IF-BRANCH] `(data != null)` (L144)

> Process a single valid record. Extracts the work result code and dispatches to the appropriate output file based on its value.

| # | Type | Code |
|---|------|------|
| 1 | SET | `kojiRslt = ""` // Initialize work result variable (工事結果) |
| 2 | SET | `kojiRslt = data[11]` // Extract work result code from field 11 (工事結果の取得) |
| 3 | EXEC | `if (super.logPrint.chkLogLevel(JBSbatLogUtil.MODE_DEBUG))` // Check if debug logging is enabled |

**Block 1.1.1.1** — [IF-BRANCH, Nested] `(debug mode == true)` (L150)

> Optional debug logging of the extracted work result code.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `super.logPrint.printDebugLog("工事結果: " + kojiRslt)` // Log work result for debugging (ログレベルがデバッグモードの場合) |

**Block 1.1.2** — [IF-ELSE-IF-ELSE-IF] `(kojiRslt == "1" || "2" || "6" || "0")` (L159)

> **CONSTANT**: `KKIFM151_KOJI_RSLT_1 = "1"` (Work Completed / 工事完了)
> **CONSTANT**: `KKIFM151_KOJI_RSLT_2 = "2"` (Work Postponed / 工事正)
> **CONSTANT**: `KKIFM151_KOJI_RSLT_6 = "6"` (Mobile / モバイル)
> **CONSTANT**: `KKIFM151_KOJI_RSLT_0 = "0"` (No Work / 工事なし)
>
> **Business Description**: Records with work result "1" (Work Completed), "2" (Work Postponed), "6" (Mobile), or "0" (No Work) are written to the Work Completion output file. This covers successful, delayed, mobile, or nullified work records that all share the same completion disposition.

| # | Type | Code |
|---|------|------|
| 1 | SET | `fileName = kj_fin_file_path` // Set Work Completion file path (工事完了ファイル名設定) |
| 2 | SET | `StringBuilder kjFinstrBuilder = new StringBuilder()` // Initialize output string builder (工事完了用StringBuilder生成) |
| 3 | SET | `kjFinstrBuilder = setKjFinStr(kjFinstrBuilder, data)` // Build output row (工事完了用データ設定). Composes CSV fields: data[0] through data[22] (23 fields) |
| 4 | EXEC | `kjFinWr.write(kjFinstrBuilder.toString())` // Write record to Work Completion file (工事完了ファイル書き込み) |
| 5 | EXEC | `kjFinWr.newLine()` // Append line separator |

**Block 1.1.3** — [ELSE-IF] `(kojiRslt == "3")` (L177)

> **CONSTANT**: `KKIFM151_KOJI_RSLT_3 = "3"` (Work Completion Cancelled / 工事完了取消)
>
> **Business Description**: Records with work result "3" are cancelled completions. They are written to the Work Completion Cancel output file with 14 fields (data[0] through data[13], excluding some fields used in the completion output).

| # | Type | Code |
|---|------|------|
| 1 | SET | `fileName = kj_fin_cl_file_path` // Set Work Completion Cancel file path (工事完了取消ファイル名設定) |
| 2 | SET | `StringBuilder kjFinClstrBuilder = new StringBuilder()` // Initialize output string builder (工事完了取消用StringBuilder生成) |
| 3 | SET | `kjFinClstrBuilder = setKjFinClStr(kjFinClstrBuilder, data)` // Build output row (工事完了取消用データ設定). Composes CSV fields: data[0] through data[13] (14 fields) |
| 4 | EXEC | `kjFinClWr.write(kjFinClstrBuilder.toString())` // Write record to Work Completion Cancel file (工事完了取消ファイル書き込み) |
| 5 | EXEC | `kjFinClWr.newLine()` // Append line separator |

**Block 1.1.4** — [ELSE-IF] `(kojiRslt == "4")` (L195)

> **CONSTANT**: `KKIFM151_KOJI_RSLT_4 = "4"` (Work Cancelled / 工事取消)
>
> **Business Description**: Records with work result "4" are cancelled work orders. They are written to the Work Cancel output file with 15 fields (data[0] through data[14]).

| # | Type | Code |
|---|------|------|
| 1 | SET | `fileName = kj_cl_file_path` // Set Work Cancel file path (工事取消ファイル名設定) |
| 2 | SET | `StringBuilder kjClstrBuilder = new StringBuilder()` // Initialize output string builder (工事取消用StringBuilder生成) |
| 3 | SET | `kjClstrBuilder = setKjClStr(kjClstrBuilder, data)` // Build output row (工事取消用データ設定). Composes CSV fields: data[0] through data[14] (15 fields) |
| 4 | EXEC | `kjClWr.write(kjClstrBuilder.toString())` // Write record to Work Cancel file (工事取消ファイル書き込み) |
| 5 | EXEC | `kjClWr.newLine()` // Append line separator |

**Block 1.2** — [AFTER LOOP] `(loop iteration complete)` (L207)

> After processing all records, flush all three output writers to ensure data is written to disk.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `kjFinWr.flush()` // Flush Work Completion file buffer |
| 2 | EXEC | `kjFinClWr.flush()` // Flush Work Completion Cancel file buffer |
| 3 | EXEC | `kjClWr.flush()` // Flush Work Cancel file buffer |

**Block 2** — [CATCH] `(IOException e)` (L213)

> Catches `IOException` from file I/O operations and wraps it in a `JBSbatBusinessException` with message code `EKKB0250CE`, including the file name and error message.

| # | Type | Code |
|---|------|------|
| 1 | THROW | `throw new JBSbatBusinessException(JPCBatchMessageConstant.EKKB0250CE, new String[]{fileName, e.getMessage()})` // Wrap IO error with business exception |

**Block 3** — [FINALLY] `(always executes)` (L218)

> Ensures all three `BufferedWriter` instances are closed, even if an exception occurred. Uses null checks to prevent `NullPointerException`.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `if (kjFinWr != null) { kjFinWr.close(); }` // Close Work Completion file writer |
| 2 | EXEC | `if (kjFinClWr != null) { kjFinClWr.close(); }` // Close Work Completion Cancel file writer |
| 3 | EXEC | `if (kjClWr != null) { kjClWr.close(); }` // Close Work Cancel file writer |

**Block 4** — [POST-FINALLY] (L229)

> After try/catch/finally, log the end of processing and return.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `super.logPrint.printDebugLog("execute_END")` // Log completion (業務サービスの主処理を終了) |
| 2 | RETURN | `return null` // Returns null (JBSbatOutputItem) — no output item data (出力情報) |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `in_file_path` | Field | Input file path — full file system path to the source CSV course change file produced by upstream batch processing |
| `kj_fin_file_path` | Field | Work Completion output file path — destination for records where work was completed, postponed, was mobile, or was skipped |
| `kj_fin_cl_file_path` | Field | Work Completion Cancel output file path — destination for records where previously-completed work was cancelled |
| `kj_cl_file_path` | Field | Work Cancel output file path — destination for records where work was cancelled before completion |
| `kojiRslt` | Field | Work result code (工事結果) — a single-digit string code extracted from CSV field 11 that determines which output file a record belongs to |
| `KKIFM151_KOJI_RSLT_0` | Constant | Work result code "0" — No Work (工事なし), meaning no installation/repair work was required |
| `KKIFM151_KOJI_RSLT_1` | Constant | Work result code "1" — Work Completed (工事完了), meaning installation/repair work was successfully finished |
| `KKIFM151_KOJI_RSLT_2` | Constant | Work result code "2" — Work Postponed (工事正), meaning work is scheduled for a later date |
| `KKIFM151_KOJI_RSLT_3` | Constant | Work result code "3" — Work Completion Cancelled (工事完了取消), meaning a previously completed work order was cancelled |
| `KKIFM151_KOJI_RSLT_4` | Constant | Work result code "4" — Work Cancelled (工事取消), meaning a work order was cancelled before or during execution |
| `KKIFM151_KOJI_RSLT_6` | Constant | Work result code "6" — Mobile (モバイル), meaning the course change was applied via mobile/remote method |
| `CONMA` | Constant | Comma delimiter (",") used to split and join CSV fields |
| `KARAMOJI` | Constant | Empty string placeholder (空文字) — used for field 13 in the Work Completion output where Work Case Cell Material Presence/Absence is not applicable |
| `courseChgeList` | Variable | Course change record list — an `ArrayList<String>` holding all CSV lines from the input file |
| `setKjFinStr()` | Method | Work Completion CSV builder — assembles 23 CSV fields (data[0] through data[22]) into a single comma-delimited output row for work completion records |
| `setKjFinClStr()` | Method | Work Completion Cancel CSV builder — assembles 14 CSV fields (data[0] through data[13]) into a comma-delimited output row for work completion cancellation records |
| `setKjClStr()` | Method | Work Cancel CSV builder — assembles 15 CSV fields (data[0] through data[14]) into a comma-delimited output row for work cancellation records |
| `readFile()` | Method | Input file reader — reads all lines from a file path into an `ArrayList<String>` using `JBSbatInputFileUtil` with SJIS encoding and LF line separators |
| `data[0]` | CSV Field | Service Contract Number (サービス契約番号) |
| `data[1]` | CSV Field | Update Year/Month/Day/Time (更新年月日時刻) |
| `data[2]` | CSV Field | Discrepant Reservation Number 1 (異動予約番号1) |
| `data[3]` | CSV Field | Update Year/Month/Day/Time 1 (更新年月日時刻1) |
| `data[4]` | CSV Field | Service Code (サービスコード) |
| `data[5]` | CSV Field | Service Contract Detail Number 1 (サービス契約内訳番号1) |
| `data[6]` | CSV Field | Generation Registration Date 1 (世代登録年月日1) |
| `data[7]` | CSV Field | Service Contract Detail Number 2 (サービス契約内訳番号2) |
| `data[8]` | CSV Field | Generation Registration Date 2 (世代登録年月日2) |
| `data[9]` | CSV Field | Discrepant Reservation Number 2 (Discrepant Details Division) (異動予約番号2（解約内訳分）) |
| `data[10]` | CSV Field | Update Year/Month/Day/Time 2 (Discrepant Details Division) (更新年月日時刻2（解約内訳分）) |
| `data[11]` | CSV Field | Work Result Code (工事結果) — the dispatch key used to route records to output files |
| `data[12]` | CSV Field | Work Completion Date (工事完了日) |
| `data[13]` | CSV Field | Work Case Cell Material Presence/Absence (工事案件セル料有無) |
| `data[14]` | CSV Field | Application Detail Number (申込明細番号) |
| `data[15]` | CSV Field | Discrepant Division (異動区分) |
| `data[16]` | CSV Field | Work Case Number (工事案件番号) |
| `data[17]` | CSV Field | Price Group Code (料金グループコード) |
| `data[18]` | CSV Field | Service Contract Status (サービス契約ステータス) |
| `data[19]` | CSV Field | Discrepant Reservation Details Code (異動予約詳細コード) |
| `data[20]` | CSV Field | Old Price Plan Code (旧料金プランコード) — added in v26.00.00 for authentication ID unification |
| `data[21]` | CSV Field | New Price Course Code (新料金コースコード) — added in v51.00.00 for Netflix introduction |
| `data[22]` | CSV Field | Old Price Course Code (旧料金コースコード) — added in v51.00.00 for Netflix introduction |
| SJIS | Encoding | Shift JIS — Japanese character encoding used for all file I/O (JKKBatConst.SJIS) |
| JBSbatBusinessException | Class | Business service exception wrapper — thrown when file I/O or validation errors occur |
| EKKB0250CE | Message Code | File write/read error message code — used when IOException is caught during file processing |
| K-Opticom | Company | K-Opticom — the telecommunications company whose customer backbone system this batch belongs to |
| コース変更 (Course Change) | Domain term | Service contract course modification — the business process of changing a customer's telecom service plan or contract details |
| 工事結果 (Koji Result) | Domain term | Work result code — a classification of the status of installation/repair work performed as part of a course change, used to determine output routing |
| エo顧客基盤システム | System Name | eO Customer Backbone System — the overall system platform this batch belongs to |