# JKKSvkeiShosaBaseCC

## Purpose

`JKKSvkeiShosaBaseCC` is the central base class for processing customer information updates in the eo Hikari NTT business system. It orchestrates the full lifecycle of a customer data review and update operation: reading customer inquiry results, determining membership types, mapping input data to update templates, calling service interfaces (SIF), and registering group/family memberships. This class exists to provide a reusable template for all customer-specific "shosa" (investigation/processing) workflows, where the exact data-fetching and message-editing strategies vary by screen but the overall orchestration logic is identical.

## Design

The class follows the **template method pattern**, implemented through a combination of concrete orchestration methods and abstract hooks. The single public-facing entry point is the `updCustinfo` method, which implements the full update pipeline. Subclasses implement four abstract methods (`getWorkParentData`, `getWorkData`, `editInMsgCmn`, `runShosa`) that handle the screen-specific details of data retrieval, message editing, and processing execution.

The class maintains **protected instance state** (mappers, current SYSID, pre-update member type code) shared across all methods, making it designed for **single-threaded use per instance** — each request should create a new instance or use a properly scoped container.

The architecture is layered:
- **Orchestration layer** (`updCustinfo`) decides the processing flow
- **Mapping layer** (`editMap*` methods) transforms inquiry results into update templates
- **SIF layer** (`callScCmn`) handles external service communication
- **Abstract hooks** are implemented by subclasses to provide screen-specific behavior

## Key Methods

### `updCustinfo` (lines 223–514) — Core Update Orchestrator

This is the heart of the class. It orchestrates the complete customer information update workflow.

**Parameters:**
- `param` — Request parameter object holding model group and control maps
- `handle` — Session handle for database and transaction management
- `rsltShokai` — HashMap containing inquiry result data (one-size-fits-all map)
- `prcGrpCd` — Price group code (e.g., `"02"` for Home, `"03"` for Maison)
- `svc_kei_no` — Service contract number
- `cntrAi` — Processing sequence number
- `errorList` — Accumulator for error information

**Return value:** The post-update member type code (`regitMemberSbtCd`)

**Processing flow:**
1. Retrieves customer inquiry data (`ECK0011A010`) via `getWorkParentData`, extracting member type, company type, and current SYSID
2. **Early return on withdrawal:** If the customer has a withdrawal date (`cust_taikai_ymd`), it calls `editCustKaihkMap` and the withdrawal CC, then returns early
3. **Price group filter:** Skips further processing for TV-related price groups (`PRC_GRP_CD_TV_KCN`, `PRC_GRP_CD_TV_SSS`)
4. **Member type routing:**
   - If already a master member (`MBTYPE_CD_MST_KOJIN` or `MBTYPE_CD_MST_HOJIN`), returns early (case: already a master member, or one service contract among multiple changed to master)
   - If company type is individual (`KSH_TYPE_CO_KOJIN`), sets member type to individual
   - If company type is corporate or self-company-use (`KSH_TYPE_CO_HOJIN` or `KSH_TYPE_CO_JISHA_USE`), sets to corporate
   - If company type is maintenance (`KSH_TYPE_CO_MNT`), inspects individual and corporate inquiry results to determine membership
5. **Hosting service sync (OM-2014-0001926):** Calls SIF via `EKK0081B519` to check for hosting service contracts (`SVC_CD = "JK40000"` with status `"100"`). If found, it maps and runs updates for individual/corporate customer info and contact registration
6. **Membership type change:** Calls `editMapMemberStb` to create update templates, optionally setting `dslAfSkssnsKh` (post-termination request form reference availability) to `"0"` when transitioning from Open member (`CD00039_OPEN`) to a master member
7. **Group registration:** If the customer was not a family member group (or was a pre-update family member), calls `editMapGrp` and `runMakeGrp` for group registration and group setting invalidation
8. **Integration data classification:** Uses `JKKBpCommon.putAxMRenkeiDataKbn` to classify integration data for the linkage system, distinguishing between new registration and update cases based on pre-update membership type

**Side effects:** Modifies `errorList` in place, sets `currentSysid` and `memberSbtCdBefore` instance fields, populates parameter maps with update templates.

