# Business Logic — JBSBatKKKkOpDlRvAdd.callRule0091001() [94 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `eo.business.service.JBSBatKKKkOpDlRvAdd` |
| Layer | Service |
| Module | `service` (Package: `eo.business.service`) |

## 1. Role

### JBSBatKKKkOpDlRvAdd.callRule0091001()

This method is a **rule-driven date resolution dispatcher** within the K-Opticom batch processing system. Its primary business purpose is to determine the correct **reference date** (基準日 — * kijunbi ) for a device option service contract line item, based on a set of business rules defined in the SOKAN rule engine (RULE0091). It prepares a structured parameter map with computed business flags — including the update opportunity flag, disconnection charge eligibility flag, and billing start/after flag — then delegates to the rule engine which evaluates which reference date to return. The method ultimately returns one of four possible dates depending on the rule outcome: the service activation date (パターン 1), the service billing start date (パターン 2), the plan billing start date (パターン 3), or the operator-managed operation date (パターン 4). This method implements the **delegation + parameter preparation** design pattern, acting as a bridge between the batch service layer and the reusable SOKAN rule engine, ensuring that business-relevant context flags are computed and passed to the rules engine before date resolution.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["callRule0091001 params"])
    START --> INIT["Initialize outMsgList map"]
    INIT --> GETCSV["getCsv for JKTK_SVC_KEI_NO GENE_ADD_DTM"]
    GETCSV --> CHECK_SVC{KKOP_SVC_CD not blank?}
    CHECK_SVC -->|Yes| FILL_SVC["Put KKOP_SVC_CD into map"]
    CHECK_SVC -->|No| SKIP_SVC["Skip KKOP_SVC_CD"]
    FILL_SVC --> CHECK_IDO{ido_div not blank?}
    SKIP_SVC --> CHECK_IDO
    CHECK_IDO -->|Yes| FILL_IDO["Put IDO_DIV into map"]
    CHECK_IDO -->|No| SKIP_IDO["Skip IDO_DIV"]
    FILL_IDO --> SET_UPD["Put UPD_OPTY 0 into map"]
    SKIP_IDO --> SET_UPD
    SET_UPD --> CHECK_DSL{isKakinCheck true?}
    CHECK_DSL -->|Yes| DSL_CHRG1["Put DSL_JI_CHRG 0"]
    CHECK_DSL -->|No| DSL_CHRG0["Put DSL_JI_CHRG 1"]
    DSL_CHRG1 --> CHECK_CHRG{svc_chrg_staymd > svc_chrg_endymd?}
    DSL_CHRG0 --> CHECK_CHRG
    CHECK_CHRG -->|Yes| CHRG_BF["Put CHRG_STA_ZENGO 0"]
    CHECK_CHRG -->|No| CHRG_AF["Put CHRG_STA_ZENGO 1"]
    CHRG_BF --> RULE_CALL["createSokanRuleEngine getCheckResultArray"]
    CHRG_AF --> RULE_CALL
    RULE_CALL --> OUT_CHECK{outMsgList not null?}
    OUT_CHECK -->|Yes| GET_STD["stdDt from STD_DT"]
    OUT_CHECK -->|No| GET_STD
    GET_STD --> STD_1{stdDt equals 1?}
    STD_1 -->|Yes| RET_SVC_STAY["Return SVC_STAYMD"]
    STD_1 -->|No| STD_2{stdDt equals 2?}
    STD_2 -->|Yes| RET_CHRG_STAY["Return SVC_CHRG_STAYMD"]
    STD_2 -->|No| STD_3{stdDt equals 3?}
    STD_3 -->|Yes| RET_PLAN_CHRG["Return plan_chrg_staymd"]
    STD_3 -->|No| STD_4{stdDt equals 4?}
    STD_4 -->|Yes| RET_OPE["Return opeDate"]
    STD_4 -->|No| RET_SPACE["Return SPACE"]
    RET_SVC_STAY --> END(["Return date"])
    RET_CHRG_STAY --> END
    RET_PLAN_CHRG --> END
    RET_OPE --> END
    RET_SPACE --> END
