# Business Logic — JKKKapKeiInfoCancelCC.editErrorInfoComArray() [81 LOC]

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

## 1. Role

### JKKKapKeiInfoCancelCC.editErrorInfoComArray()

This method serves as the **central error consolidation and resolution dispatcher** in the K-Opticom cancellation processing pipeline. It is invoked by `callSCArray()` after a Service Component (SC) call returns results, and it bridges the gap between low-level SC error codes and the presentation layer's error reporting mechanism.

The method performs three coordinated business operations. **First**, it resolves the effective status code by comparing the SC return code against any previously set Business Process (BP) status, applying a fallback of 9000 when a non-zero return code is detected — and resetting to 0 when no localized message exists for that status. This ensures the most severe status always wins. **Second**, it stores the winning status code and its corresponding localized return message (looked up via the `RETURN_MESSAGE_XXXX` constant pattern) into the control map, making them available for screen-level error display. **Third**, it walks through a list of child records (e.g., service contract lines or cancellation items) and extracts per-field validation error messages (identified by `_err` suffix keys), consolidating them into a single flat map while avoiding duplicates. It also checks for a list-level aggregate error and appends that if present.

The method implements the **routing/dispatch pattern** with priority-based status resolution and the **collector pattern** for error message aggregation. As a shared utility within the common package, it is reused across all SC-call paths in the cancellation processing flow, ensuring consistent error handling and message localization.

The conditional branches are: (a) if `returnCode != 0`, the status is overridden to 9000 (a generic SC error); (b) if the formatted status has no corresponding `RETURN_MESSAGE_XXXX` entry, the status resets to 0 (unknown status, no error message); (c) if the template's status is higher than the BP's existing status, the template's status and message replace the BP's; (d) for each child record, only `_err` keys are extracted; (e) only errors not already in the map are added (first-write wins).

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["editErrorInfoComArray()"])
    S1["template = templates[0]"]
    S2["templateStatus = template.getInt(STATUS_INT_KEY)"]
    C1{returnCode != 0?}
    S3["templateStatus = 9000"]
    S4["Format: %04d"]
    S5["Lookup RETURN_MESSAGE_ + format"]
    C2{Lookup null?}
    S6["templateStatus = 0"]
    S7["bpStatus = control map RETURN_CODE or -1"]
    C3{templateStatus > bpStatus?}
    S8["Set RETURN_CODE and RETURN_MESSAGE"]
    S9["inMap = param.getData(dataMapKey)"]
    S10["templateArray = template.getCAANMsgList(inListMsgName)"]
    S11["Loop: for i in inList"]
    S12["childMap = inList[i]"]
    S13["Iterate childMap.keySet()"]
    C4{key starts with key_?}
    C5{childTemplate has key_err?}
    C6{inMap not contains key_err?}
    S14["inMap.put(key_err, childTemplate.getString(key_err))"]
    S15["Check template for list_err"]
    C7{template has list_err?}
    C8{inMap not contains list_err?}
    S16["inMap.put(list_err, template.getString(list_err))"]
    S17["Return param"]
    START --> S1 --> S2 --> C1
    C1 -- Yes --> S3
    C1 -- No --> S4
    S3 --> S4
    S4 --> S5 --> C2
    C2 -- Yes --> S6 --> S7
    C2 -- No --> S7
    S7 --> C3
    C3 -- Yes --> S8 --> S9
    C3 -- No --> S9
    S8 --> S9
    S9 --> S10 --> S11 --> S12 --> S13
    S13 --> C4
    C4 -- Yes --> C5
    C4 -- No --> S15
    C5 -- Yes --> C6
    C5 -- No --> S13
    C6 -- Yes --> S14 --> S13
    C6 -- No --> S13
    S14 --> S13
    S15 --> C7
    C7 -- Yes --> C8
    C7 -- No --> S17
    C8 -- Yes --> S16 --> S17
    C8 -- No --> S17
    S16 --> S17