### `editCustKaihkMap` (lines 526–544) — Customer Withdrawal Mapping

Prepares the customer withdrawal parameter map with the current SYSID, service contract number, and function code. Creates the target map in the request parameters if it doesn't exist.

### `editMapMemberStb` (lines 558–602) — Membership Type Change Mapping

Creates SIF update templates for membership type changes. Iterates over inquiry results, uses `shosaOkMapper.editInMsgECK0011C120` to generate the update message, then calls `editInMsgCmn` to finalize each template. The `dslAfSkssnsKh` parameter controls whether post-termination request form references are available.

### `callScCmn` (lines 613–651) — Service IF Invocation

Handles the full service interface call lifecycle:
1. Sets template common info via the mapper
2. Builds the SIF request map with template list
3. Invokes `ServiceComponentRequestInvoker().run()` to execute the SIF
4. Maps results back to request parameters via `editResultRP`
5. Checks for errors via `errChk`
6. Validates the return code (throws `Exception` if non-zero)
7. Returns the result message array

### `editResultRP` (lines 664–723) — SC Result to Parameter Mapping

Maps service component return values (status code, messages, errors) into the request parameter's control map. Uses `JCMAPLConstMgr` to look up human-readable messages by status code. Sets return code, return message, and error info in the control map. If the template status is worse than the existing BP status, it overwrites the BP status.

### `errChk` (lines 733–749) — Error Checking

Validates the SIF result by checking both the return code and template status. If either is non-zero, throws an `SCCallException` with the error code and status. This acts as a gate before processing results.

### `editMapCustKojin` (lines 759–807) — Individual Customer Update Mapping

Creates update templates for individual customer information changes (`ECK0021C010`). Iterates over both general customer inquiry results (`ECK0011A010`) and individual customer inquiry results (`ECK0021A010`), pairs them, calls `shosaOkMapper.editInMsgECK0021C010` for each pair, and accumulates results.

### `editMapCustHojin` (lines 817–865) — Corporate Customer Update Mapping

Same pattern as `editMapCustKojin` but for corporate customers (`ECK0031C010`), pairing general customer inquiry results with corporate customer inquiry results (`ECK0031A010`).

### `editMapRrks` (lines 875–979) — Contact Registration Mapping

Creates update templates for contact (contact information) registration. This method has two modes controlled by `renSakiInsertFlg`:
- **Update mode (`renSakiInsertFlg = false`):** If an existing contact has content-specific contact data (checked via `checkContRenSaki`), generates an update template (`ECK0201C010`)
- **Insert mode (`renSakiInsertFlg = true`):** If no existing contact has content-specific contact data, generates a new registration template (`ECK0201D010`)

The method also dynamically sets a `map_key` field in the result to indicate which operation was performed, which is later used by the caller.

### `runMakeGrp` (lines 991–1010) — Group Registration Execution

Runs two SIF processes in sequence: group registration (`ECK0111D010`) and customer group setting invalidation (`ECK0121C020`). Collects and returns any errors.

### `editMapGrp` (lines 1021–1081) — Group Registration Mapping

Creates update templates for group registration. If the pre-update member type was a family member (`CD00039_FAMILY_HOJIN` or `CD00039_FAMILY_KOJIN`), it additionally creates a template to invalidate the old customer group settings by retrieving the group setting number from inquiry results.

### `checkContRenSaki` (lines 1092–1111) — Contact Content Check

Returns `true` if a contact record is a content-specific contact, which requires different handling. A contact is content-specific when all three conditions hold:
- Contact method code (`RRK_WAY_CD`) is `"003"`
- Contact type code (`RRKS_SBT_CD`) is `"1"`
- Contact classification code (`RRKS_BUNRUI_CD`) is `"1"`

### Abstract Methods