```

**Conditional branch summary:**

| Branch | Condition | Constant Value | Business Meaning |
|--------|-----------|---------------|------------------|
| UPD_OPTY | Always set to `0` | `UPD_OPTY_ZERO = "0"` | Update opportunity flag: 0 = cancellation (解約時) |
| DSL_JI_CHRG | `isKakinCheck(...)` returns `true` | `DSLJI_CHRG_FLG_HIKAKIN = "0"` | Disconnection charge: 0 = non-chargeable (非課金) |
| DSL_JI_CHRG | `isKakinCheck(...)` returns `false` | `DSLJI_CHRG_FLG_KAKIN = "1"` | Disconnection charge: 1 = chargeable (課金) |
| CHRG_STA_ZENGO | `svc_chrg_staymd > svc_chrg_endymd` | `CHRG_STA_ZENGO_BF = "0"` | Billing start phase: 0 = before start (開始前) |
| CHRG_STA_ZENGO | `svc_chrg_staymd <= svc_chrg_endymd` | `CHRG_STA_ZENGO_AF = "1"` | Billing start phase: 1 = after start (開始後) |
| Return path 1 | `stdDt == "1"` | — | Return service activation date (サービス開始年月日) |
| Return path 2 | `stdDt == "2"` | — | Return service billing start date (サービス課金開始年月日) |
| Return path 3 | `stdDt == "3"` | — | Return plan billing start date (プラン課金開始年月日) |
| Return path 4 | `stdDt == "4"` | — | Return operator-managed operation date (opeDate) |

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `kkopSvKeiKeyMap` | `JBSbatCommonDBInterface` | Current record of the device option service contract (機器オプションサービス契約). Provides access to database-stored fields such as service code (KKOP_SVC_CD), billing start date (SVC_CHRG_STAYMD), and activation date (SVC_STAYMD). Serves as the primary data source for rule parameters. |
| 2 | `ido_div` | `String` | Migration division flag (異動区分). Indicates the type of contract migration operation. When non-blank, passed to the rule engine to inform context. |
| 3 | `plan_chrg_staymd` | `String` | Plan billing start date (プラン課金開始日). The billing start date of the underlying service plan. Used as a return candidate when the rule engine indicates reference date type "3". |
| 4 | `svc_chrg_endymd` | `String` | Service billing end date (サービス課金終了日). The date when service billing terminates. Used in the billing start phase comparison (`svc_chrg_staymd > svc_chrg_endymd`). |
| 5 | `svc_kei_no` | `String` | Service contract number (サービス契約番号). Identifies the service contract line item. Used in the disconnection charge determination alongside generation registration date and service code. |
| 6 | `gene_add_dtm` | `String` | Generation registration date and time (世代登録年月日). The timestamp when this generation/record version was registered. Used in the disconnection charge determination to identify the correct record generation. |
| 7 | `inMap` | `JBSbatServiceInterfaceMap` | Input message map (入力電文). Contains the serialized input data from the batch message, from which CSV-formatted service contract numbers and generation registration dates are extracted via `getCsv()`. |

**Instance fields read:**

| Field | Type | Business Description |
|-------|------|---------------------|
| `opeDate` | `String` | Operator-managed operation date. Used as the return value when the rule engine indicates reference date type "4" (サービス終了年月日 — service end date). |

## 4. CRUD Operations / Called Services

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `JBSBatKKKkOpDlRvAdd.getCsv` | — | — | Calls `getCsv()` to extract CSV-formatted data (e.g., KKTk_SVC_KEI_NO, GENE_ADD_DTM) from the input message map. |
| R | `JBSBatKKKkOpDlRvAdd.isKakinCheck` | — | — | Calls `isKakinCheck()` to determine whether a disconnection charge applies (解約時課金判定). Reads contract record data to decide charge eligibility. |
| C | `JCCBatCommon.createSokanRuleEngine` | — | — | Creates a SOKAN rule engine handler for RULE0091001 in single mode. Initializes the rule processing pipeline. |
| R | `JCCBatCommon.getCheckResultArray` | — | — | Executes the rule engine against the prepared parameter map and returns the check result array containing the resolved reference date code (STD_DT). |
| R | `kkopSvKeiKeyMap.getString` | — | KK_T_KKOP_SVC_KEI | Reads fields from the device option service contract entity: KKOP_SVC_CD, SVC_CHRG_STAYMD, SVC_STAYMD. |

**SC Code identification:**
- No explicit SC (Service Component) codes like `EKK0361A010SC` are present in this method's source code.
- The rule engine `RULE0091001` maps to the EJB rule class `JKKejbRule0091001` which performs data access via the entity data access `JKKejbKK2811ETDA`, reading from table `KK_T_KKOP_SVC_KEI` (機器オプションサービス契約テーブル — device option service contract table).

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Batch: JBSBatKKKkOpDlRvAdd | `insertKkopSvcKei()` -> `callRule0091001(kkopSvKeiKeyMap, ido_div, plan_chrg_staymd, svc_chrg_endymd, svc_kei_no, gene_add_dtm, inMap)` | `getCsv [R] inMap`, `getString [R] KK_T_KKOP_SVC_KEI`, `isKakinCheck [R] KK_T_KKOP_SVC_KEI`, `getCheckResultArray [R] RULE0091001` |

**Terminal operations from this method:** `getString` [R], `getCsv` [R], `isKakinCheck` [R], `createSokanRuleEngine` [C], `getCheckResultArray` [R], `getString` [R]. All terminal operations are **Read (R)** operations targeting the `KK_T_KKOP_SVC_KEI` table or the rule engine.

## 6. Per-Branch Detail Blocks

**Block 1** — [SET] Variable initialization (L3537)

| # | Type | Code |
|---|------|------|
| 1 | SET | `outMsgList = new ArrayList<ArrayList<HashMap<String, Object>>>()` // Rule result container |
| 2 | SET | `map = new HashMap<String, Object>()` // Rule parameter map |

**Block 2** — [SET] CSV data extraction (L3540–3541)

| # | Type | Code |
|---|------|------|
| 1 | SET | `kkop_svc_cd = JKKBatConst.SPACE` // Initialize to empty, resolved from SPACE constant |
| 2 | SET | `kktk_svc_kei_no = getCsv(JBSbatKKIFM554.KKTK_SVC_KEI_NO, inMap)` // Extract CSV service contract number from input |
| 3 | SET | `gene_add_dtm1 = getCsv(JBSbatKKIFM554.GENE_ADD_DTM, inMap)` // Extract CSV generation registration date from input |

**Block 3** — [IF] Service code extraction from key map (L3544–3547) — `KKOP_SVC_CD not blank`

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `kkopSvKeiKeyMap.getString(JBSbatKK_T_KKOP_SVC_KEI.KKOP_SVC_CD)` // Read service code from database record |
| 2 | SET | `map.put("KKOP_SVC_CD", ...)` // Pass to rule parameter map |
| 3 | SET | `kkop_svc_cd = kkopSvKeiKeyMap.getString(...)` // Store for disconnection charge check |

**Block 4** — [IF] Migration division propagation (L3550–3552) — `ido_div not blank`

| # | Type | Code |
|---|------|------|
| 1 | SET | `map.put("IDO_DIV", ido_div)` // Pass migration division to rule engine |

**Block 5** — [SET] Update opportunity flag (L3555)

| # | Type | Code |
|---|------|------|
| 1 | SET | `map.put("UPD_OPTY", UPD_OPTY_ZERO)` // `[-> UPD_OPTY_ZERO = "0"]` (Update opportunity: 0 = cancellation 解約時) |

**Block 6** — [IF] Disconnection charge determination (L3558–3564) — `isKakinCheck(...) true`

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `isKakinCheck(svc_kei_no, gene_add_dtm, kkop_svc_cd, kkopSvKeiKeyMap, kktk_svc_kei_no, gene_add_dtm1)` // Disconnection charge eligibility check |

**Block 6.1** — [IF branch: true] Chargeable flag set to non-chargeable (L3560–3561)

| # | Type | Code |
|---|------|------|
| 1 | SET | `map.put("DSL_JI_CHRG", DSLJI_CHRG_FLG_HIKAKIN)` // `[-> DSLJI_CHRG_FLG_HIKAKIN = "0"]` (Disconnection charge: non-chargeable 非課金) |

**Block 6.2** — [ELSE branch: false] Chargeable flag set to chargeable (L3563–3564)

| # | Type | Code |
|---|------|------|
| 1 | SET | `map.put("DSL_JI_CHRG", DSLJI_CHRG_FLG_KAKIN)` // `[-> DSLJI_CHRG_FLG_KAKIN = "1"]` (Disconnection charge: chargeable 課金) |

**Block 7** — [IF] Billing start phase determination (L3568–3581) — `svc_chrg_staymd > svc_chrg_endymd`

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `kkopSvKeiKeyMap.getString(JBSbatKK_T_KKOP_SVC_KEI.SVC_CHRG_STAYMD).compareTo(svc_chrg_endymd) > 0` // Compare billing start date with end date |

**Block 7.1** — [IF branch: true] Before billing start (L3570–3571)

| # | Type | Code |
|---|------|------|
| 1 | SET | `map.put("CHRG_STA_ZENGO", CHRG_STA_ZENGO_BF)` // `[-> CHRG_STA_ZENGO_BF = "0"]` (Billing start phase: before start 開始前) |

**Block 7.2** — [ELSE branch: false] After billing start (L3573–3575)

| # | Type | Code |
|---|------|------|
| 1 | SET | `map.put("CHRG_STA_ZENGO", CHRG_STA_ZENGO_AF)` // `[-> CHRG_STA_ZENGO_AF = "1"]` (Billing start phase: after start 開始後) |

**Block 8** — [CALL] Rule engine creation and execution (L3585–3586)

| # | Type | Code |
|---|------|------|
| 1 | SET | `xmlHandler = JCCBatCommon.createSokanRuleEngine(RULE0091001, JRuleXMLPattern.SINGLE_MODE_TYPE)` // `[-> RULE0091001 = "RULE0091001"]` Create SOKAN rule engine handler |
| 2 | SET | `outMsgList = JCCBatCommon.getCheckResultArray(xmlHandler, map)` // Execute rules, get result array with STD_DT |

**Block 9** — [SET] Initialize standard date (L3588–3589)

| # | Type | Code |
|---|------|------|
| 1 | SET | `stdDt = JKKBatConst.SPACE` // Initialized to empty, will be overwritten by rule result |
| 2 | COMMENT | `// rltDatCnt = JKKBatConst.SPACE;` // RELATIVE_DATE_COUNT unused at present |