```

**Processing Flow:**
1. Extract the first CAANMsg template from the SC result and read its status code.
2. If the SC returned a non-zero return code, override the status to 9000.
3. Check if a localized return message exists for the formatted status code (e.g., `RETURN_MESSAGE_9000`). If not found, reset status to 0 (no error to display).
4. Read the BP's existing status from the control map. If not set, default to -1.
5. If the template's status is higher, replace the control map with the template's status and message.
6. Retrieve the error map from param data, get the child template array, and iterate through all child records to extract per-field error messages.
7. Check for a list-level error and append it if not already present.
8. Return the param with consolidated error information.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `param` | `IRequestParameterReadWrite` | The request parameter object carrying the control map (containing status, return code, return message, and error info) and data maps. This is the primary vehicle for passing error state back to the screen layer. |
| 2 | `templates` | `CAANMsg[]` | The array of CAANMsg templates returned by the SC call. Contains the status code, per-field error messages (for each child record), and list-level error messages. `templates[0]` is always the primary template. |
| 3 | `returnCode` | `int` | The integer return code extracted from the SC result. If 0, the SC succeeded and no error resolution is triggered. If non-zero, it signals an SC-level failure and the status is overridden to 9000. |
| 4 | `dataMapKey` | `String` | The key used to retrieve the `HashMap<String, String>` from `param.getData()`. This map accumulates all error messages (per-field and list-level) that will be sent back to the screen. |
| 5 | `mappingData` | `Object[][]` | A 2D mapping array (unused in this method, but passed through from the caller `callSCArray`). It would contain field-level mapping configuration if used by upstream logic. |
| 6 | `inListMsgName` | `String` | The name/key used to retrieve a `CAANMsg[]` array of child templates from the parent template. Typically corresponds to a list of child records (e.g., service contract lines, cancellation items) and also serves as the prefix for the list-level error key (appending `_err`). |
| 7 | `inList` | `ArrayList<HashMap<String, Object>>` | The list of child records (maps) processed during the SC call. Each map contains key-value pairs for a single child record. The iteration count determines how many child templates' error messages are extracted. |

**External State / Instance Fields:**
- None directly read in this method. The method operates entirely on its parameters and returns the modified `param`.

## 4. CRUD Operations / Called Services

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| - | `CAANMsg.getInt` | - | - | Reads status code from SC return template |
| - | `JCMAPLConstMgr.getString` | - | - | Looks up localized return message by key (e.g., `RETURN_MESSAGE_9000`) |
| - | `param.getControlMapData` | - | - | Reads BP-level return code from control map |
| - | `param.setControlMapData` | - | - | Writes return code and return message to control map |
| - | `param.getData` | - | - | Retrieves error accumulation map by key |
| - | `CAANMsg.getCAANMsgList` | - | - | Retrieves child template array for list-level message unpacking |
| - | `CAANMsg.isNull` | - | - | Checks if a field exists/not null in CAANMsg template |
| - | `CAANMsg.getString` | - | - | Reads error message string from CAANMsg template |
| - | `HashMap.keySet` | - | - | Iterates over error message keys in child record map |
| - | `String.startsWith` | - | - | Filters keys to only extract `_err` suffixed fields |
| - | `HashMap.containsKey` | - | - | Checks for duplicate error messages before insertion |
| - | `HashMap.put` | - | - | Accumulates error messages into the consolidation map |

**Notes:**
- This method does **not** perform any database or SC-level CRUD operations directly. It operates entirely on **in-memory data structures** (CAANMsg templates, HashMaps, control maps).
- The `JCMAPLConstMgr.getString()` call is a **read** from a constant/message resource — not a database operation, but a localization resource lookup.
- The method reads error information produced by a prior SC call (made by `callSCArray`) and consolidates it for the presentation layer.

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | CBS: callSCArray (JKKKapKeiInfoCancelCC) | `JKKKapKeiInfoCancelCC.callSCArray` → `editErrorInfoComArray` | `CAANMsg.getInt [R]`, `JCMAPLConstMgr.getString [R]` |

**Caller Analysis:**
- `callSCArray()` (line 2189 of JKKKapKeiInfoCancelCC.java) is the **direct caller** and the sole caller of this method within this class.
- `callSCArray()` is itself a private method that wraps an SC invocation: it prepares the request map via `editInArrayMsg()`, calls the SC via `scCall.run()`, extracts the CAANMsg templates and return code, then delegates to `editErrorInfoComArray()` for error consolidation.
- No screen/batch entry points (KKSV*) are found within 8 hops — this method is a deep utility called through the CBS layer.

## 6. Per-Branch Detail Blocks

**Block 1** — [SET] (L2225)

> Extracts the first template from the SC result array and reads its status code.

| # | Type | Code |
|---|------|------|
| 1 | SET | `template = templates[0]` // Extract first SC result template |
| 2 | SET | `templateStatus = template.getInt(JCMConstants.STATUS_INT_KEY)` // Read status code from template |

---

**Block 2** — [IF] `(returnCode != 0)` (L2227)

> If the SC returned a non-zero error code, override the template status to 9000 (generic SC error). The original Japanese comment says: 「本来はサービスインターフェース分の処理が必要」(Originally, processing per service interface would be required) — meaning in the ideal design, the exact SC error code would be dispatched to different handling paths, but currently all non-zero codes converge to 9000.

| # | Type | Code |
|---|------|------|
| 1 | SET | `templateStatus = 9000` // Generic SC failure status override |

---

**Block 3** — [IF] `(JCMAPLConstMgr.getString(...) == null)` (L2232)

> Check if a localized return message exists for the current status. If no message key exists, the status is reset to 0 (no error to display).

| # | Type | Code |
|---|------|------|
| 1 | SET | `formatStatus = String.format("%1$04d", templateStatus)` // Format: e.g., "9000" or "0000" |
| 2 | EXEC | `JCMAPLConstMgr.getString("RETURN_MESSAGE_" + formatStatus)` // Lookup: RETURN_MESSAGE_9000 |
| 3 | SET | `templateStatus = 0` // Reset: unknown status, no message available |

---

**Block 4** — [IF] Read from control map (L2235–L2242)

> Read the BP-level (Business Process level) return code from the control map. If not set, default to -1. This establishes the "existing status" for comparison.

| # | Type | Code |
|---|------|------|
| 1 | SET | `bpStatus = 0` // Initialize |
| 2 | SET | `obj = param.getControlMapData(SCControlMapKeys.RETURN_CODE)` // Try to read BP return code |
| 3 | SET | `bpStatus = -1` // Default when not set |
| 4 | SET | `bpStatus = Integer.parseInt((String)param.getControlMapData(...))` // Parse existing status |

---

**Block 5** — [IF] `(templateStatus > bpStatus)` (L2244)

> The **priority resolution** block. If the template's status code is higher than the BP's existing status, update the control map with the template's status and localized message. This implements a "winner takes all" strategy — only the highest severity status is surfaced. The Japanese comment says: 「BPにサービスコンポーネントのステータスを設定する。」(Set the service component status on the BP.)

| # | Type | Code |
|---|------|------|
| 1 | SET | `formatStatus = String.format("%1$04d", templateStatus)` // Re-format status to fixed-width |
| 2 | SET | `message = JCMAPLConstMgr.getString("RETURN_MESSAGE_" + formatStatus)` // Lookup localized message |
| 3 | EXEC | `param.setControlMapData(SCControlMapKeys.RETURN_CODE, formatStatus)` // Write status to control map |
| 4 | EXEC | `param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, message)` // Write message to control map |

---

**Block 6** — [SET] (L2251–L2253)

> Prepare the error accumulation map and the child template array.

| # | Type | Code |
|---|------|------|
| 1 | SET | `inMap = (HashMap<String, String>)param.getData(dataMapKey)` // Get error consolidation map |
| 2 | SET | `templateArray = template.getCAANMsgList(inListMsgName)` // Get child templates for error extraction |

---

**Block 7** — [FOR LOOP] `for (int i = 0; i < inList.size(); i++)` (L2255)

> Iterate through each child record from the SC call result. For each child, extract per-field validation error messages whose keys end with `_err`. This is the core error consolidation loop.

| # | Type | Code |
|---|------|------|
| 1 | SET | `childMap = (HashMap)inList.get(i)` // Get child record map |
| 2 | SET | `childTemplate = templateArray[i]` // Get corresponding child template |

---

**Block 7.1** — [WHILE LOOP] `while (it.hasNext())` (L2258)

> Iterate over all keys in the child record map to find error fields.

| # | Type | Code |
|---|------|------|
| 1 | SET | `it = childMap.keySet().iterator()` // Create key iterator |
| 2 | SET | `key = (String)it.next()` // Get next key |

---

**Block 7.1.1** — [IF] `(key).startsWith("key_")` (L2262)

> Filter: only process keys that start with `key_`. This is a naming convention that identifies field-specific data entries in the child record. Non-key_ keys (like metadata or structural fields) are skipped.

| # | Type | Code |
|---|------|------|

---

**Block 7.1.1.1** — [IF] `!childTemplate.isNull(key + "_err")` (L2264)

> Check if the child template has an error message for this field. The `_err` suffix is appended to the field name to form the error key (e.g., `key_abc_err`). This follows the CAANMsg convention where error messages are stored as separate fields.

| # | Type | Code |
|---|------|------|

---

**Block 7.1.1.2** — [IF] `!inMap.containsKey(key + "_err")` (L2266)

> Only add the error message if it hasn't already been accumulated in the map. This prevents overwriting — the first occurrence (earlier in the list) wins. The Japanese comment says: 「エラー情報のマップを取得」(Get the error information map) — referring to the consolidation logic for the overall block.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `inMap.put(key + "_err", childTemplate.getString(key + "_err"))` // Append error message to consolidation map |

---

**Block 8** — [IF] `!template.isNull(inListMsgName + "_err")` (L2275)

> After processing all child records, check for a **list-level** aggregate error message. The `inListMsgName` (e.g., `childList`) is appended with `_err` to form the list error key (e.g., `childList_err`). This would contain a summary or overall validation error that applies to the entire list. The check follows the same duplicate-avoidance pattern.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `!inMap.containsKey(inListMsgName + "_err")` // Check for duplicate |
| 2 | EXEC | `inMap.put(inListMsgName + "_err", template.getString(inListMsgName + "_err"))` // Append list-level error |

---

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

> Return the modified `param` object, which now contains:
> - Updated control map: `RETURN_CODE` and `RETURN_MESSAGE` (highest-priority status)
> - Updated data map: All per-field error messages (key_err) and list-level error (inListMsgName_err)

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return param` // Return param with consolidated error info |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `CAANMsg` | Technical | CAAN message class — a message container used throughout the eo Customer Base system to carry structured data between layers. Supports typed getters (getInt, getString, isNull) and list access (getCAANMsgList). |
| `STATUS_INT_KEY` | Field | Status key constant — the key used to read the integer status code from a CAANMsg template. Represents the processing status returned by an SC call. |
| `RETURN_CODE` | Field | Return code key in the control map — stores the numerical status code for display on the screen. |
| `RETURN_MESSAGE` | Field | Return message key in the control map — stores the localized error/description message corresponding to the return code. |
| `ERROR_INFO` | Field | Error info key in the control map — stores a list of detailed error objects produced by TemplateErrorUtil. |
| `RETURN_MESSAGE_XXXX` | Constant Pattern | Message lookup key pattern — appends a 4-digit zero-padded status code to `RETURN_MESSAGE_` to find the localized message string (e.g., `RETURN_MESSAGE_9000`). |
| `bpStatus` | Field | Business Process status — the status previously set at the BP layer. Used as the baseline for priority comparison with SC-level status. |
| `templateStatus` | Field | Template status — the status code extracted from the SC return template. May be overridden to 9000 if a non-zero return code is detected. |
| `key_` | Field Prefix | Field data key prefix — all per-field data in child record maps use `key_` as a prefix to distinguish them from metadata. |
| `_err` | Field Suffix | Error field suffix — appended to a field name to form the error message key (e.g., `key_telephone_no_err` holds the error message for the telephone number field). |
| `inListMsgName` | Field | Input list message name — the name/key used to retrieve a CAANMsg[] array of child templates from the parent template. Also serves as the prefix for list-level error keys. |
| `inList` | Field | Input list — the ArrayList of child record maps. Each map represents one child item (e.g., one service contract line item in a cancellation request). |
| `inMap` | Field | Input map — the HashMap<String, String> that accumulates all error messages extracted from templates. Serves as the error consolidation buffer. |
| `param` | Parameter | Request parameter object — the IRequestParameterReadWrite interface that carries data maps (for business data) and control maps (for system metadata like status codes and error messages) between layers. |
| `SC` | Acronym | Service Component — a reusable business logic module that performs a specific business operation (e.g., cancellation processing, data registration). |
| `BP` | Acronym | Business Process — the higher-level orchestration layer that coordinates multiple SC calls and manages the overall transaction flow. |
| `CC` | Acronym | Common Component — a shared utility or coordinator class providing cross-cutting functionality used by multiple screens/processes. |
| `JCMConstants` | Class | JCM (Joint Common Message) Constants — a class holding constant keys for CAANMsg field access (e.g., STATUS_INT_KEY, TEMPLATE_LIST_KEY, RET_CD_INT_KEY). |
| `SCControlMapKeys` | Class | Service Component Control Map Keys — constants defining the keys used to store/retrieve system metadata in the request parameter's control map (e.g., RETURN_CODE, RETURN_MESSAGE, ERROR_INFO). |
| `JCMAPLConstMgr` | Class | JCM Application Constants Manager — a utility class for looking up localized strings and constant values by key name. |
| `callSCArray` | Method | The calling method in JKKKapKeiInfoCancelCC that wraps an SC invocation and delegates error processing to editErrorInfoComArray. |
| `K-Opticom` | Business term | K-Opticom — the NTT Group's fiber-optic telecommunications brand. This system manages customer subscription, cancellation, and modification operations. |
| `割当契約情報キャンセル` | Field (Japanese) | Allocated Contract Information Cancellation — the business domain of this class. Handles cancellation of previously allocated service contract information. |