| Method | Description |
|--------|-------------|
| `getWorkParentData(String workMapKey, Map<String, Object> rsltShokai, String shokaiMapKey)` | Retrieves parent-level work data. Implemented by subclasses to fetch data from the inquiry results map using the parent data key. |
| `getWorkData(String workMapKey, Map<?, ?> rsltShokai)` | Retrieves work data from a specific inquiry result. Implemented by subclasses for screen-specific data extraction. |
| `editInMsgCmn(IRequestParameterReadOnly param, CAANMsg msg)` | Edits common message data from a template. Implemented by subclasses with screen-specific mapping logic. |
| `runShosa(SessionHandle handle, IRequestParameterReadWrite param, HashMap<String, Object> rsltMap, String mapKey)` | Executes the processing (shosa) for a given map key. Implemented by subclasses to perform the actual SIF execution and result handling. |

## Relationships

```mermaid
flowchart TD
    subgraph BaseClass["JKKSvkeiShosaBaseCC"]
        updCustinfo["updCustinfo
Core update orchestrator"]
        editMapMemberStb["editMapMemberStb
Membership type change mapping"]
        editMapCustKojin["editMapCustKojin
Individual customer update mapping"]
        editMapCustHojin["editMapCustHojin
Corporate customer update mapping"]
        editMapRrks["editMapRrks
Contact registration mapping"]
        editMapGrp["editMapGrp
Group registration mapping"]
        callScCmn["callScCmn
Service IF invocation"]
        editResultRP["editResultRP
SC result to param mapping"]
        errChk["errChk
Error checking"]
        runMakeGrp["runMakeGrp
Group registration execution"]
        runShosa["runShosa
Abstract processing runner"]
        getWorkData["getWorkData
Abstract data retrieval"]
        getWorkParentData["getWorkParentData
Abstract parent data retrieval"]
        editInMsgCmn["editInMsgCmn
Abstract message common editing"]
        checkContRenSaki["checkContRenSaki
Check content contact validity"]
        editCustKaihkMap["editCustKaihkMap
Customer withdrawal mapping"]
    end

    subgraph Subclass["JKKSvkeiShosaCC"]
        impl["Implements abstract methods
getWorkData, getWorkParentData,
editInMsgCmn, runShosa"]
    end

    updCustinfo --> editMapMemberStb
    updCustinfo --> editMapCustKojin
    updCustinfo --> editMapCustHojin
    updCustinfo --> editMapRrks
    updCustinfo --> editMapGrp
    updCustinfo --> runMakeGrp
    updCustinfo --> editCustKaihkMap
    editMapMemberStb --> editInMsgCmn
    editMapCustKojin --> editInMsgCmn
    editMapCustHojin --> editInMsgCmn
    editMapRrks --> editInMsgCmn
    editMapGrp --> editInMsgCmn
    callScCmn --> editResultRP
    callScCmn --> errChk
    editMapCustKojin --> getWorkData
    editMapCustHojin --> getWorkData
    editMapRrks --> getWorkData
    editMapRrks --> checkContRenSaki
    editMapGrp --> getWorkData
    updCustinfo --> getWorkParentData
    runMakeGrp --> runShosa
    editMapMemberStb --> runShosa
    Subclass --> impl
```

### Dependency Summary

- **Inbound (1):** `JKKSvkeiShosaCC` extends this class, implementing the four abstract methods for a specific screen/workflow
- **Outbound (dependencies via fields):**
  - `JKKSvkeiShosaShokaiMapperCC` — Mapper for inquiry (shokai) results
  - `JKKSvkeiShosaShosaOkMapperCC` — Mapper for processing (shosa) OK templates
  - `JKKExclusiveMapper` — Exclusive update date management mapper
  - `ServiceComponentRequestInvoker` — Invokes service IF components
  - Various SIF mappers (`JKKSIFEKK0081Mapper`) for hosting service checks
- **External services:** `EKK0081B519` (hosting service contract inquiry), `ECK0011C120` (membership type change), `ECK0021C010` (individual customer update), `ECK0031C010` (corporate customer update), `ECK0201B001`/`ECK0201C010`/`ECK0201D010` (contact management), `ECK0111D010` (group registration), `ECK0121B020`/`ECK0121C020` (group settings)

## Usage Example

The typical usage pattern involves a subclass implementing the four abstract methods:

```java
// 1. Subclass must implement abstract hooks
public class JKKSvkeiShosaCC extends JKKSvkeiShosaBaseCC {

    @Override
    protected CAANMsg[] getWorkData(String workMapKey, Map<?, ?> rsltShokai) {
        // Screen-specific data retrieval from rsltShokai
    }

    @Override
    protected CAANMsg[] getWorkParentData(String workMapKey,
            Map<String, Object> rsltShokai, String shokaiMapKey) {
        // Screen-specific parent data retrieval
    }

    @Override
    protected HashMap<String, Object> editInMsgCmn(
            IRequestParameterReadOnly param, CAANMsg msg) {
        // Screen-specific message editing
    }

    @Override
    protected ArrayList<Object> runShosa(SessionHandle handle,
            IRequestParameterReadWrite param,
            HashMap<String, Object> rsltMap, String mapKey) {
        // Screen-specific processing execution
    }
}

// 2. Caller invokes the template method
JKKSvkeiShosaBaseCC cc = new JKKSvkeiShosaCC();
ArrayList<Object> errors = new ArrayList<>();
String memberType = cc.updCustinfo(param, handle, rsltShokai,
    "02", "12345678", 1, errors);
```

The flow within a single `updCustinfo` call:

```mermaid
flowchart TD
    A[getWorkParentData - fetch customer data] --> B{Has withdrawal date?}
    B -->|Yes| C[editCustKaihkMap + execute withdrawal]
    B -->|No| D{TV price group?}
    C --> E[Return member type]
    D -->|Yes| E
    D -->|No| F{Master member?}
    F -->|Yes| E
    F -->|No| G[Determine member type from company type]
    G --> H{Company type = maintenance?}
    H -->|No| I[Call SIF EKK0081 for hosting check]
    H -->|Yes| I
    I --> J{Hosting service found?}
    J -->|No| K[editMapMemberStb - membership change]
    J -->|Yes| L[Customer update + contact registration]
    L --> K
    K --> M{Pre-update = family member?}
    M -->|Yes| N[editMapGrp + runMakeGrp]
    M -->|No| N
    N --> O[Classification for linkage system]
    O --> E
```

## Notes for Developers

- **Thread safety:** This class is **not thread-safe**. It maintains mutable instance fields (`currentSysid`, `memberSbtCdBefore`, `shk_eoId`, and the three mapper fields). Each thread or request should have its own instance.
- **Abstract contract:** Subclasses must implement exactly four abstract methods. The base class calls these in specific contexts (e.g., `getWorkData` during `editMapCustKojin`, `runShosa` during `runMakeGrp`). The return types must be compatible.
- **Early return paths:** `updCustinfo` has multiple early return points (withdrawal, TV price group, master member) that bypass the standard update flow. Callers must handle these cases appropriately.
- **Error accumulation:** Errors are accumulated into the passed `errorList` via `addAll`. The method never throws from the error accumulation path itself — errors are collected for the caller to decide rollback behavior.
- **Membership type determination:** The logic for determining the post-update member type (`MBTYPE_CD_MST_KOJIN` vs `MBTYPE_CD_MST_HOJIN`) involves multiple nested conditions on company type codes and inquiry results. This logic has evolved over multiple issue fixes (noted by Japanese code comments referencing issue IDs like `ST2-2013-0000028`, `ANK-3179-00-00`, `OM-2014-0001926`).
- **Integration data classification:** At the end of `updCustinfo`, the class classifies data for the AX/M linkage system. The classification differs based on whether the pre-update membership type was Open, family member, or non-eo member — this determines whether the linkage marks the operation as ADD or UPD.
- **Mapper dependency:** The `shosaOkMapper` must be initialized by the subclass (via its abstract method implementations or constructor) before `updCustinfo` is called. If null, NPE will occur in any `editMap*` method.
- **Static constants:** The class defines a large set of static string constants for price group codes (`PRC_GRP_CD_*`), member type codes (`MBTYPE_CD_MST_*`), and company type codes (`KSH_TYPE_CO_*`) that serve as a shared vocabulary across the codebase.
- **CAANMsg arrays:** Many methods return `CAANMsg[]` rather than single `CAANMsg` objects, reflecting the SIF convention of returning message lists even when only one message is present.
