# KKW00128SFLogic

## Purpose

`KKW00128SFLogic` is the central business-logic controller for the **Service Contract Information Update (eo Hikari Net)** screens in the JCC web application framework. It handles the full lifecycle of a customer's service contract modification — from initial data display through confirmation, finalization, and correction — across multiple action screens (KKW00128, KKW00134, KKW00140). It orchestrates data fetching, form population, input validation, service invocation, and post-update processing for fiber-optic broadband service contracts in a Japanese ISP/telecom backend.

This class exists to consolidate the complex, multi-step business flow of changing, suspending, resuming, cancelling, or correcting a service contract into a single entry-point class that screens can delegate to.

## Design

`KKW00128SFLogic` extends `JCCWebBusinessLogic` and follows the **screen-controller / facade** pattern common in the JKK framework. It acts as a thin orchestration layer between the web presentation layer (JSP/Action servlets) and the underlying SOAP-based service contracts. It does not implement an interface itself; instead, its public methods conform to the framework's expected action-method signature (`boolean actionXxx() throws Exception`).

The class manages several key concerns:

1. **Initialization flow** — retrieves inherited screen data from the previous page, fetches comprehensive service and contract data via a large `invokeInitService` call, populates pulldowns and form fields, and prepares the multi-tab UI.
2. **Confirmation (update) flow** — validates user input against business rules, maps DataBean fields to service parameters, invokes the appropriate update service, and handles error messaging.
3. **Finalization flow** — re-invokes with check-and-register mode (`FUNC_CODE_1`), calls auxiliary charge-applying logic (`executeAxMRnkSjisho`), and navigates to the completion screen (KKW00140).
4. **Tab navigation** — delegates to `JKKTabCommonLogic` for each of the 11 tabs on the main form.
5. **Domain-specific validations** — contract suspension dates, long-term discount rules, penalty calculations, duplicate application numbers, ONU exchange checks, Netflix Premium conflicts, and more.

### Class diagram

```mermaid
flowchart TD
    subgraph Dependers["Dependers - inbound"]
        WEB1["KKW001280PJP Screen Controller"]
        WEB2["KKW001340PJP Confirmation Screen"]
        WEB3["KKW001400PJP Completion Screen"]
        XML1["x31business_logic_KKW00128SF Business Logic XML"]
    end

    subgraph Logic["KKW00128SFLogic"]
        INIT["actionInit actionInitKKW00128 Screen init and data fetch"]
        UPDCF["actionUpdcfm Registration confirm"]
        FIX["actionFix Finalize changes"]
        RN["actionRn Return to previous screen"]
        SHUSEI["actionShusei Edit correction"]
        TABS["actionTab1 through actionTab11 Tab navigation"]
        VALID["updcfmErrCheck and validators Business rule checks"]
        MAPDB["mapForDbUpd Map DataBean to service params"]
        SVCKEI["getSvckeiCommonMap Common contract data map"]
        INITSVC["invokeInitService Initial service invocation"]
        GETSESSION["getSessionKKW00128SFBean Inherited info extraction"]
        SETLIST["setListKKW00128SFBean List field population"]
        SETTBX["setTbxKKW00128SFBean Text field population"]
        CFM_LIST["cfmListKKW00128SFBean List field collection"]
        CFM_TBX["cfmTbxKKW00128SFBean Text field collection"]
    end

    subgraph Parent["Parent class"]
        JCCWEB["JCCWebBusinessLogic Framework base class"]
    end

    WEB1 --> Logic
    WEB2 --> Logic
    WEB3 --> Logic
    XML1 --> Logic
    Logic --> JCCWEB
    INIT --> GETSESSION
    INIT --> INITSVC
    INIT --> MAPDB
    INIT --> SETLIST
    INIT --> SETTBX
    INIT --> SVCKEI
    UPDCF --> MAPDB
    UPDCF --> VALID
    FIX --> MAPDB
    RN --> GETSESSION
```

## Key Methods

### Lifecycle / Entry-Point Actions

#### `actionInit() throws Exception → boolean`

The screen initialization entry point. Determines which screen ID was requested (`KKW00128`, `KKW00134`, or `KKW00140`) and dispatches to the appropriate init handler. For the main screen (`KKW00128`), it calls `actionInitKKW00128()`.

