# Business Logic — JKKAdchgCheckerCC.maCheck() [90 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `com.fujitsu.futurity.bp.custom.common.JKKAdchgCheckerCC` |
| Layer | CC/Common Component (Package: `com.fujitsu.futurity.bp.custom.common`) |
| Module | `common` (Package: `com.fujitsu.futurity.bp.custom.common`) |

## 1. Role

### JKKAdchgCheckerCC.maCheck()

This method performs a **telephone office number block range validation** (番号区割一致確認) within the address change registration (住所変更登録) workflow. Specifically, it verifies whether the area block code (区域コード) associated with a customer's telephone number matches the area block code associated with their registered address. The method serves as a data consistency gate: before the system proceeds with address change processing, it confirms that the telephone number's serving office and the new address belong to the same geographic block, which is a prerequisite for local service delivery in K-Opticom's fiber-optic (eo光インターネット) network infrastructure.

The method implements a **serial three-step read pattern**: it queries the telephone number master to derive the office number (局番), then queries the office number master to obtain the office-level area block code, and finally queries the address master to retrieve all address-level area block codes. It then compares these codes to determine validity. The design follows a **guard-early / fail-fast** pattern -- if any data lookup fails or returns null, the method returns `true` (passing validation) rather than blocking the operation. The only case that returns `false` (failing validation) is when all three lookups succeed but the office-level and address-level area codes do not match.

A key design aspect is the fallback logic introduced in OM-2013-0003967 (20131102): when the telephone number master (EZM0121A010) returns no master data, the system falls back to deriving the office number directly from the first 6 digits of the phone number (the original behavior of returning `true` was commented out). This ensures that even in the absence of master data, the validation can proceed using the phone number itself.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["maCheck param, fixedText"])

    START --> GET["Get paramMap from param.getData fixedText"]
    GET --> ISNULL{paramMap == null}
    ISNULL -->|Yes| RET_TRUE1["Return true early"]
    ISNULL -->|No| EXTRCT["Extract telno and jyusyo_cd from paramMap"]
    RET_TRUE1 --> END_RETURN["Return / Next"]

    EXTRCT --> CHECKLEN{telno or jyusyo_cd empty or telno length < 6}
    CHECKLEN -->|True| RET_TRUE2["Return true early"]
    CHECKLEN -->|False| INIT["Initialize condMap, reqMap, resMap"]

    INIT --> GETMAPPER["Get JKKAdchgMapperCC instance and ServiceComponentRequestInvoker"]

    GETMAPPER --> STEP1["Step 1: Telephone Number Agreement Inquiry EZM0121A010"]
    STEP1 --> S1COND["Set COND_KEY_TELNO condition with telno"]
    S1COND --> S1CALL["mapper.setEZM0121A010 param, fixedText, condMap"]
    S1CALL --> S1RUN["scCall.run reqMap, keepSesHandle"]
    S1RUN --> S1GET["mapper.getEZM0121A010 param, fixedText, resMap"]
    S1GET --> S1CHECK["mapper.scResultCheck param"]

    S1CHECK --> S1RESULT{zm0121_a010 null or KYOKU_NO empty}
    S1RESULT -->|Yes| DERIVE["kyokuNo = telno.substring 0, 6"]
    S1RESULT -->|No| USEKYOKU["kyokuNo = zm0121_a010 KYOKU_NO"]

    DERIVE --> STEP2
    USEKYOKU --> STEP2["Step 2: Office Number Agreement Inquiry EZM0301A010"]

    STEP2 --> S2COND["Set COND_KEY_KYOKU_NO condition with kyokuNo"]
    S2COND --> S2CALL["mapper.setEZM0301A010 param, fixedText, condMap"]
    S2CALL --> S2RUN["scCall.run reqMap, keepSesHandle"]
    S2RUN --> S2GET["mapper.getEZM0301A010 param, fixedText, resMap"]
    S2GET --> S2CHECK["mapper.scResultCheck param"]

    S2CHECK --> S2RESULT{zm0301_a010 null or NO_KUKAKU_CD empty}
    S2RESULT -->|Yes| RET_TRUE3["Return true early"]
    S2RESULT -->|No| EXTRACTNO["Extract noKukakuC_Kyok from result"]

    EXTRACTNO --> STEP3["Step 3: Address Target Office Number Block Range Inquiry EZM0091B010"]
    STEP3 --> S3COND["Set COND_KEY_AD_CD condition with jyusyo_cd"]
    S3COND --> S3CALL["mapper.setEZM0091B010 param, fixedText, condMap"]
    S3CALL --> S3RUN["scCall.run reqMap, keepSesHandle"]
    S3RUN --> S3GET["mapper.getEZM0091B010 param, fixedText, resMap"]
    S3GET --> S3CHECK["mapper.scResultCheck param"]

    S3CHECK --> LOOP{"For each zm0091_b010_map in zm0091_b010_list"}
    LOOP --> ITER["Extract noKukakuCDs_Jusyo from map"]
    ITER --> MATCH{noKukakuC_Kyok equals noKukakuCDs_Jusyo}
    MATCH -->|Yes| RET_TRUE4["Return true - code matches"]
    MATCH -->|No| NEXTLOOP{"More records?"}
    NEXTLOOP -->|Yes| ITER
    NEXTLOOP -->|No| RET_FALSE["Return false - no match found"]
    RET_TRUE4 --> END_RETURN
    RET_FALSE --> END_RETURN
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `param` | `IRequestParameterReadWrite` | The request parameter object carrying the model group and control map for the address change process. It is accessed via `getData(fixedText)` to retrieve a HashMap containing business data such as the telephone number (`telno`) and address code (`jyusyo_cd`). |
| 2 | `fixedText` | `String` | A user-defined string used as a key to retrieve data from the `param` object. It identifies which data map within the request parameters to use (typically corresponds to a specific screen or processing context within the address change workflow). |