**Block 10** — [IF] Extract STD_DT from rule result (L3591–3600) — `outMsgList.get(0) != null`

| # | Type | Code |
|---|------|------|
| 1 | SET | `stdDt = outMsgList.get(0).get(0).get("STD_DT").toString()` // Resolve reference date type code from rule engine |
| 2 | COMMENT | // `// rltDatCnt = outMsgList.get(0).get(0).get("RELATIVE_DATE_COUNT").toString();` // Unused |

**Block 11** — [IF/ELSE-IF] Reference date resolution (L3603–3626)

**Block 11.1** — [IF] `stdDt == "1"` (L3605–3607) — "Service activation date"

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `kkopSvKeiKeyMap.getString(JBSbatKK_T_KKOP_SVC_KEI.SVC_STAYMD)` // Return service activation date (サービス開始年月日) |

**Block 11.2** — [ELSE-IF] `stdDt == "2"` (L3610–3612) — "Service billing start date"

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `kkopSvKeiKeyMap.getString(JBSbatKK_T_KKOP_SVC_KEI.SVC_CHRG_STAYMD)` // Return service billing start date (サービス課金開始年月日) |

**Block 11.3** — [ELSE-IF] `stdDt == "3"` (L3616–3618) — "Plan billing start date"

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `plan_chrg_staymd` // Return plan billing start date (プラン課金開始年月日) — passed as parameter |

