# Business Logic — JBSbatKKFmtcelSodUpdInfCst.getLogMsgKojiStop() [47 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `eo.business.service.JBSbatKKFmtcelSodUpdInfCst` |
| Layer | Service (Batch processing layer) |
| Module | `service` (Package: `eo.business.service`) |

## 1. Role

### JBSbatKKFmtcelSodUpdInfCst.getLogMsgKojiStop()

The `getLogMsgKojiStop` method is a log-message assembly utility that retrieves and formats system identifiers and service contract numbers for use when a new-construction work order has been suspended/canceled. It acts as a **builder-pattern** helper: it iterates over the address-change detail records (`KK_T_ADCHG_DTL`) filtered by the change number, extracts the before-change and after-change service contract line numbers, and classifies each record into one of three business change types — **Addition** (only after-change exists), **Cancellation/Retention** (only before-change exists), or **Transfer** (both before and after exist). For Transfer records, it further distinguishes between a same-number transfer (identity-preserving) and a different-number transfer (cancellation plus new registration). The SYSID is fetched lazily (only once) from the service contract header table (`KK_T_SVC_KEI`) using the first resolved service contract number. The method is currently **not actively called** — its sole call site within `JBSbatKKFmtcelSodUpdInfCst.execute()` is commented out (disabled by OM-2014-0001680, dated 2014-04-28), meaning this code path is dormant but preserved for potential future re-enablement.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["getLogMsgKojiStop adchgNo"])

    START --> INIT["Initialize msgSvcKei and sysId"]

    INIT --> PARAM["Create paramList: adchgNo, SBT_CD 01"]

    PARAM --> QUERY["DB query: KK_T_ADCHG_DTL KK_SELECT_003"]

    QUERY --> FETCH["Fetch adchgDtl = selectNext"]

    FETCH --> CHECK_NULL{adchgDtl == null}

    CHECK_NULL -->|Yes| RETURN["Return SYSID and msgSvcKei"]

    CHECK_NULL -->|No| EXTRACT["Extract motoSvcKeiNo and sakiSvcKeiNo"]

    EXTRACT --> BOTH_NULL{Both null}

    BOTH_NULL -->|Yes| FETCH

    BOTH_NULL -->|No| ONE_NULL{One null}

    ONE_NULL -->|Yes: Addition or Cancellation or Retention| ADD_CASE{motoSvcKeiNo == null}

    ADD_CASE -->|Yes: sakiSvcKeiNo present| SET_SAKI["svcKeiNo = sakiSvcKeiNo"]

    ADD_CASE -->|No: motoSvcKeiNo present| SET_MOTO["svcKeiNo = motoSvcKeiNo"]

    SET_SAKI --> APPEND_SVC1["msgSvcKei append svcKeiNo"]

    SET_MOTO --> APPEND_SVC2["msgSvcKei append svcKeiNo"]

    APPEND_SVC1 --> CHECK_SYSID
    APPEND_SVC2 --> CHECK_SYSID

    ONE_NULL -->|No: Transfer| TRANSFER{motoSvcKeiNo equals sakiSvcKeiNo}

    TRANSFER -->|Yes: Same| APPEND_SAME["msgSvcKei append motoSvcKeiNo"]

    TRANSFER -->|No: Different| APPEND_DIFF["msgSvcKei append both numbers"]

    APPEND_SAME --> SET_SVC_TRANSFER
    APPEND_DIFF --> SET_SVC_TRANSFER

    SET_SVC_TRANSFER["svcKeiNo = motoSvcKeiNo"] --> CHECK_SYSID

    CHECK_SYSID{sysId empty and svcKeiNo set}

    CHECK_SYSID -->|Yes| GET_SYSID["getSysId svcKeiNo: query KK_T_SVC_KEI KK_SELECT_023"]

    CHECK_SYSID -->|No| FETCH

    GET_SYSID --> SET_SYSID["sysId = returned SYSID"]

    SET_SYSID --> FETCH