**Instance fields / external state read:**

| No | Field | Type | Business Description |
|----|-------|------|---------------------|
| 1 | `keepSesHandle` | `ThreadLocal<SessionHandle>` | Thread-local session handle storage. The session handle is set by the caller (`maChecker`) in the same thread, and this method reads it via `keepSesHandle.get()` to pass to the `ServiceComponentRequestInvoker` for maintaining session context across SC calls. |

## 4. CRUD Operations / Called Services

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `JKKAdchgMapperCC.getInstance` | - | - | Retrieves the singleton instance of the mapping component coordinator that handles service IF request/response mapping. |
| R | `ServiceComponentRequestInvoker.<init>` | - | - | Creates a new SC request invoker instance for executing service component calls. |
| R | `mapper.setEZM0121A010` | EZM0121A010 | Telephone Number Master | Sets up the request mapping for the telephone number agreement inquiry (電話番号照会), using the telephone number as the search key. Template ID: `EZM0121A010`. |
| R | `scCall.run` | EZM0121A010 | Telephone Number Master | Executes the telephone number inquiry service component with the mapped request and session handle. Returns the service result map. |
| R | `mapper.getEZM0121A010` | EZM0121A010 | Telephone Number Master | Extracts the output mapping from the SC response, retrieving fields including telephone number, office number (局番), and block code. |
| - | `mapper.scResultCheck` | EZM0121A010 | - | Checks the result status of the EZM0121A010 SC call for error conditions. |
| R | `mapper.setEZM0301A010` | EZM0301A010 | Office Number Master | Sets up the request mapping for the office number agreement inquiry (局番照会), using the derived office number (kyokuNo) as the search key. Template ID: `EZM0301A010`. |
| R | `scCall.run` | EZM0301A010 | Office Number Master | Executes the office number inquiry service component. |
| R | `mapper.getEZM0301A010` | EZM0301A010 | Office Number Master | Extracts the output mapping, retrieving the area block code (no_kukaku_cd) associated with the office number. |
| - | `mapper.scResultCheck` | EZM0301A010 | - | Checks the result status of the EZM0301A010 SC call. |
| R | `mapper.setEZM0091B010` | EZM0091B010 | Address Block Range Master | Sets up the request mapping for the address target office number block range inquiry (住所対象番号区割一覧照会), using the address code (jyusyo_cd) as the search key. Template ID: `EZM0091B010`. |
| R | `scCall.run` | EZM0091B010 | Address Block Range Master | Executes the address block range inquiry service component. Returns a list of area block codes for the address. |
| R | `mapper.getEZM0091B010` | EZM0091B010 | Address Block Range Master | Extracts the list of address block codes from the SC response. |
| - | `mapper.scResultCheck` | EZM0091B010 | - | Checks the result status of the EZM0091B010 SC call. |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Method: `maChecker` (JKKAdchgCheckerCC) | `JKKAdchgCheckerCC.maChecker` -> `JKKAdchgCheckerCC.maCheck` | `EZM0121A010 [R] Telephone Number Master`, `EZM0301A010 [R] Office Number Master`, `EZM0091B010 [R] Address Block Range Master` |

