# Business Logic — Transformer.transform() [80 LOC]

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

## 1. Role

### Transformer.transform()

The `WribSvcKeiMover.transform()` method (a private inner class implementing the `Transformer<CAANMsg, HashMap<String, String>>` interface, where `WribSvcKeiMover` is defined within `JKKWribSvcKeiOperateCC`) is a **service data transformation route** that maps raw service item records — specifically **discount/disbursement service contracts** and **non-disbursement service contracts** — from a `CAANMsg` input message into a normalized `HashMap<String, String>` output structure. It implements the **strategy / routing-dispatch design pattern**: based on a dispatch discrimination code (`WRIB_DCHS_HAMBET_CD`), the method branches between two service types — **disbursement (discount) services** (`KeiKind.WRIB`) and **non-disbursement services** (`KeiKind.HNSOKU`) — and populates the output map with the appropriate set of service contract fields from the corresponding message list constants. Its role in the larger system is a **shared data mapper** called by batch posting processors, transactional message adapters, credit/cash processing controllers, and information control services across the Fujitsu Futurity billing platform. The disbursement branch includes special date logic (v5.00.24) where the start date is computed as the day after the end date when the start date carries a placeholder value (`20991231`), ensuring proper billing period calculation. The non-disbursement branch has an additional override for network-phone-TV three-party bundle applications (`DT0000002`), where billing dates are intentionally cleared per the LT-2013-0000101 change request.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["WribSvcKeiMover.transform"])
    END_NODE(["Return out"])

    START --> INIT["Create out HashMap"]
    INIT --> GET_HAMBET["Read keiKind from WRIB_DCHS_HAMBET_CD"]
    GET_HAMBET --> COND1{keiKind is 1}

    COND1 -->|"Yes: Disbursement"| DISB_PATH
    COND1 -->|"No: Non-disbursement"| NONDISB_PATH

    DISB_PATH --> DISB_STAY["Read sYmd from SVC_CHRG_DCHSKMST_STAYMD"]
    DISB_STAY --> DISB_END["Read eYmd from SVC_CHRG_DCHSKMST_ENDYMD"]
    DISB_END --> DISB_DATE_COND{sYmd equals 20991231}
    DISB_DATE_COND -->|"Yes"| DISB_CHECK_END{eYmd valid and not 20991231}
    DISB_DATE_COND -->|"No"| DISB_MAP
    DISB_CHECK_END -->|"Yes"| DISB_CALC["sYmd = addDay(eYmd, 1)"]
    DISB_CHECK_END -->|"No"| DISB_MAP
    DISB_CALC --> DISB_MAP
    DISB_MAP --> DISB_MAP_F["Set all output fields for disbursement branch"]
    DISB_MAP_F --> DISB_RET["Return out"]

    NONDISB_PATH --> NONDISB_MAP_F["Set all output fields for non-disbursement branch"]
    NONDISB_MAP_F --> NONDISB_BUNDLE{WRISVC_DCHSKM_CD equals DT0000002}
    NONDISB_BUNDLE -->|"Yes: 3-party bundle"| NONDISB_CLR["Clear staymd and endymd"]
    NONDISB_BUNDLE -->|"No"| NONDISB_RET["Return out"]
    NONDISB_CLR --> NONDISB_RET

    NONDISB_RET --> END_NODE
    DISB_RET --> END_NODE