```

**Processing flow:**

1. **Initialization**: Local variables `msgSvcKei` and `sysId` are initialized to empty strings.
2. **Parameter Setup**: A `JBSbatCommonDBInterface` paramList is created. Two values are bound:
   - The input `adchgNo` (address-change number)
   - `ADCHG_DTL_SBT_CD_SVC_KEI_NO` = `"01"` (Address-change detail subtype code for service contract numbers)
3. **DB Query**: Executes `KK_T_ADCHG_DTL.selectBySqlDefine` using SQL key `KK_SELECT_003` to fetch address-change detail rows.
4. **Row Loop**: Iterates over each row from the query result.
   - If no more rows (`selectNext()` returns null), proceed to return.
   - If both `motoSvcKeiNo` (before-change service contract line number) and `sakiSvcKeiNo` (after-change service contract line number) are null, skip to the next row.
   - **Case A: Addition / Cancellation / Retention** — Exactly one of `motoSvcKeiNo` / `sakiSvcKeiNo` is null:
     - If `motoSvcKeiNo` is null: **Addition** (`追加`) — the `sakiSvcKeiNo` (after-change) is the new service contract line. Set `svcKeiNo = sakiSvcKeiNo`.
     - Otherwise: **Cancellation / Retention** (`解約、保留`) — the `motoSvcKeiNo` (before-change) is the affected service contract line. Set `svcKeiNo = motoSvcKeiNo`.
     - Append `" Service Contract Number:" + svcKeiNo` to the log message.
   - **Case B: Transfer** (`引越し`) — Both numbers are present:
     - If `motoSvcKeiNo.equals(sakiSvcKeiNo)`: Same-number transfer. Append `" Service Contract Number:" + motoSvcKeiNo`.
     - If different: Transfer with cancellation plus new registration (`引越し：解約＋新規`). Append `" Service Contract Number(move-from / move-to):" + motoSvcKeiNo + " / " + sakiSvcKeiNo`.
     - Set `svcKeiNo = motoSvcKeiNo`.
5. **SYSID Retrieval**: If `sysId` is still empty and a `svcKeiNo` was resolved, call `getSysId(svcKeiNo)` which queries `KK_T_SVC_KEI` via `KK_SELECT_023` to obtain the system identifier.
6. **Return**: Returns the formatted string `" SYSID:" + sysId + msgSvcKei`.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `adchgNo` | `String` | Address-change number — the unique identifier for an address-change event that triggers service contract modifications. Used as the primary key to look up related address-change detail records (`KK_T_ADCHG_DTL`) via SQL key `KK_SELECT_003`. |

**Instance fields read:**

| Field | Type | Business Description |
|-------|------|---------------------|
| `db_KK_T_ADCHG_DTL` | `JBSbatSQLAccess` | Database access handle for the `KK_T_ADCHG_DTL` (Address-change detail) table. |
| `db_KK_T_SVC_KEI` | `JBSbatSQLAccess` | Database access handle for the `KK_T_SVC_KEI` (Service contract) table, used by the called `getSysId` method. |

## 4. CRUD Operations / Called Services

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `db_KK_T_ADCHG_DTL.selectBySqlDefine` | KK_SELECT_003 | `KK_T_ADCHG_DTL` (Address-change detail) | Queries address-change detail rows filtered by `adchgNo` and subtype code `"01"` (service contract number subtype) |
| R | `JBSbatCommonDBInterface.getString` | - | - | Extracts `CHBF_SKBT_NO` (before-change service contract line number) and `CHAF_SKBT_NO` (after-change service contract line number) from the detail row |
| R | `getSysId(String)` | KK_SELECT_023 | `KK_T_SVC_KEI` (Service contract) | Looks up the SYSID for a given service contract number and operation date via `KK_T_SVC_KEI_KK_SELECT_023` |
| R | `JBSbatKK_T_SVC_KEI.getString` | - | - | Extracts `SYSID` field from the service contract row returned by `getSysId` |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Batch: `JBSbatKKFmtcelSodUpdInfCst` | `execute()` -> `getLogMsgKojiStop()` (COMMENTED OUT) | `KK_T_ADCHG_DTL [R]`, `KK_T_SVC_KEI [R]` |
| 2 | Batch: `JBSbatKKPlaceNoChgRnkiInfCst` | (has own local `getLogMsgKojiStop` method, line 853) | N/A — self-contained method, callers commented out |
| 3 | Batch: `JBSbatKKAdChgAddDataCst` | (has own local `getLogMsgKojiStop` method, line 2395) | N/A — self-contained method, callers commented out |
| 4 | Batch: `JBSbatKKSodUpdInfCst` | (has own local `getLogMsgKojiStop` method, line 1060) | N/A — self-contained method, callers commented out |
| 5 | Batch: `JBSbatKKSmtvlRnkiInfCst` | (has own local `getLogMsgKojiStop` method, line 518) | N/A — self-contained method, callers commented out |

**Note**: The call site to `getLogMsgKojiStop` in `JBSbatKKFmtcelSodUpdInfCst.execute()` (line 208) is fully commented out as part of OM-2014-0001680. This method is currently **orphaned / dormant** — no active code path invokes it. The same method signature is independently duplicated across 4 other batch service classes, each with its own commented-out call site, suggesting this was a feature that was designed but never activated, or was disabled and the references were removed in a rollback.

## 6. Per-Branch Detail Blocks

**Block 1** — VARIABLE DECLARATION (L568)

> Initialize local accumulators for the log message and SYSID.

| # | Type | Code |
|---|------|------|
| 1 | SET | `msgSvcKei = ""` // Initialize message accumulator [-> CONSTANT_NAME="empty string"] |
| 2 | SET | `sysId = ""` // Initialize SYSID holder [-> CONSTANT_NAME="empty string"] |

**Block 2** — DB QUERY SETUP (L571-L574)

> Build query parameters for fetching address-change detail records filtered by subtype code.

| # | Type | Code |
|---|------|------|
| 1 | SET | `paramList = new JBSbatCommonDBInterface()` // Create parameter container |
| 2 | EXEC | `paramList.setValue(adchgNo)` // Bind address-change number |
| 3 | EXEC | `paramList.setValue(ADCHG_DTL_SBT_CD_SVC_KEI_NO)` // Bind subtype code [-> CONSTANT `ADCHG_DTL_SBT_CD_SVC_KEI_NO = "01"` (Address-change detail subtype code: Service contract number)] |
| 4 | CALL | `db_KK_T_ADCHG_DTL.selectBySqlDefine(paramList, KK_T_ADCHG_DTL_KK_SELECT_003)` // Execute DB query KK_SELECT_003 on KK_T_ADCHG_DTL |

**Block 3** — WHILE LOOP: Row iteration (L575)

> Iterate over all address-change detail rows returned by the query.

| # | Type | Code |
|---|------|------|
| 1 | SET | `adchgDtl = db_KK_T_ADCHG_DTL.selectNext()` // Fetch next row |

**Block 3.1** — [IF] Null-check and break (L576-L578)

> Exit loop when no more rows exist.

| # | Type | Code |
|---|------|------|
| 1 | SET | `if (adchgDtl == null)` |
| 2 | EXEC | `break` // Exit the while loop |

**Block 4** — EXTRACT fields (L579-L581)

> Extract before-change and after-change service contract line numbers from the current detail row.

| # | Type | Code |
|---|------|------|
| 1 | SET | `motoSvcKeiNo = adchgDtl.getString(JBSbatKK_T_ADCHG_DTL.CHBF_SKBT_NO)` // Before-change service contract line number |
| 2 | SET | `sakiSvcKeiNo = adchgDtl.getString(JBSbatKK_T_ADCHG_DTL.CHAF_SKBT_NO)` // After-change service contract line number |
| 3 | SET | `svcKeiNo = null` // Temporary variable for resolved service contract line |

**Block 5** — [IF] Both null — skip record (L582-L584)

> If neither before nor after service contract line numbers exist, skip this row.

| # | Type | Code |
|---|------|------|
| 1 | SET | `if (motoSvcKeiNo == null && sakiSvcKeiNo == null)` |
| 2 | EXEC | `continue` // Skip to next row |

**Block 6** — [IF/ELSE] One null — Addition or Cancellation/Retention (L585)

> Exactly one of before/after exists. This covers Addition (追加) and Cancellation or Retention (解約、保留) scenarios.

**Block 6.1** — [IF] Addition: moto is null, saki is present (L586-L588)

> Addition case: only the after-change service contract line number is set.

| # | Type | Code |
|---|------|------|
| 1 | SET | `if (motoSvcKeiNo == null)` |
| 2 | SET | `svcKeiNo = sakiSvcKeiNo` // Addition (追加) — use after-change number |
| 3 | EXEC | `msgSvcKei += " Service Contract Number:" + svcKeiNo` // Append to log message [Japanese: `サービス契約番号`] |

**Block 6.2** — [ELSE] Cancellation/Retention: saki is null, moto is present (L589-L591)

> Cancellation or retention case: only the before-change service contract line number is set.

| # | Type | Code |
|---|------|------|
| 1 | SET | `else` |
| 2 | SET | `svcKeiNo = motoSvcKeiNo` // Cancellation / Retention (解約、保留) — use before-change number |
| 3 | EXEC | `msgSvcKei += " Service Contract Number:" + svcKeiNo` // Append to log message |

**Block 7** — [ELSE] Transfer scenario (L592)

> Both before and after exist. This is a Transfer (引越し) scenario.

**Block 7.1** — [IF] Same number transfer (L593)

> The before and after service contract line numbers are identical — identity-preserving transfer.

| # | Type | Code |
|---|------|------|
| 1 | SET | `if (motoSvcKeiNo.equals(sakiSvcKeiNo))` |
| 2 | EXEC | `msgSvcKei += " Service Contract Number:" + motoSvcKeiNo` // Same number transfer — single entry |

**Block 7.2** — [ELSE] Different number transfer (L594-L596)

> Cancellation of old contract plus new registration.

| # | Type | Code |
|---|------|------|
| 1 | SET | `else` // Transfer: Cancellation + New registration (引越し：解約＋新規) |
| 2 | EXEC | `msgSvcKei += " Service Contract Number(move-from / move-to):" + motoSvcKeiNo + " / " + sakiSvcKeiNo` // Append both numbers with separator [Japanese: `サービス契約番号(転居元・先)`] |
| 3 | SET | `svcKeiNo = motoSvcKeiNo` // Store before-change number for SYSID lookup |

**Block 8** — [IF] SYSID lazy fetch (L601-L603)

> Only fetch SYSID once, using the first service contract number resolved during the loop.

| # | Type | Code |
|---|------|------|
| 1 | SET | `if (" ".equals(sysId))` // Equivalent to `"".equals(sysId)` — SYSID not yet obtained |
| 2 | SET | `sysId = getSysId(svcKeiNo)` // Call helper method: query KK_T_SVC_KEI via KK_SELECT_023 |

**Block 9** — [RETURN] (L605)

> Assemble and return the formatted log message string.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return " SYSID:" + sysId + msgSvcKei` // Concatenate SYSID and all service contract numbers into a single log line |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `adchgNo` | Field | Address-change number — unique identifier for a housing/address change event in the K-Opticom system |
| `motoSvcKeiNo` | Field | Before-change service contract line number — the service contract line identifier prior to the address change |
| `sakiSvcKeiNo` | Field | After-change service contract line number — the service contract line identifier after the address change |
| `svcKeiNo` | Field | Service contract line number — the resolved service contract line identifier (before or after, depending on context) |
| `CHBF_SKBT_NO` | Field | Before-change service contract line number — column in `KK_T_ADCHG_DTL` table |
| `CHAF_SKBT_NO` | Field | After-change service contract line number — column in `KK_T_ADCHG_DTL` table |
| `ADCHG_DTL_SBT_CD_SVC_KEI_NO` | Constant | Address-change detail subtype code for service contract number = `"01"` — filters queries to service contract-related detail rows |
| `KK_T_ADCHG_DTL` | Table | Address-change detail table — stores line-level details of address-change events |
| `KK_T_SVC_KEI` | Table | Service contract table — stores service contract header records including SYSID |
| `KK_SELECT_003` | SQL Key | SQL definition key for querying address-change detail records by adchgNo and subtype code |
| `KK_SELECT_023` | SQL Key | SQL definition key for querying service contract records by svcKeiNo and opeDate (used by getSysId) |
| SYSID | Field | System identifier — a unique system-level ID associated with a service contract, used for cross-system correlation |
| Addition (追加) | Business term | Scenario where only a new (after-change) service contract line is created — no prior line exists |
| Cancellation/Retention (解約、保留) | Business term | Scenario where only a before-change service contract line exists — the line was cancelled or retained without a replacement |
| Transfer (引越し) | Business term | Scenario where both before and after service contract lines exist — the customer moved and their service was relocated |
| Transfer: Cancellation + New (引越し：解約＋新規) | Business term | A transfer where the before and after service contract line numbers differ, indicating a full cancellation of the old contract and creation of a new one |
| opeDate | Field | Operation date — the date associated with the batch processing operation, used as a filter in service contract queries |
| `getSysId` | Method | Helper method that queries `KK_T_SVC_KEI` to retrieve the SYSID for a given service contract number |
| `JBSbatCommonDBInterface` | Class | Framework data interface class used for building DB query parameters and holding result row data |
| `JBSbatSQLAccess` | Class | Framework database access class that provides `selectBySqlDefine` and `selectNext` methods for DB queries |