**Caller details:** The `maChecker` public method (lines 1395–1420) serves as the sole entry point to this private method. It performs session handle preservation, retrieves the same data map, initializes a `check_result` field, and delegates to `maCheck`. If `maCheck` returns `false`, the `check_result` is set to `CHECK_ERR` (error flag), signaling to the caller that the validation failed.

## 6. Per-Branch Detail Blocks

**Block 1** — [GET / SET] `(extract data map from param)` (L1432)

Retrieve the data map from the parameter object using the fixedText key.

| # | Type | Code |
|---|------|------|
| 1 | SET | `paramMap = param.getData(fixedText)` // Extract HashMap from param using fixedText key [-> FIXED_TEXT is a user-defined key string] |

**Block 2** — [IF] `(paramMap == null)` (L1433)

Guard clause: if no data map exists for the given fixedText key, the validation passes by default since there is nothing to validate.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return true` // No data map, skip validation |

**Block 3** — [EXTRACT] `(extract telno and jyusyo_cd)` (L1436-1437)

Pull the telephone number and address code from the data map.

| # | Type | Code |
|---|------|------|
| 1 | SET | `telno = (String) paramMap.get("telno")` // Extract telephone number |
| 2 | SET | `jyusyo_cd = (String) paramMap.get("jyusyo_cd")` // Extract address code |

**Block 4** — [IF] `(telno or jyusyo_cd empty or telno length < 6)` (L1438-1442)

Validation guard: if either the telephone number or address code is empty, or if the telephone number has fewer than 6 digits (insufficient for office number derivation), skip validation and pass. The length < 6 check was added in OM-2013-0003967 (星野 ADD, 20131102) to prevent substring errors when deriving office numbers from short phone numbers.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return true` // Insufficient data for validation |

**Block 5** — [INIT] `(initialize processing objects)` (L1445-1451)

Prepare the data structures and components needed for service IF calls.

| # | Type | Code |
|---|------|------|
| 1 | SET | `condMap = new HashMap<String, String>()` // Search condition map [-> Japanese: 照会事前準備 / English: pre-inquiry preparation] |
| 2 | SET | `reqMap` declared as `HashMap<String, Object>` // Request map for SC calls |
| 3 | SET | `resMap` declared as `Map<?, ?>` // Response map from SC calls |
| 4 | SET | `mapper = JKKAdchgMapperCC.getInstance()` // Get mapping coordinator instance [-> Japanese: 住所情報変更初期表示情報取得コマコンコンポーネント / English: address change info retrieval component] |
| 5 | SET | `scCall = new ServiceComponentRequestInvoker()` // Create SC request invoker [-> Japanese: SCリクエストInvokerを取得 / English: get SC request invoker] |

**Block 6** — [SERIES] `(Step 1: Telephone Number Agreement Inquiry)` (L1453-1468)