```

**Processing Description:**

1. **Initialization** — Creates a `HashMap<String, String>` with `DEFAULT_HASH_SIZE` (50) as the initial capacity.
2. **Dispatch Discrimination** — Reads the service kind discrimination code (`WRIB_DCHS_HAMBET_CD`) from the input `CAANMsg`. This field determines whether the service record represents a disbursement (discount) type or a non-disbursement type.
3. **Branch: Disbursement (折扣)** — When `keiKind` equals `"1"`, the method processes a **discount/disbursement service contract**. It reads the start date (`sYmd`) and end date (`eYmd`), then applies a date-computation rule (added in v5.00.24): if the start date is the sentinel value `20991231` and the end date is valid and also not the sentinel, the start date is recalculated as **end date + 1 day** using `JPCDateUtil.addDay()`. This handles the case where no explicit start date was recorded. All 12 service contract fields are then populated from the `DCHSKMST`-sourced message list constants, with the computed `sYmd` used for `staymd`.
4. **Branch: Non-disbursement (非折扣)** — When `keiKind` does NOT equal `"1"`, the method processes a **non-disbursement service contract**. It follows a similar field-mapping pattern but reads `staymd` directly from the source message (no date recalculation). After the base mapping, it checks a second condition: if `WRISVC_DCHSKM_CD` equals `"DT0000002"` (the 3-party bundle service code), both `staymd` and `endymd` are overwritten with empty strings, effectively clearing billing dates for network-phone-TV bundled applications as per requirement LT-2013-0000101.
5. **Return** — The populated output `HashMap` is returned to the caller.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `in` | `CAANMsg` | The input service item message carrying raw discount/non-disbursement service contract data. It contains fields such as the service item number (`WRIBSVK_DCHSKMST_NO`), service status (`WRIBSVK_DCHSKMST_STAT`), service kind discrimination code (`WRIB_DCHS_HAMBET_CD`), type code (`WRIB_DCHS_TYPE_CD`), campaign codes, billing period dates, and more. The actual field keys used are defined in `EKK0451B011CBSMsg1List`. |

**Instance fields / external state read:**
- `JKKWribSvcKeiOperateCC.KeiKind.WRIB.getKeiKind()` — An enum constant representing the disbursement service kind code.
- `JKKWribSvcKeiOperateCC.KeiKind.HNSOKU.getKeiKind()` — An enum constant representing the non-disbursement service kind code.
- `JPCDateUtil.addDay(String, int)` — A static utility method for date arithmetic, used in the disbursement branch.
- `JKKStringUtil.isNullBlank(String)` — A static utility method for null/blank string validation.

## 4. CRUD Operations / Called Services

Analyze all method calls within this method and classify each as a CRUD operation.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `CAANMsg.getString` | - | - | Reads field values from the input message `in` (message-level read, not a DB read) |
| R | `JPCDateUtil.addDay` | - | - | Reads and computes a date by adding days to a date string (date arithmetic utility, v5.00.24) |
| R | `JKKStringUtil.isNullBlank` | - | - | Checks whether a string is null or blank (null-validation utility) |
| C | `JKKWribSvcKeiOperateCC.KeiKind.WRIB.getKeiKind` | - | - | Returns the enum constant value for the disbursement service kind |
| C | `JKKWribSvcKeiOperateCC.KeiKind.HNSOKU.getKeiKind` | - | - | Returns the enum constant value for the non-disbursement service kind |

**Notes:**
- This method performs **no direct database access**. It is a pure data transformation (mapping) layer method that reads from a `CAANMsg` input object and writes to a `HashMap` output.
- The `CAANMsg` input itself is typically populated by upstream CBS (Core Banking System) screen components or batch processors that issue actual database reads against entity tables such as `EKK_M_WRIB_SVC_KEI` (Discount Service Item Master).
- The `JPCDateUtil.addDay()` call is a date utility that performs date arithmetic without database interaction.

## 5. Dependency Trace

**Direct callers of this method (pre-computed from code graph):**

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Batch: `JKKBatKKCashPostBase` | `JKKBatKKCashPostBase.execute()` -> `WribSvcKeiMover.transform` | `getString` [R] (CAANMsg) |
| 2 | Data: `Items` | `Items.map()` -> `WribSvcKeiMover.transform` | `getString` [R] (CAANMsg) |
| 3 | CBS: `JECNA0040001TPMA` | `JECNA0040001TPMA.invoke()` -> `WribSvcKeiMover.transform` | `getString` [R] (CAANMsg) |
| 4 | CBS: `JECNA0040002TPMA` | `JECNA0040002TPMA.invoke()` -> `WribSvcKeiMover.transform` | `getString` [R] (CAANMsg) |
| 5 | CBS: `JECNA0150001TPMA` | `JECNA0150001TPMA.callPost()` -> `WribSvcKeiMover.transform` | `getString` [R] (CAANMsg) |
| 6 | CBS: `JECNA0160001TPMA` | `JECNA0160001TPMA.callPost()` -> `WribSvcKeiMover.transform` | `getString` [R] (CAANMsg) |
| 7 | Controller: `JKKejbKKA0010002SecProc` | `JKKejbKKA0010002SecProc.searchCredit()` -> `WribSvcKeiMover.transform` | `getString` [R] (CAANMsg) |
| 8 | Controller: `JKKejbKKA001SecProc` | `JKKejbKKA001SecProc.shokaiOsrIrai()` -> `WribSvcKeiMover.transform` | `getString` [R] (CAANMsg) |
| 9 | Controller: `JKKejbKKA0110001SecProc` | `JKKejbKKA0110001SecProc.execute()` -> `WribSvcKeiMover.transform` | `getString` [R] (CAANMsg) |
| 10 | Controller: `JCKCtrlCisInfoImpl` | `JCKCtrlCisInfoImpl.call_CIS()` -> `WribSvcKeiMover.transform` | `getString` [R] (CAANMsg) |
| 11 | Controller: `JCKCtrlCisInfoStubImpl` | `JCKCtrlCisInfoStubImpl.call_CIS()` -> `WribSvcKeiMover.transform` | `getString` [R] (CAANMsg) |
| 12 | Controller: `JCRCtrlTnInfoImpl` | `JCRCtrlTnInfoImpl.ctrlTnInfo_CRA0001()` -> `WribSvcKeiMover.transform` | `getString` [R] (CAANMsg) |
| 13 | Controller: `JKKCtrlMvnoSvcKeiInfoImpl` | `JKKCtrlMvnoSvcKeiInfoImpl.ctrlMvnoInfo_KKA0003()` -> `WribSvcKeiMover.transform` | `getString` [R] (CAANMsg) |
| 14 | Controller: `JZMCtrlCisInfoImpl` | `JZMCtrlCisInfoImpl.ctrlCisInfo_ZMA0001()` -> `WribSvcKeiMover.transform` | `getString` [R] (CAANMsg) |
| 15 | Controller: `JZMCtrlTrankInfoImpl` | `JZMCtrlTrankInfoImpl.call_TRANK()` -> `WribSvcKeiMover.transform` | `getString` [R] (CAANMsg) |

**Summary:** This method is a **widely shared utility** called from batch processors (cash posting), CBS transactional message adapters, and multiple controller services across credit, customer info, telecom info, MVNO info, and trunking domains. No screen (KKSV*) entry points are found within 8 hops — this method operates at the service/carbon component layer, not directly behind screens.

## 6. Per-Branch Detail Blocks

**Block 1** — [IF/ELSE] `keiKind = "1" (Disbursement vs Non-disbursement)` (L17059)

> Determines the service type (折扣/disbursement or 非折扣/non-disbursement) using the dispatch discrimination code from the input message.

| # | Type | Code |
|---|------|------|
| 1 | SET | `keiKind = in.getString(EKK0451B011CBSMsg1List.WRIB_DCHS_HAMBET_CD)` |
| 2 | COND | `"1".equals(keiKind)` -> true = disbursement branch, false = non-disbursement branch |

**Block 1.1** — [disbursement branch: 折扣] `(keiKind == "1")` (L17062)

> Processes a discount/disbursement service contract. Includes special date recalculation logic (v5.00.24) for placeholder start dates.

| # | Type | Code |
|---|------|------|
| 1 | SET | `sYmd = in.getString(EKK0451B011CBSMsg1List.SVC_CHRG_DCHSKMST_STAYMD)` // Read start date (v5.00.24) |
| 2 | SET | `eYmd = in.getString(EKK0451B011CBSMsg1List.SVC_CHRG_DCHSKMST_ENDYMD)` // Read end date (v5.00.24) |
| 3 | COND | `"20991231".equals(sYmd)` // Sentinel date check (v5.00.24) |

**Block 1.1.1** — [nested IF] `sYmd is sentinel "20991231"` (L17065)

> If the start date is the placeholder sentinel value, compute it from the end date.

| # | Type | Code |
|---|------|------|
| 1 | COND | `!JKKStringUtil.isNullBlank(eYmd) && !"20991231".equals(eYmd)` // end date is valid and not sentinel |
| 2 | SET | `sYmd = JPCDateUtil.addDay(eYmd, 1)` // Compute: start = end date + 1 day |

**Block 1.2** — [field mapping: disbursement branch] (L17071)

> Populates the output HashMap with all 12 fields from the disbursement service contract. The `staymd` uses the (possibly computed) `sYmd` value.

| # | Type | Code |
|---|------|------|
| 1 | SET | `out.put("no", in.getString(EKK0451B011CBSMsg1List.WRIBSVK_DCHSKMST_NO))` |
| 2 | SET | `out.put("kei_kind", JKKWribSvcKeiOperateCC.KeiKind.WRIB.getKeiKind())` // = "1" (Disbursement) |
| 3 | SET | `out.put("stat", in.getString(EKK0451B011CBSMsg1List.WRIBSVK_DCHSKMST_STAT))` |
| 4 | SET | `out.put("stat_nm", in.getString(EKK0451B011CBSMsg1List.WRIBSVK_DCHSKMST_STAT_NM))` |
| 5 | SET | `out.put("type_cd", in.getString(EKK0451B011CBSMsg1List.WRIB_DCHS_TYPE_CD))` |
| 6 | SET | `out.put("type_cd_nm", in.getString(EKK0451B011CBSMsg1List.WRIB_DCHS_TYPE_CD_NM))` |
| 7 | SET | `out.put("campaign_cd", in.getString(EKK0451B011CBSMsg1List.DSP_CAMPAIGN_DCHSKM_CD))` |
| 8 | SET | `out.put("campaign_nm", in.getString(EKK0451B011CBSMsg1List.WRISVC_DCHSKM_NM))` |
| 9 | SET | `out.put("mskm_ymd", in.getString(EKK0451B011CBSMsg1List.MSKM_YMD))` |
| 10 | SET | `out.put("staymd", sYmd)` // May be computed from eYmd (v5.00.24 mod) [-> computed start date] |
| 11 | SET | `out.put("endymd", in.getString(EKK0451B011CBSMsg1List.SVC_CHRG_DCHSKMST_ENDYMD))` |
| 12 | SET | `out.put("wrib_svc_cd", in.getString(EKK0451B011CBSMsg1List.WRISVC_DCHSKM_CD))` |
| 13 | SET | `out.put("aply_jun_nm", in.getString(EKK0451B011CBSMsg1List.APLY_JUN_NM))` |

**Block 2** — [ELSE: non-disbursement branch: 非折扣] (`keiKind != "1"`) (L17087)

> Processes a non-disbursement (standard) service contract.

| # | Type | Code |
|---|------|------|
| 1 | SET | `out.put("no", in.getString(EKK0451B011CBSMsg1List.WRIBSVK_DCHSKMST_NO))` |
| 2 | SET | `out.put("kei_kind", JKKWribSvcKeiOperateCC.KeiKind.HNSOKU.getKeiKind())` // = non-disbursement kind code |
| 3 | SET | `out.put("stat", in.getString(EKK0451B011CBSMsg1List.WRIBSVK_DCHSKMST_STAT))` |
| 4 | SET | `out.put("stat_nm", in.getString(EKK0451B011CBSMsg1List.WRIBSVK_DCHSKMST_STAT_NM))` |
| 5 | SET | `out.put("type_cd", in.getString(EKK0451B011CBSMsg1List.WRIB_DCHS_TYPE_CD))` |
| 6 | SET | `out.put("type_cd_nm", in.getString(EKK0451B011CBSMsg1List.WRIB_DCHS_TYPE_CD_NM))` |
| 7 | SET | `out.put("campaign_cd", in.getString(EKK0451B011CBSMsg1List.DSP_CAMPAIGN_DCHSKM_CD))` |
| 8 | SET | `out.put("campaign_nm", in.getString(EKK0451B011CBSMsg1List.WRISVC_DCHSKM_NM))` |
| 9 | SET | `out.put("mskm_ymd", in.getString(EKK0451B011CBSMsg1List.MSKM_YMD))` |
| 10 | SET | `out.put("staymd", in.getString(EKK0451B011CBSMsg1List.SVC_CHRG_DCHSKMST_STAYMD))` // Direct read (no computation) |
| 11 | SET | `out.put("endymd", in.getString(EKK0451B011CBSMsg1List.SVC_CHRG_DCHSKMST_ENDYMD))` |
| 12 | SET | `out.put("wrib_svc_cd", in.getString(EKK0451B011CBSMsg1List.WRISVC_DCHSKM_CD))` |
| 13 | SET | `out.put("aply_jun_nm", in.getString(EKK0451B011CBSMsg1List.APLY_JUN_NM))` |

**Block 2.1** — [IF] `WRISVC_DCHSKM_CD = "DT0000002" (Network Phone TV 3-party bundle)` (L17094)

> For network-phone-TV three-party bundle applications, clear the billing dates. Per requirement LT-2013-0000101.

| # | Type | Code |
|---|------|------|
| 1 | SET | `TgHansoku = "DT0000002"` // Bundle service code constant |
| 2 | COND | `TgHansoku.equals(in.getString(EKK0451B011CBSMsg1List.WRISVC_DCHSKM_CD))` |
| 3 | SET | `out.put("staymd", "")` // Clear start date |
| 4 | SET | `out.put("endymd", "")` // Clear end date |

**Block 3** — [RETURN] (L17106)

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return out;` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `WRIB` | Business term | Discount / Disbursement service — a service contract type where pricing discounts are applied (from Japanese `割引` - waribiki) |
| `HNSOKU` | Business term | Non-disbursement / Non-discount service — a standard service contract without price discounts (from Japanese `非折扣` - hisekkyaku) |
| `WRIB_DCHS_HAMBET_CD` | Field | Disbursement dispatch discrimination code — determines whether the service item is a discount or non-disbursement type |
| `WRIBSVK_DCHSKMST_NO` | Field | Discount service item key master number — unique identifier for the discount service contract record |
| `WRIBSVK_DCHSKMST_STAT` | Field | Discount service item key master status — current processing/status code of the discount service contract |
| `WRIBSVK_DCHSKMST_STAT_NM` | Field | Discount service item key master status name — human-readable description of the service contract status |
| `WRIB_DCHS_TYPE_CD` | Field | Discount dispatch type code — classifies the type of discount service (e.g., new, change, cancellation) |
| `WRIB_DCHS_TYPE_CD_NM` | Field | Discount dispatch type code name — human-readable discount service type description |
| `DSP_CAMPAIGN_DCHSKM_CD` | Field | Display campaign discount service master code — campaign/promotion code associated with the discount service |
| `WRISVC_DCHSKM_NM` | Field | WRIB service discount service master name — name of the discount service campaign |
| `MSKM_YMD` | Field | Service charge management year/month/day — the service charge billing reference date |
| `staymd` | Field | Start year/month/day — the service activation/start date for billing purposes |
| `endymd` | Field | End year/month/day — the service termination/end date for billing purposes |
| `wrib_svc_cd` | Field | WRIB service code — the unique service code identifying the specific discount service product |
| `aply_jun_nm` | Field | Application order name — the sequence/order name for application processing |
| `SVC_CHRG_DCHSKMST_STAYMD` | Field | Service charge discount service master start date — raw start date from the source message |
| `SVC_CHRG_DCHSKMST_ENDYMD` | Field | Service charge discount service master end date — raw end date from the source message |
| `WRISVC_DCHSKM_CD` | Field | WRIB service discount service master code — the specific discount service code, including the bundle identifier `DT0000002` |
| `KeiKind` | Enum | Service kind enumeration — inner enum in `JKKWribSvcKeiOperateCC` with at least `WRIB` (disbursement/折扣) and `HNSOKU` (non-disbursement/非折扣) values |
| `DT0000002` | Constant | Network Phone TV 3-party bundle service code — a special service code for bundled internet, telephone, and TV services where billing dates are cleared per LT-2013-0000101 |
| `20991231` | Constant | Sentinel/far-future date — used as a placeholder value to indicate "no start date specified"; triggers date recalculation logic |
| `LT-2013-0000101` | Change request | Internal change request ticket requiring billing dates to be cleared for 3-party bundle applications |
| `Transformer` | Interface | Generic functional interface `Transformer<I, O>` that defines a single `transform(I in)` method for data conversion |
| `CAANMsg` | Type | Fujitsu message container object — a structured message carrying field values via `getString(String key)` and other accessors |
| v5.00.20 | Version | Version modification that consolidated discount and promotion information retrieval into a single service IF |
| v5.00.24 | Version | Version modification that added date-recalculation logic (start date = end date + 1) when start date is the sentinel `20991231` |
| `EKK0451B011CBSMsg1List` | Message list | CBS message list class defining field keys for the `EKK0451B011` CBS interface (discount service item master data) |
| `JPCDateUtil` | Utility | Date arithmetic utility class — provides methods like `addDay(String yyyymmdd, int days)` for date manipulation |
| `JKKStringUtil` | Utility | String utility class — provides null/blank validation methods like `isNullBlank(String)` |