- **Parameters:** None (reads screen ID from `CommonInfoBean`).
- **Returns:** `true` on success.
- **Side effects:** Sets `NEXT_SCREEN_NAME` on the common info bean; triggers full screen initialization via `actionInitKKW00128()`.

#### `actionInitKKW00128() throws Exception → void`

The core initialization method — the heart of the class at roughly 200+ lines. It performs:

1. Retrieves the service form `DataBean`.
2. If not a re-display (`re_flg == false`), calls `getSessionKKW00128SFBean()` to extract inherited screen info.
3. Creates a `paramBean` array and calls `invokeInitService()` to fetch all initial data from the backend.
4. Special-cases the "recovery"ido_div (00004) to display a cancellation message.
5. Calls `itsOverKaihkPsbPrd()` to check if the recovery period has expired.
6. Populates **23 pulldown lists** (commission types, work fees, penalty info, PON subtypes, etc.) via `setPulldown()`.
7. Calls `sethiddenKKW00128SFBean()`, `setListKKW00128SFBean()`, and `setTbxKKW00128SFBean()` to populate list-type and text-type form fields.
8. Extracts the preferred termination date from the agreement result data and the mansion management notes.
9. Sets the WAO (Wavelength Access Optical) correlation info, CAF number, and scheduled/completion dates for work orders.
10. Calls `checkNtto()` for NTT uninstall judgment and `checkKoji()` for work-flag checks.
11. Backs up inherited contract data into screen session info.
12. Sets the shared `svc_kei_dataMap` via `getSvckeiCommonMap()` for cross-screen navigation.

#### `invokeInitService(X31SDataBeanAccess[] paramBean) → HashMap<String, Object>`

Prepares and executes the initial service call for screen display. Uses `KKSV0059_KKSV0059OPDBMapper` to map input fields for roughly **50+ service calls** covering:
- Service agreement info (KKSV005901SC – KKSV005909SC)
- Pulldown code lists (KKSV005912SC – KKSV005932SC)
- Contract history and supplementary data (KKSV005933SC – KKSV005955SC)
- Various CC (confirm/check) calls and recent feature additions (KKSV005959SC – KKSV005981SC)

After `invokeService(paramMap, inputMap, outputMap)`, it unmapps the output back into the `DataBean` via corresponding `get*SC()` calls on the mapper.

Returns the `outputMap` containing all fetched service results, keyed by SC identifiers like `"KKSV005903SC"`, `"KKSV005941SC"`, etc.

#### `actionUpdcfm() throws Exception → boolean`

Handles the **registration confirmation** button press. This is the primary business-processing path:

1. Gets the service form `DataBean` and clears the map-open flag.
2. Calls `mapOnukknkjinfstku()` for ONU exchange work data.
3. Runs `updcfmErrCheck()` — if errors, returns to the same screen with error messages.
4. Sets service parameters via `setServiceParamater()`.
5. Collects user-edited list and text fields via `cfmListKKW00128SFBean()` and `cfmTbxKKW00128SFBean()`.
6. Invokes domain-specific pre-checks (cancellation-specific penalty logic, course-change pre-reservation check, ONU exchange status validation).
7. Maps DataBean fields to service input via `mapForDbUpd()` with `FUNC_CODE_2` (check-only mode).
8. Calls `invokeService()` to execute the backend update.
9. Validates service response with `checkSvcKeiNum()` and `checkError()`.
10. Checks for additional post-update issues: double application numbers, Netflix Premium conflicts, course-change warnings, service start/end date validation, and pre-executed cancellation checks.
11. Displays formatted values via `dspTbxKKW00128SFBean()`.
12. Sets the next screen to KKW00134 (confirmation screen) and updates the shared contract info map.
13. Returns `true` on success, `false` on error.

#### `actionFix() throws Exception → boolean`

Handles the **finalize** button on the confirmation screen. Similar to `actionUpdcfm()` but with key differences:
- Uses `FUNC_CODE_1` (check-and-register mode) instead of `FUNC_CODE_2` (check-only).
- Calls `JKKSvkeiUpdScreenUtil.executeAxMRnkSjisho()` to handle auxiliary charge rate application (for course-change scenarios).
- On success, navigates to **KKW00140** (completion screen) instead of KKW00134.
- Retrieves service messages for recovery, cancellation, and course-change scenarios via `getMsgList()`.