Execute the telephone number inquiry SC (EZM0121A010) to look up the office number (局番) associated with the telephone number.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `condMap.clear()` // Clear condition map [-> Japanese: 電話番号一意照会 / English: telephone number unique inquiry] |
| 2 | SET | `condMap.put(JKKAdchgMapperCC.COND_KEY_TELNO, telno)` // Set telephone number as search key [-> COND_KEY_TELNO = "cond_key_telno" (JKKAdchgMapperCC.java:1637)] |
| 3 | CALL | `reqMap = mapper.setEZM0121A010(param, fixedText, condMap)` // Build request mapping for SC [-> TEMPLATE_ID_EZM0121A010 = "EZM0121A010" (JKKAdchgMapperCC.java:479)] |
| 4 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` // Execute SC call with session handle [-> Japanese: SCリクエストInvokerを実行 / English: execute SC request invoker] |
| 5 | SET | `zm0121_a010 = mapper.getEZM0121A010(param, fixedText, resMap)` // Extract response data |
| 6 | EXEC | `mapper.scResultCheck(param)` // Check SC result for errors |

**Block 7** — [IF-ELSE] `(EZM0121A010 result null or KYOKU_NO empty)` (L1471-1478)

Handle the case where the telephone number master has no entry or the office number field is missing. The OM-2013-0003967 change (星野 MOD, 20131102) replaced the original `return true` with a fallback: extract the first 6 digits of the telephone number as the office number, allowing validation to continue. This is a soft degradation strategy (番号追加と判断 / "judge as number addition").

| # | Type | Code |
|---|------|------|
| 1 | SET | `kyokuNo` declared as `String` // Office number variable [OM-2013-0003967 ADD] |
| 2 | IF-ELSE | Check: `zm0121_a010 == null` OR `StringUtils.isEmpty(zm0121_a010.get(EZM0121A010CBSMsg1List.KYOKU_NO))` [-> Japanese: 電話番号マスタが取得できない場合は番号追加と判断し、電話番号の頭6桁を局番として使用 / English: if telephone number master cannot be retrieved, judge as number addition and use first 6 digits of phone number as office number] |
| 3 | THEN | `kyokuNo = telno.substring(0, 6)` // Derive office number from phone number |
| 4 | ELSE | `kyokuNo = zm0121_a010.get(EZM0121A010CBSMsg1List.KYOKU_NO)` // Use master data office number [-> Japanese: 局番 / English: office number] |

**Block 8** — [SERIES] `(Step 2: Office Number Agreement Inquiry)` (L1480-1492)

Query the office number master (EZM0301A010) using the derived or extracted office number to obtain the area block code (番号区割コード). The OM-2013-0003967 modification (星野 MOD, 20131102) changed the condition from using the raw `KYOKU_NO` from zm0121 to using the derived `kyokuNo` variable, ensuring the fallback phone number prefix is also routed through the office number lookup.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `condMap.clear()` // Clear condition map [-> Japanese: 局番一意照会 / English: office number unique inquiry] |
| 2 | SET | `condMap.put(JKKAdchgMapperCC.COND_KEY_KYOKU_NO, kyokuNo)` // Set office number as search key [-> COND_KEY_KYOKU_NO = "key_kyoku_no" (JKKAdchgMapperCC.java:1669)] |
| 3 | CALL | `reqMap = mapper.setEZM0301A010(param, fixedText, condMap)` // Build request for office number inquiry [-> TEMPLATE_ID_EZM0301A010 = "EZM0301A010" (JKKAdchgMapperCC.java:572)] |
| 4 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` // Execute SC call |
| 5 | SET | `zm0301_a010 = mapper.getEZM0301A010(param, fixedText, resMap)` // Extract response |
| 6 | EXEC | `mapper.scResultCheck(param)` // Check SC result |

**Block 9** — [IF] `(EZM0301A010 result null or NO_KUKAKU_CD empty)` (L1494-1496)