**Block 11.4** — [ELSE-IF] `stdDt == "4"` (L3621–3625) — "Service end date (operator-managed)"

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `this.opeDate` // Return operator-managed operation date (was formerly SVC_ENDYMD, changed in v7.00.05 correction) |

**Block 12** — [RETURN] Default fallback (L3626)

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `JKKBatConst.SPACE` // Return empty string when no rule result or unmatched stdDt |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `KKOP_SVC_CD` | Field | Service code (サービスコード) — classifies the type of device option service (e.g., FTTH, cable, wireless) |
| `IDO_DIV` | Field | Migration division (異動区分) — indicates the type of contract migration operation (transfer, change, extension) |
| `UPD_OPTY` | Field | Update opportunity (更新機会) — flag indicating the type of update: 0 = cancellation (解約時), 1 = start (開始時) |
| `DSL_JI_CHRG` | Field | DSL disconnection charge flag (DSL解約時課金フラグ) — 0 = non-chargeable (非課金), 1 = chargeable (課金) |
| `CHRG_STA_ZENGO` | Field | Billing start before/after (課金開始前/開始後) — 0 = before billing start (開始前), 1 = after billing start (開始後) |
| `STD_DT` | Field | Standard date (基準日) — rule engine output indicating which reference date type to return (1–4) |
| `SVC_STAYMD` | Field | Service activation date (サービス開始年月日) — the date the service was activated |
| `SVC_CHRG_STAYMD` | Field | Service billing start date (サービス課金開始年月日) — the date service billing begins |
| `SVC_CHRG_ENDYMD` | Field | Service billing end date (サービス課金終了日) — the date service billing terminates |
| `SVC_ENDYMD` | Field | Service end date (サービス終了日) — the date the service contract ends |
| `plan_chrg_staymd` | Field | Plan billing start date (プラン課金開始日) — the billing start date of the underlying plan |
| `gene_add_dtm` | Field | Generation registration date (世代登録年月日) — timestamp when this record generation was created |
| `opeDate` | Field | Operator-managed operation date (操作日) — system-managed date used as fallback for reference date type 4 |
| RULE0091001 | Constant | Rule ID for the SOKAN rule engine — business rules for determining reference dates for device option service contracts |
| SOKAN | Acronym | Rule evaluation framework (判断エンジン) — Fujitsu's rule engine platform used for business rule execution |
| `isKakinCheck` | Method | Disconnection charge eligibility check (解約時課金判定処理) — determines whether a disconnection fee applies based on contract status and timing |
| `getCsv` | Method | Extracts CSV-formatted values from the input message map (入力電文からCSV形式の値を取得) |
| KK_T_KKOP_SVC_KEI | Table | Device option service contract table (機器オプションサービス契約テーブル) — stores device option service contract records |
| JRuleXMLHandler | Class | SOKAN rule engine XML handler — manages rule engine lifecycle and execution |
| JCCBatCommon | Class | Common batch utility class — provides rule engine creation and result retrieval methods |
| v7.00.05 | Version | Version tag for the code correction period (修正開始/修正終了/追加開始/追加終了 markers) — introduced DSL charge determination and billing phase flag logic |