#### `actionRn() throws Exception → boolean`

Handles the **return** button. Merges the current inherited contract data back into the previous screen's session info and navigates back. Does not modify any data.

#### `actionShusei() throws Exception → boolean`

Handles the **edit/correction** button on the confirmation screen. Clears the map-open flag, sets the next screen back to KKW00128, and restores the shared contract info map — effectively returning the user to the update screen with existing data.

### Data Population (Display Phase)

#### `getSessionKKW00128SFBean(X31SDataBeanAccess svcFormBean) throws Exception → void`

Extracts inherited screen information from the HKTGI (inherited contract data) list and sets it on the service form `DataBean`. Key fields extracted:
- `ido_div` — change category code
- `sysid` — system ID
- `svc_kei_no` — service contract number
- `popup_mode` — popup mode flag
- `syscd` — external system code
- `ido_rsn_cd[]` — reason codes for change (array)
- `ido_rsn_memo` — reason memo
- `unyo_ymd` / `unyo_dtm` — operation date/time
- `ido_div_seni_ptn` — navigation pattern for inherited screens
- `wrib_auto_aply_tg_gai_flg` — write auto-application target change flag

Also checks for the "contractor death registration" reason code (`T5`) and sets the `keisya_die_add_ari_flg` flag.

#### `setListKKW00128SFBean(X31SDataBeanAccess svcFormBean) throws Exception → void`

Populates list-type `DataBean` fields. This method processes sub-beans for:
- Service agreement info (`EKK0081A010CBSMsg1List`)
- Service contract circuit details (`EKK0241B001CBSMsg1List`)
- Discount service info (`EKK0451B010CBSMsg1List`)
- Work order info (KU0011A010BSMsg1List)
- Work order info for eo Hikari Net / Mansion

It determines whether the work order is unconnected (`kojiNotRenFlg`) based on:
- Price group code (`PRC_GRP_CD_04` — mansion pricing)
- PCRS code (mansion private, global, or Hikari Consent patterns)
- Work order status

For course-change scenarios (`ido_div = 00009`), it pre-initializes the commission code to "02" and the standard work fee to "01" (standard/free).

#### `setTbxKKW00128SFBean(X31SDataBeanAccess svcFormBean, Map<String, Object> outputMap) throws Exception → void`

Populates text-type form fields with data from service results. This method sets display values for various input fields including dates, codes, and free-text entries.

#### `sethiddenKKW00128SFBean(X31SDataBeanAccess[] paramBean, HashMap<String, Object> outputMap) throws Exception → void`

Configures hidden/conditional display flags on the form. Determines which fields should be visible or hidden based on the current business context (e.g., showing mansion-specific fields only for certain price groups).

#### `dspTbxKKW00128SFBean(X31SDataBeanAccess svcFormBean) throws Exception → void`

Formats and sets display-ready values for text fields after a service call. Used in both confirmation and finalization flows.

### Data Collection (Input Phase)

#### `cfmListKKW00128SFBean(X31SDataBeanAccess svcFormBean) throws Exception → void`

Collects user-edited values from list-type `DataBean` fields into the input map for service calls. Essentially the inverse of `setListKKW00128SFBean()` — reads what the user changed and prepares it for the backend.

#### `cfmTbxKKW00128SFBean(X31SDataBeanAccess svcFormBean) throws Exception → void`

Collects user-edited values from text-type `DataBean` fields. Called before service invocation in both `actionUpdcfm()` and `actionFix()`.

### Service Parameter Mapping

#### `mapForDbUpd(X31SDataBeanAccess[] paramBean, HashMap<String, Object> inputMap, String func_code) throws Exception → void`

A critical dispatching method that creates the appropriate `DataBean`-to-service mapper based on `ido_div` (change category). Each branch instantiates a different mapper class and configures service/confirm calls:

| ido_div | Mapper Class | Scenario |
|---------|-------------|----------|
| 00004 | `KKSV0194_*` | Recovery (resume suspended service) |
| 00005 | `KKSV0195_*` | Cancellation |
| 00008 | `KKSV0196_*` | Cancellation (alternate flow) |
| 00010 | `KKSV0197_*` | Service suspension application |
| 00011 | `KKSV0198_*` | Service suspension cancellation |
| 00032/00033 | `KKSV0200_*` | Registration content correction / service info correction |
| 00053 | `KKSV0195_*` | Cancellation pre-execution cancellation |
| 00009 | `KKSV0202_*` | Course change (most complex mapper, ~40 service calls) |
| 00024 | `KKSV0203_*` | Suspension application |
| 00025 | `KKSV0204_*` | Suspension change / pre-execution cancellation |
| 00084 | `KKSV0787_*` | Address change / start date correction |

The `func_code` parameter determines whether calls are check-only (`FUNC_CODE_2`) or check-and-register (`FUNC_CODE_1`). The `iyakFlg` variable (penalty flag) is set based on service type — mansion and mansion-platinum types skip the penalty field.

#### `setServiceParamater(String idoDiv, HashMap<String, Object> paramMap) → void`

Sets the usecase ID and operation ID on the parameter map based on `ido_div`. Maps each scenario to its corresponding usecase (e.g., recovery → `UCID_KKSV0194`, cancellation → `UCID_KKSV0195`, course change → `UCID_KKSV0202`).

#### `getSvckeiCommonMap(HashMap<String, Object> outputMap, X31SDataBeanAccess[] paramBean) → HashMap<String, Object>`

Generates the shared contract data map used across all three screens (KKW00128 → KKW00134 → KKW00140). Extracts:
- Contract status, customer name, address, phone number
- Service contract number, billing contract number, SYSID, EO ID
- Price group name, PCRS (plan) name, P-ID, reservation info
- Mansion ID (pair ID for speeds > 1Gbps, otherwise mansion ID)
- Rank name and total point count (from loyalty program)
- Family pack flag, router subtype, special contract status

### Validation Methods

#### `updcfmErrCheck(X31SDataBeanAccess svcFormBean) → boolean`

Pre-service validation for the confirmation button. Checks:
- **Course change:** The selected PCRS must differ from the current one.
- **Course change with work:** Application number must be entered when work is required.
- **Suspension/resumption date:** The suspension date must respect the minimum service-unavailable month period.
- **Mansion vs. home:** Different error messages are displayed for mansion vs. home/platinum plans.

#### `itsOverKaihkPsbPrd(X31SDataBeanAccess svcFormBean, HashMap<String, Object> outputMap) → boolean`

Checks if the recovery (resume) eligibility period has expired. Uses the cancellation date or end date as the start of the period, adds the recovery-possible period days, and compares against the current operation date.

#### `checkChokiWrib() → boolean`

Validates long-term discount contract rules. For home/platinum type course changes with long-term discount agreements, checks if the change would cause a discrepancy between the fixed-rate discount start date and the new volume-based plan — displaying a confirmation warning if so.

#### `checkKapKei() → boolean`

Checks for active discount contracts. For recovery or cancellation, displays a warning if a discount contract is still active.

#### `checkDbleMskmDslNo(X31SDataBeanAccess[] paramBean, HashMap<String, Object> outputMap) → boolean`

Checks for duplicate application numbers. For course-change scenarios, verifies that the entered application number (`mskmsho_dtl_no`) does not already exist in work orders or main item deletions.

#### `checkKojiUm() → boolean`

Determines whether a work (installation) is required. A work is required when:
- The current PON type is E-PON and the new PCRS is GE-PON-only or 10GE-PON-only.
- The current PON type is GE-PON and the new PCRS is 10GE-PON-only.
- The equipment replacement flag is set due to speed band changes with existing router/HGW.

#### `checkPcrsCgWribCpAly(X31SDataBeanAccess[] paramBean, HashMap<String, Object> outputMap) → boolean`

Checks for course-change service charge SP applicability. For service-contract-in-progress course changes, checks if there are applicable SP entries that need user confirmation.

#### `checkSvcStaYmd(), checkSvcUseStaKiboYmd(), checkSvcEndYmd()`

Validate service start date, desired start date, and end date respectively.

#### `checkDslPreExec(Map<String, Object> outputMap, String idoDiv, String funcCode) → boolean`

Checks for pre-executed cancellations — whether a cancellation is already scheduled when an immediate cancellation is attempted.

### Tab Navigation Handlers

The class provides **11 tab handlers** (lines 4693–4847), each delegating to `JKKTabCommonLogic`:

| Method | Tab | Description |
|--------|-----|-------------|
| `actionTab1()` | Tab1 | Application info tab |
| `actionTab2()` | Tab2 | Service contract tab (passes `prcGrpCd` for conditional logic) |
| `actionTab3()` | Tab3 | Customer info tab |
| `actionTab4()` | Tab4 | Equipment info tab |
| `actionTab5()` | Tab5 | Option info tab |
| `actionTab6()` | Tab6 | Billing contract info tab |
| `actionTab7()` | Tab7 | Progress info tab |
| `actionTab8()` | Tab8 | Discount info tab |
| `actionTab9()` | Tab9 | Address info tab |
| `actionTab10()` | Tab10 | ADSL work info tab |
| `actionTab11()` | Tab11 | Contents tab (added 2016/05/26) |

### Other Notable Methods

#### `actionTaiikiInfoShokai() → boolean`

Introduces area information. Navigates to screen KKW02541 with the service contract number, setting up a return path to the current screen.

#### `actionOpenSmtv() → boolean`

Opens the smart battery screen (KKW13901), passing the SYSID, service contract number, and change category.

#### `checkError(X31SDataBeanAccess[] paramBean, HashMap<String, Object> outputMap) → boolean`

Post-service-call error check. Determines if the backend returned an error condition that requires user attention.

#### `setSvcPauseStpInfo(X31SDataBeanAccess, Map, X31SDataBeanAccess, String) → void`

Configures service suspension/resumption date information on the form. Handles the distinction between "suspension" (休止) and "stop" (中止) codes, setting formatted date strings for display.

#### `isMansionPrivate(String pcrsCd) → boolean` / `isMansionGlobal(String pcrsCd) → boolean`

Checks whether a PCRS code belongs to the mansion private (`A47`, `A48`, `A49`, `A67`, `A68`, `A78`) or mansion global (`A79`, `A80`, `A50`, `A51`, `A52`, `A53`, `A54`, `A55`, `A69`, `A70`) price group lists.

#### `checkNtto(HashMap<String, Object> outputMap) → void`

NTT uninstall judgment. Determines whether the service type is Type N (NTT-related), setting the `isTypeN` flag based on service output data.

#### `chkSameSpeedCrsChg(X31SDataBeanAccess svcFormBean) → boolean`

Checks if a course change involves the same speed — used to display a warning that the service charge reduction SP may not apply.

#### `chkNetflixPremiumOP(X31SDataBeanAccess svcFormBean) → boolean`

Checks if Netflix Premium is already registered for the service — blocks course changes when so, as Netflix Premium cannot coexist with certain plan changes.

#### `setInitKojiInfo(X31SDataBeanAccess, HashMap) → void`

Initializes work information fields on the form, including CAF number, scheduled work date, and completed work date from the WAO correlation service.

### Utility Methods

| Method | Purpose |
|--------|---------|
| `isNull(Object)` | Checks for null or empty string values |
| `subString(String, int, int)` | Safe substring with null-length checks |
| `getPulldownMame(X31SDataBeanAccess, String, String)` | Gets the display name for a pulldown code |
| `selectedPulldownIndex(X31SDataBeanAccess, String, String)` | Selects a pulldown option by code value |
| `getHktgiDataMap(X31SDataBeanAccess, String, String[])` | Extracts inherited contract data into a HashMap |
| `getLabelString(String, String)` | Concatenates code + "." + name |
| `getCodeName(Map, String)` | Resolves a code to its display name from an output map |
| `setString(X31SDataBeanAccess, String, String)` | Sets a string field on the bean |
| `getString(X31SDataBeanAccess, String) → String` | Gets a string field from the bean |
| `getBoolean(X31SDataBeanAccess, String) → boolean` | Gets a boolean field from the bean |
| `isMaxYmd(String) → boolean` | Checks if a date is the maximum possible value |
| `getStringAt(X31SDataBeanAccess, String, int) → String` | Gets a string array element |
| `getArrayCount(X31SDataBeanAccess, String) → int` | Gets a string array count |
| `getPcrsSpeed(X31SDataBeanAccess, String) → String` | Gets the speed code for a PCRS |
| `getBundleDiv(X31SDataBeanAccess, String) → String` | Gets the bundle division for a PCRS |
| `getYYYYMM(String) → String` | Formats a YYYYMMDD string as "YYYY/MM" |
| `editPrettyYmd(String) → String` | Formats a date for pretty display |
| `isBlankString(String) → boolean` | Checks for blank string |
| `isHikariConsent(X31SDataBeanAccess) → boolean` | Checks if the contract is Hikari Consent type |
| `getUcwkBean(X31SDataBeanAccess) → X31SDataBeanAccess` | Gets the circuit-detail sub-bean |
| `actioShkSetSprtBtn() → boolean` | Handles the phone-set support button action |
| `actionTushinBtn() → boolean` | Handles the transmission button action |
| `checkSvcKeiNum(X31SDataBeanAccess[], HashMap, String) → void` | Validates service contract count |
| `getMsgList(String, Map) → Map` | Retrieves service messages for a given change category |
| `isNeedWrisvcMsg(String) → boolean` | Determines if a change category needs warning messages |
| `setPulldown(X31SDataBeanAccess, HashMap, String, String, boolean)` | Sets a pulldown list on the form |
| `setMapGmnData(X31SDataBeanAccess) → void` | Configures map screen display data |
| `mapOnukknkjinfstku(X31SDataBeanAccess) → void` | Maps ONU exchange work status data |
| `isNfPackJudge(X31SDataBeanAccess) → void` | Netflix pack judgment |