If the office number inquiry returns no result or the area block code (NO_KUKAKU_CD) is missing, the validation passes. The system defers to the address-based check in the subsequent step.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return true` // No area code from office lookup, defer |

**Block 10** — [SET] `(extract office-level area block code)` (L1499)

| # | Type | Code |
|---|------|------|
| 1 | SET | `noKukakuC_Kyok = zm0301_a010.get(EZM0301A010CBSMsg1List.NO_KUKAKU_CD)` // Office-level area block code [-> Japanese: 番号区割コード(局番) / English: area block code (office)] |

**Block 11** — [SERIES] `(Step 3: Address Block Range Inquiry)` (L1501-1510)

Query the address block range master (EZM0091B010) with the address code to retrieve all area block codes applicable to that address. This is a list-based inquiry — a single address may span multiple block ranges.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `condMap.clear()` // Clear condition map [-> Japanese: 住所対象番号区割一覧照会 / English: address target office number block range list inquiry] |
| 2 | SET | `condMap.put(JKKAdchgMapperCC.COND_KEY_AD_CD, jyusyo_cd)` // Set address code as search key [-> COND_KEY_AD_CD = "key_ad_cd" (JKKAdchgMapperCC.java:1667)] |
| 3 | CALL | `reqMap = mapper.setEZM0091B010(param, fixedText, condMap)` // Build request for address inquiry [-> TEMPLATE_ID_EZM0091B010 = "EZM0091B010" (JKKAdchgMapperCC.java:569)] |
| 4 | CALL | `resMap = scCall.run(reqMap, keepSesHandle.get())` // Execute SC call |
| 5 | SET | `zm0091_b010_list = mapper.getEZM0091B010(param, fixedText, resMap)` // Extract list of address block codes |
| 6 | EXEC | `mapper.scResultCheck(param)` // Check SC result |

**Block 12** — [FOR] `(iterate over address block list)` (L1512)

Iterate through all area block codes associated with the address. The loop checks each address block code against the office-level area block code.

| # | Type | Code |
|---|------|------|
| 1 | SET | `zm0091_b010_map` iterated from `zm0091_b010_list` // Each map represents one address block range record |

**Block 12.1** — [SET] `(extract address-level area block code)` (L1513)

| # | Type | Code |
|---|------|------|
| 1 | SET | `noKukakuCDs_Jusyo = zm0091_b010_map.get(EZM0301A010CBSMsg1List.NO_KUKAKU_CD)` // Address-level area block code [-> Note: uses EZM0301 field constant, not EZM0091] |

**Block 12.2** — [IF] `(noKukakuC_Kyok equals noKukakuCDs_Jusyo)` (L1516)

Compare the office-level area block code with the address-level area block code. If they match, the validation passes -- the telephone number and address are in the same geographic block.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return true` // [-> Japanese: 局番の区割コードと住所の区割コードが一致すればOK / English: OK if office block code matches address block code] |

**Block 13** — [RETURN] `(end of loop, no match found)` (L1520)

If the loop completes without finding a matching area block code between the office and address, the validation fails.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return false` // No area code match found |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `telno` | Field | Telephone number — the customer's phone number used to identify their serving office and block range |
| `jyusyo_cd` | Field | Address code (住所コード) — a code identifying the registered address, used to look up applicable area block ranges |
| `kyokuNo` | Field | Office number (局番) — the 6-digit prefix of a telephone number that identifies the serving telephone exchange/office |
| `noKukakuCD` | Field | Area block code (番号区割コード) — a geographic code that defines which telephone number block ranges are serviced by which exchange |
| `COND_KEY_TELNO` | Constant | Search condition key "cond_key_telno" — map key for telephone number search condition [-> JKKAdchgMapperCC.java:1637] |
| `COND_KEY_KYOKU_NO` | Constant | Search condition key "key_kyoku_no" — map key for office number search condition [-> JKKAdchgMapperCC.java:1669] |
| `COND_KEY_AD_CD` | Constant | Search condition key "key_ad_cd" — map key for address code search condition [-> JKKAdchgMapperCC.java:1667] |
| EZM0121A010 | SC Code | Telephone Number Agreement Inquiry (電話番号照会) — SC that retrieves telephone number master data including office number and block code |
| EZM0301A010 | SC Code | Office Number Agreement Inquiry (局番照会) — SC that retrieves office-level area block code from the office number master |
| EZM0091B010 | SC Code | Address Target Office Number Block Range List Inquiry (住所対象番号区割一覧照会) — SC that retrieves all area block codes applicable to a given address |
| KYOKU_NO | Field | Office number (局番) — derived from telephone number, identifies the serving exchange |
| NO_KUKAKU_CD | Field | Area block code (番号区割コード) — geographic code defining service area boundaries |
| `fixedText` | Parameter | User-defined string key — identifies which data map within the request parameter to use for this processing context |
| `maCheck` | Method | Area block consistency check (区割一致確認) — validates that telephone number and address share the same area block |
| `maChecker` | Method | Public entry point for area check — wraps maCheck with session handle management and result flagging |
| EO | Business term | eo — K-Opticom's brand name for its fiber-optic internet and broadband services (eo光インターネット, eo光テレビ, eo電話) |
| ServiceComponentRequestInvoker | Class | Infrastructure class that executes SC (Service Component) calls, managing session context and request/response mapping |
| `check_result` | Field | Validation result flag — set to CHECK_OK or CHECK_ERR to signal whether validation passed or failed |
