# Business Logic — JBSbatKKSmtvlIdoInfSksi.getTchiTelnoJun() [97 LOC]

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

## 1. Role

### JBSbatKKSmtvlIdoInfSksi.getTchiTelnoJun()

This method determines which telephone number record (order 1 or order 2) should be treated as the primary notification target in ISP service contract processing. It is called when a customer has two telephone numbers registered under a single service contract, and the batch needs to decide which one's data to forward as the authoritative record. The decision logic follows a priority-based evaluation: if the provider code (`pcrsCd`) is `"A31"`, telephone number order 1 is always selected unconditionally. Otherwise, the method compares the two records' service charge start dates (`svc_chrg_staymd`) to select the older one, since the earlier-starting contract is considered the primary service. When both start dates are identical, the method falls back to comparing survey dates (`shosa_ymd`) to break the tie. If only one record has a start date, that record wins. When neither record has a start date, the survey dates are used as the final tiebreaker. This method implements a routing/dispatch pattern — it does not transform or modify data but rather resolves a choice between two competing records based on temporal precedence. It serves as a shared utility called by the batch's `mainProp()` and `setOutMapNetUpd()` methods to ensure consistent notification target selection across the ISP service contract processing pipeline. The fallback to survey dates was added in change ticket KT1-2013-0000816 to handle cases where the 2nd telephone number's charge start date matches the primary's, ensuring the older survey record is used for correlation.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["getTchiTelnoJun<br/>pcrsCd, tel1SvcChrgStaymd, tel2SvcChrgStaymd, tel1ShosaYmd, tel2ShosaYmd"])
    INIT["tchiTelnoJun = 1 (default)"]

    START --> INIT

    INIT --> COND1{"pcrsCd equals<br/>CD00134_A31 = \"A31\""}

    COND1 -->|Yes| RETURN1["tchiTelnoJun = 1"]
    COND1 -->|No| COND2{"Both tel1SvcChrgStaymd<br/>and tel2SvcChrgStaymd<br/>non-null?"}

    RETURN1 --> END(["Return tchiTelnoJun"])

    COND2 -->|Yes| COND3{"tel1SvcChrgStaymd equals<br/>tel2SvcChrgStaymd?"}
    COND2 -->|No| COND8{"tel1SvcChrgStaymd non-null<br/>tel2SvcChrgStaymd null?"}

    COND3 -->|Yes - Same Start Date| COND4{"Both tel1ShosaYmd<br/>and tel2ShosaYmd<br/>non-null?"}
    COND3 -->|No - tel1 older| SET_TEL1["tchiTelnoJun = 1"]
    COND3 -->|No - tel2 older| SET_TEL2["tchiTelnoJun = 2"]

    COND4 -->|Yes| COND5{"tel1ShosaYmd older<br/>than tel2ShosaYmd?"}
    COND4 -->|No - Survey dates missing| SET_DEFAULT["tchiTelnoJun = 1"]

    COND5 -->|Yes - tel1 older| SET_TEL1_A["tchiTelnoJun = 1"]
    COND5 -->|No - tel2 older| SET_TEL2_A["tchiTelnoJun = 2"]

    SET_TEL1 --> END
    SET_TEL2 --> END
    SET_DEFAULT --> END
    SET_TEL1_A --> END
    SET_TEL2_A --> END

    COND8 -->|Yes - tel1 set, tel2 null| SET_TEL1_B["tchiTelnoJun = 1"]
    COND8 -->|No| COND9{"Both tel1ShosaYmd<br/>and tel2ShosaYmd<br/>non-null?"}

    SET_TEL1_B --> END

    COND9 -->|Yes| COND10{"tel1ShosaYmd older<br/>than tel2ShosaYmd?"}
    COND9 -->|No - Survey dates missing| SET_DEFAULT_B["tchiTelnoJun = 1"]

    COND10 -->|Yes - tel1 older| SET_TEL1_C["tchiTelnoJun = 1"]
    COND10 -->|No - tel2 older| SET_TEL2_B["tchiTelnoJun = 2"]

    SET_DEFAULT_B --> END
    SET_TEL1_C --> END
    SET_TEL2_B --> END