### Additional Action Handlers (History/Info Screens)

| Method | Purpose |
|--------|---------|
| `actionCourserireki()` | Displays course history |
| `actionCourserirekirefresh()` | Refreshes course history |
| `actionKojirireki()` | Displays work history |
| `actionUseplaceadschbtn()` | Address change button for usage place |
| `actionUseplaceadschrefresh()` | Refreshes address change info |
| `actionNinshoidrireki()` | Displays approval history |
| `actionKojiifinput()` | Work information input |
| `actionKojiifinputrefresh()` | Refreshes work information input |
| `actionVsitshokai()` | Visit introduction |
| `actionTasys()` | TASYS screen |
| `actionPrche()` | PR check screen |
| `actionDslLetterSch()` | DSL letter search |
| `actionTaiorrki()` | Taio experience (service experience) |
| `actionRiyofukaRireki()` | Fee reduction history |
| `actionIdodivchoice()` | Change category selection |
| `actionIdodivchoiceFin()` | Change category selection confirmation |
| `actionCustshokai()` | Customer introduction |
| `actionItiKakunin()` | Single-point confirmation |
| `actionPaimkka()` | Payment check |
| `actionTransferTrank()` | Transfer to TRANK |
| `actionDslLetterAdd()` | DSL letter addition |
| `actionSeisankinDsp()` | Display maintenance fee |
| `actionKojihiKappu()` | Work fee collection |
| `actionTransferVcms()` | Transfer to VCMS |

## Relationships

### Who uses this class (inbound)

| Dependent | Role |
|-----------|------|
| `WEBGAMEN_KKW001280PJP.xml` | Main update screen — calls `actionInit()`, `actionUpdcfm()`, `actionFix()`, `actionRn()`, `actionShusei()`, and all tab handlers |
| `WEBGAMEN_KKW001340PJP.xml` | Confirmation screen — calls `actionUpdcfm()`, `actionFix()`, `actionRn()`, `actionShusei()` |
| `WEBGAMEN_KKW001400PJP.xml` | Completion screen — called after `actionFix()` succeeds; may reference logic for post-processing |
| `x31business_logic_KKW00128SF.xml` | Business logic orchestration XML — declares this class as the logic bean for the KKW00128 business flow |

### What this class depends on (outbound)

| Dependency | Relationship |
|-----------|-------------|
| `JCCWebBusinessLogic` | Parent class — provides framework methods like `getServiceFormBean()`, `getCommonInfoBean()`, `invokeService()`, `getScreenInfo()` |

The class also heavily depends on:
- `KKSV0059_*` and related mapper classes for service parameter mapping
- `KKW00128SFConst` for constant definitions
- `JKKCommonConst`, `JKKScreenConst` for framework constants
- `JCCWebCommon`, `JKKWebCommon` for shared utility methods
- Various `DataBean` classes (`X31SDataBeanAccess`, `X31SDataBeanAccessArray`)
- Screen constants for `KKW00128`, `KKW00134`, `KKW00140`, and related screens

## Usage Example

The typical lifecycle of this class is:

1. A user navigates to the service contract update screen (KKW00128). The screen controller (`KKW001280PJP`) invokes `KKW00128SFLogic.actionInit()`.
2. `actionInit()` determines the screen ID and calls `actionInitKKW00128()`, which:
   - Extracts inherited info (contract number, change category, etc.) via `getSessionKKW00128SFBean()`.
   - Fetches all service data via `invokeInitService()` (~50 service calls).
   - Populates pulldowns, lists, and text fields via `setPulldown()`, `setListKKW00128SFBean()`, `setTbxKKW00128SFBean()`.
3. The user modifies fields and clicks the registration confirmation button. `actionUpdcfm()` is called, which validates, maps, and invokes the update service.
4. If validation passes, the user is redirected to the confirmation screen (KKW00134), where they review changes.
5. The user clicks the finalize button. `actionFix()` is called, which re-invokes the service with check-and-register mode, applies auxiliary charges, and navigates to the completion screen (KKW00140).
6. If the user clicks return or edit at any point, `actionRn()` or `actionShusei()` navigates back to the previous screen with data preserved.

## Notes for Developers

### Thread Safety

This class is **not thread-safe**. It maintains instance fields (`svc_kei_no`, `sysid`, `ido_div`, `svc_kei_dataMap`, `cust_nm`, `re_flg`, etc.) that are read and written during the lifecycle of a single request. In the JKK framework, logic beans are typically instantiated per-request, so this is not a practical concern — but you must never share an instance across requests.

### ido_div (Change Category) Codes

The `ido_div` field is the primary discriminator for behavior. Key codes:
- `00004` — Recovery (resume a suspended service)
- `00005` — Cancellation
- `00008` — Cancellation (alternate flow)
- `00009` — Course change (most complex flow)
- `00010` — Suspension application
- `00011` — Suspension cancellation
- `00024` — Suspension application (alternate)
- `00025` — Suspension change
- `00032` — Registration content correction
- `00033` — Service information correction
- `00053` — Cancellation pre-execution cancellation
- `00084` — Address change / start date correction

### Large Number of Service Calls

`invokeInitService()` alone configures 50+ service mapper calls. Adding new fields to the init screen requires:
1. Adding a `set*SC()` call to the mapper setup section.
2. Adding a corresponding `get*SC()` call to the unmapping section.
3. Ensuring the mapper interface exists and is properly versioned.

### Japanese-Language Field Names

Field names in the `DataBean` use Japanese strings (e.g., `"サービス契約番号"`, `"工事"`). These are literal keys used in `setDataBeanString()` / `getDataBeanString()` calls. Do not refactor these into constants without coordinating with the full codebase, as other classes (like XML configuration) reference them directly.

### Screen Navigation Chain

The three screens form a chain: **KKW00128** (update) → **KKW00134** (confirmation) → **KKW00140** (completion). The `svc_kei_dataMap` shared field is the key mechanism for passing contract summary data across screens. All navigation uses `CommonInfoBean` to set `NEXT_SCREEN_ID` and `NEXT_SCREEN_NAME`.

### Date Handling

Date strings are used in `yyyyMMdd` format throughout. `JPCDateUtil` and `JKKWebCommon.addDay()` are used for date arithmetic. When working with suspension/resumption dates, note that mansion and home/platinum types have different rules for the minimum service-unavailable month.

### WAO (Wavelength Access Optical) Integration

Recent additions (2023–2025) include WAO correlation checks (`checkNtto()`, `isWaornkiflg`, `WAO_RNKI_HI_1`), NTT uninstall judgments, and CAF number management. These affect the work order flow for fiber-optic installations.

### ONU Exchange

The `IT1-2023-0000059` and related features handle ONU exchange work, including checks for `KOJIAK_SBT_CD = "015"` (ONU exchange work) and status codes `140`–`190` (pre-activation work stage). This blocks course-change registration during active ONU exchange.

### Framework Version Tags

The codebase contains numerous version/issue tags in comments (e.g., `ANK-2477-00-00`, `IT1-2013-0001255`, `OM-2021-0000633`). These trace to specific development tasks and should be used when searching git history or issue trackers for context on why specific logic exists.