```

**Branch summary:**

| Branch | Condition | Result | Business Meaning |
|--------|-----------|--------|------------------|
| B1 | `pcrsCd = "A31"` | Returns `1` | Provider A31 always uses telephone number order 1 |
| B2 | Both dates set and equal | Compare survey dates | Tiebreaker when charge start dates are identical |
| B3 | tel1 date older (lexicographically earlier) | Returns `1` | Earlier start date wins |
| B4 | tel2 date older (lexicographically later) | Returns `2` | The later-starting contract is not primary |
| B5 | Only tel2 has date | Returns `2` | The sole record with a date wins |
| B6 | Only tel1 has date | Returns `1` | The sole record with a date wins |
| B7 | Neither has a date | Fall back to survey dates | Ultimate fallback when charge dates are both absent |

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `pcrsCd` | `String` | Provider code / contract code that identifies the service provider or product category. When set to `"A31"` (constant `JKKStrConst.CD00134_A31`), the method unconditionally selects telephone number order 1, regardless of any date values. This represents a business rule for a specific provider where only the primary telephone number is ever used. |
| 2 | `tel1SvcChrgStaymd` | `String` | Service charge start year/month/day for telephone number order 1. Format is `YYYYMMDD` (e.g., `"20130801"`). Represents when billing started for the first telephone service contract. Used to determine temporal precedence — the older date is selected as the primary record. Retrieved from `JBSbatKK_T_SVC_KEI.SVC_CHRG_STAYMD` of the first record in the telephone list. |
| 3 | `tel2SvcChrgStaymd` | `String` | Service charge start year/month/day for telephone number order 2. Same format and business meaning as `tel1SvcChrgStaymd` but for the second telephone record. May be `null` when only one telephone number is registered. Retrieved from `JBSbatKK_T_SVC_KEI.SVC_CHRG_STAYMD` of the second record in the telephone list. |
| 4 | `tel1ShosaYmd` | `String` | Survey (investigation) year/month/day for telephone number order 1. Format is `YYYYMMDD`. Used as a tiebreaker when both service charge start dates are identical or when neither record has a charge start date. Represents when the field survey was conducted for the first telephone service. Retrieved from `JBSbatKK_T_SVC_KEI.SHOSA_YMD` of the first record. |
| 5 | `tel2ShosaYmd` | `String` | Survey (investigation) year/month/day for telephone number order 2. Same format and business meaning as `tel1ShosaYmd` but for the second telephone record. Used as the ultimate fallback for tiebreaking. May be `null` in edge cases. Retrieved from `JBSbatKK_T_SVC_KEI.SHOSA_YMD` of the second record. |

**External state / helper methods used:**

| Source | Description |
|--------|-------------|
| `isNull(String)` | Utility method in `JBSbatKKSmtvlIdoInfSksi` that checks whether a given string is `null` or blank (empty/whitespace). Used to guard date comparisons. |
| `JKKStrConst.CD00134_A31` | Constant with resolved value `"A31"` — provider code for a specific ISP service product. |

## 4. CRUD Operations / Called Services

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

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| - | `JBSbatKKSmtvlIdoInfSksi.isNull` | JBSbatKKSmtvlIdoInfSksi | - | Calls `isNull` in `JBSbatKKSmtvlIdoInfSksi` — utility method to check if a String is null or blank. Used to guard date comparisons. No database access. |

**Analysis:** This method is a pure decision/routing utility — it performs no database access, no entity creation, no CRUD operations of its own. It reads only its five parameters and calls the internal `isNull()` helper method. All data needed for its decision logic (charge start dates and survey dates) has already been fetched by the caller from the `KK_T_SVC_KEI` table (Service contract details table) via SQL queries that populate the `telList` before this method is invoked.

## 5. Dependency Trace

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

No screen/batch entry points found within 8 hops. Direct callers found: 2 methods.
Terminal operations from this method: `isNull` [-], `isNull` [-], `isNull` [-], `isNull` [-], `isNull` [-], `isNull` [-], `isNull` [-], `isNull` [-], `isNull` [-], `isNull` [-], `isNull` [-], `isNull` [-], `isNull` [-], `isNull` [-], `isNull` [-], `isNull` [-], `isNull` [-]  # NOSONAR

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Batch: `JBSbatKKSmtvlIdoInfSksi.mainProp()` | `mainProp()` → `getTchiTelnoJun(pcrsCd, tel1SvcChrgStaymd, tel2SvcChrgStaymd, tel1ShosaYmd, tel2ShosaYmd)` | `isNull` (utility, no CRUD) |
| 2 | Batch: `JBSbatKKSmtvlIdoInfSksi.setOutMapNetUpd()` | `setOutMapNetUpd()` → `getTchiTelnoJun(pcrsCd, tel1SvcChrgStaymd, tel2SvcChrgStaymd, tel1ShosaYmd, tel2ShosaYmd)` | `isNull` (utility, no CRUD) |

**Caller context details:**

- In `mainProp()` (around line 623): The caller fetches up to 2 telephone records from the service contract details table (`KK_T_SVC_KEI`) into a `telList`. It extracts `SVC_CHRG_STAYMD` and `SHOSA_YMD` from each record and passes them to `getTchiTelnoJun()`. The returned value is used to select which record from `telList` (index 0 or 1) becomes the authoritative `telMap` for further processing.

- In `setOutMapNetUpd()` (around line 1528): Similar pattern — extracts the same fields from the telephone list and uses the result to choose between record 0 (order 1) and record 1 (order 2).

## 6. Per-Branch Detail Blocks

**Block 1** — [INITIALIZATION] `(default setup)` (L2796)

> Initialize the result variable with the default value of telephone number order 1.

| # | Type | Code |
|---|------|------|
| 1 | SET | `tchiTelnoJun = 1` // Default: telephone number order 1 |

**Block 2** — [IF-ELSE] `(pcrsCd equals CD00134_A31 = "A31")` (L2799–L2889)

> Main decision block: If provider code is A31, always use telephone number 1. Otherwise, apply date-based comparison logic to determine the primary telephone number order.

| # | Type | Code |
|---|------|------|
| 1 | IF | `JKKStrConst.CD00134_A31.equals(pcrsCd)` [-> "A31"] // Provider code check |
| 2 | SET | `tchiTelnoJun = 1` // A31 always selects telephone number 1 |
| 3 | ELSE | // Proceed to date-based comparison |

**Block 2.1** — [IF] `(Both tel1SvcChrgStaymd and tel2SvcChrgStaymd are non-null)` (L2803)

> Both telephone records have service charge start dates. Compare the dates to determine which is older.

| # | Type | Code |
|---|------|------|
| 1 | IF | `!isNull(tel1SvcChrgStaymd) && !isNull(tel2SvcChrgStaymd)` // Both dates present |
| 2 | ELSE | // Only one or neither has a charge start date (Block 2.3) |

**Block 2.1.1** — [IF-ELSE-IF-ELSE] `(Compare service charge start dates)` (L2818–L2851)

> When both dates are set, compare them. If equal, fall back to survey dates. Otherwise, the lexicographically earlier date (older) determines the primary telephone number.

| # | Type | Code |
|---|------|------|
| 1 | IF | `tel1SvcChrgStaymd.compareTo(tel2SvcChrgStaymd) == 0` // Dates are identical |
| 2 | IF | `!isNull(tel1ShosaYmd) && !isNull(tel2ShosaYmd)` [-> Both survey dates present] (L2824) |
| 2.1 | IF | `tel1ShosaYmd.compareTo(tel2ShosaYmd) < 1` // tel1 survey older |
| 2.1.1 | SET | `tchiTelnoJun = 1` (L2826) // Select telephone number 1 |
| 2.1.2 | ELSE | `tchiTelnoJun = 2` (L2829) // Select telephone number 2 |
| 2.2 | ELSE | // Survey dates not both set |
| 2.2.1 | SET | `tchiTelnoJun = 1` (L2836) // Default to tel 1 |
| 3 | ELSE-IF | `tel1SvcChrgStaymd.compareTo(tel2SvcChrgStaymd) < 0` // tel1 is older (earlier date) |
| 3.1 | SET | `tchiTelnoJun = 1` (L2844) // tel1 wins because it started first |
| 4 | ELSE | // tel2 is older (earlier date) |
| 4.1 | SET | `tchiTelnoJun = 2` (L2848) // tel2 wins because it started first |

> **Business note:** Lexicographic string comparison on `YYYYMMDD` format correctly preserves chronological ordering. A smaller value means an earlier (older) date. The method selects the older service charge start date as the primary because the earlier-starting contract is considered the authoritative one for notifications.

**Block 2.2** — [IF-ELSE-IF] `(Only one telephone record has a charge start date)` (L2854–L2874)

> When exactly one of the two telephone records has a service charge start date, use that record as the primary. Also handle the edge case where neither record has a date.

| # | Type | Code |
|---|------|------|
| 1 | IF | `isNull(tel1SvcChrgStaymd) && !isNull(tel2SvcChrgStaymd)` // Only tel2 has date |
| 1.1 | SET | `tchiTelnoJun = 2` (L2856) // tel2 is the only valid record |
| 2 | ELSE-IF | `!isNull(tel1SvcChrgStaymd) && isNull(tel2SvcChrgStaymd)` // Only tel1 has date |
| 2.1 | SET | `tchiTelnoJun = 1` (L2866) // tel1 is the only valid record |
| 3 | ELSE | // Neither record has a charge start date |

**Block 2.2.3** — [IF] `(Neither record has a charge start date — fall back to survey dates)` (L2870)

> Ultimate fallback: when neither telephone record has a service charge start date, compare survey dates to break the tie.

| # | Type | Code |
|---|------|------|
| 1 | IF | `!isNull(tel1ShosaYmd) && !isNull(tel2ShosaYmd)` [-> Both survey dates present] |
| 1.1 | IF | `tel1ShosaYmd.compareTo(tel2ShosaYmd) < 1` // tel1 survey older |
| 1.1.1 | SET | `tchiTelnoJun = 1` // Select telephone number 1 |
| 1.1.2 | ELSE | `tchiTelnoJun = 2` // Select telephone number 2 |
| 1.2 | ELSE | // Survey dates not set (should not occur per comment) |
| 1.2.1 | SET | `tchiTelnoJun = 1` // Default to tel 1 |

> **Business note:** The comment on line 2834 states "調査年月日が設定されていないことは、ありえない" (It is not possible for survey dates to not be set). This indicates survey dates are expected to always be present on both records, making them a reliable ultimate tiebreaker.

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `pcrsCd` | Field | Provider code — identifies the ISP service provider or product category. Value `"A31"` triggers a business rule where telephone number 1 is always selected. |
| `svc_chrg_staymd` | Field | Service charge start year/month/day — the date when billing started for a service contract line item. Stored as `YYYYMMDD` string format. Used as the primary criterion for selecting the primary telephone record. |
| `shosa_ymd` | Field | Survey (investigation) year/month/day — the date a field survey was conducted for the service contract. Stored as `YYYYMMDD` string format. Used as a tiebreaker when service charge start dates are equal or absent. |
| `tchiTelnoJun` | Field | Primary telephone number order — the internal result variable (1 or 2) indicating which telephone number record is the authoritative one for notification purposes. |
| `tel1SvcChrgStaymd` | Field | Service charge start date for telephone number order 1. The first (primary) telephone record associated with the service contract. |
| `tel2SvcChrgStaymd` | Field | Service charge start date for telephone number order 2. The second (secondary) telephone record associated with the service contract. May be null if only one telephone is registered. |
| `tel1ShosaYmd` | Field | Survey date for telephone number order 1. |
| `tel2ShosaYmd` | Field | Survey date for telephone number order 2. |
| CD00134_A31 | Constant | Provider code constant with value `"A31"`. Represents a specific ISP service product where only the primary telephone number is ever used for notifications. |
| JBSbatKK_T_SVC_KEI | Entity | Service contract details table — stores records for each telephone number associated with a service contract, including charge start dates and survey dates. |
| KK_T_SVC_KEI | Table | The actual database table (Kopt Batch Service = KBS) containing ISP service contract detail records. Each telephone number gets one row. |
| `isNull()` | Method | Utility method that checks if a String parameter is `null`, empty, or whitespace-only. Used throughout the method to safely guard date comparisons. |
| ISP | Business term | Internet Service Provider — the domain context of this method. The batch processes ISP service contract orders. |
| Notification target | Business concept | The telephone record selected by this method. It determines which telephone number's data is forwarded as the authoritative source for downstream processing and customer notifications. |
| 調査日 (Shosa-bi) | Japanese term | Survey date — the date when a technician or representative conducted an on-site investigation for the service installation. |
| 課金開始日 (Sekini Kaishi-bi) | Japanese term | Service charge start date — the date when billing commenced for the service. |
| 電話番号順序 (Denwa bangoo jun) | Japanese term | Telephone number order — the positional index (1 or 2) assigned to each telephone record in the service contract. |
| KT1-2013-0000816 | Change ticket | Change request that added the survey date fallback logic (2番目で内線の課金開始日が同日の場合、調査日の古い方の内線の情報を連係する — When the 2nd telephone's charge start date is the same day, correlate the information from the telephone with the older survey date). |
| mainProp() | Method | Batch processing entry method in `JBSbatKKSmtvlIdoInfSksi` that orchestrates the main property data flow for ISP service contracts. Calls `getTchiTelnoJun()` to determine the primary telephone record. |
| setOutMapNetUpd() | Method | Batch processing method in `JBSbatKKSmtvlIdoInfSksi` that builds the output map for network update operations. Calls `getTchiTelnoJun()` for the same primary telephone selection. |
