# KKW04202SFLogic

## Purpose

`KKW04202SFLogic` is the central business-logic controller for the **Address Change Registration** feature (住所変更登録) in the Kopt Web B application. It orchestrates the multi-step workflow that operators use to modify a customer's registered address and, as a consequence, adjust all associated telecommunications services — including eo光ネットワーク (eo光 Internet), eo光電話 (eo光 Phone), and eo光テレビ (eo光 TV) — along with any attached set-top boxes, routers, and device options (KKop / 機器オプション). This class sits at the heart of the system with 8 inbound connections, acting as a facade that coordinates UI interactions, validation, backend service calls, and data transformation across the entire address-change lifecycle.

## Design

`KKW04202SFLogic` follows the **front-controller / page-controller** pattern common in this codebase's web architecture. It extends `JCCWebBusinessLogic`, which provides base infrastructure for message handling, service invocation, and screen state management. The class implements a state machine over the address-change process, governed by input parameters such as `ido_div` (異動区分 - change category), `adchgStatCd` (住所変更状態コード), and `rvsPtn` (復元パターン - restore pattern).

Key design characteristics:

- **Screen-driven state machine**: Each `actionXxx()` method represents a screen transition point. The class reads `X31SDataBeanAccess` form beans from the request context, performs business logic, and either returns control to the UI or navigates to the next screen.
- **Two-phase registration**: The workflow supports a "temporary save" (一時保存) and "final registration" (本登録) pattern, with the distinction tracked via `RVS_PAT_ADCHM` and `RVS_PAT_ADCHG` restore patterns.
- **Service facade**: The class delegates to multiple backend services (primarily `KKSV0698` for address-change registration, `KKSV0097` for customer contract information, and `KKSV0452`/`KKSV0453` for header data) via the `invokeService()` method inherited from its parent.
- **Data transformation pipeline**: Display values (human-readable text) and internal codes are converted back and forth through `dataConvertDispToCode()` and `dataConvertCodeToDisp()`, supporting both full conversions and targeted updates for specific change patterns (`chgAddPtn`).

## Key Methods

### Screen Lifecycle Methods

#### `actionInit()` → boolean
The entry point for the address-change registration screen. Handles initial display setup:
- Retrieves common and screen-specific data beans from the request context
- Sets the operational date (`OPE_DATE`) on the form bean
- Reads screen-continuation information from the previous screen (`prevScreenId`)
- If coming from screen `KKW00145` (異動区分選択 - change category selection), it copies customer contract list data, service numbers, change category, and change reason codes into the current form
- If coming from screen `KKW04201` (転居先サービス契約選択 - destination service contract selection), it copies forward all relevant screen data including control service numbers, change reasons, and EO Net contract processing category
- Calls `executeHederSvc()` to fetch header service information
- Clears the STB/TV course list
- Sets the next screen to `KKW04204`

#### `actionAdd()` → boolean
Handles the "Add/Change" action where the operator submits service changes:
- Performs input validation via `inputCheck("2")`
- Disables pulldowns if the screen is in a final registration state (`INPUT_FIX`)
- Checks for multiple BBR (Broadband Router) contract inheritance conflicts via `isBbrKknChk()`
- Validates modem count warnings (ANK-2588): warns if 2+ inherited modems of the same type exist
- Validates mesh WiFi device conflicts (ANK-3825): errors if exactly 1 inherited mesh WiFi device exists for transfer, retention, or swap
- Checks the work scope setting (`TEKKYO_AD_KJ_SCOPE_PDN`) must not be empty
- Calls `makeAdchgCmnHeader()` to generate the common change header
- Navigates to `KKW04204` (転居先サービス契約選択)

#### `actionFix()` → boolean
The critical confirmation and registration method. Executes the final address-change registration:
- Converts all display values to codes via `dataConvertDispToCode()`
- Sets up `KKSV0698` service mapper with check mode "2" (確定 - confirm/final)
- Invokes the `KKSV0698` address-change registration service with extensive parameter mapping (SC/CC methods for 15+ data sections)
- Validates the service response via `isCheckRslt()`
- Performs additional business rules:
  - If work scope is "070" (ロゼット済工事不要 - no outlet-required work), validates that TV change/continuation/dsl modes are compatible
  - Checks NTT (NTT equipment) completion status
  - Validates BMP (installation) completion via `checkBmpKojiFin()`
- On failure, generates common change header and returns false
- On success, the service persists the address change

#### `actionBack()` → boolean
Handles the "Back" navigation:
- Copies selected STB/TV course data from source beans
- Restores previous screen state
- Calls `makeAdchgCmnHeader()` for the common change header
- Navigates back to `KKW04202SF`

#### `actionFin()` → boolean
Handles the "Finish" action:
- Converts display values to codes
- Calls `dataConvertDispToCode()` for data preparation
- Generates common change header
- Navigates to `KKW04210` (完了画面 - completion screen)

#### `actionChange()` → boolean
Switches the screen to "change mode" rather than "add mode":
- Preserves selected values by copying pulldown lists to backup beans
- Updates change category indicators
- Calls `makeAdchgCmnHeader()`
- Navigates to `KKW04204`

#### `actionStcRouter()` → boolean
Handles the "Set Router" action for managing router-related operations:
- Sets the selected router from the screen to the `EOH_NET_STC_ROUTER` field
- Iterates through the used devices list to find router-type devices (`TAKNKIKI_SBT_F0`)
- If no router is set, marks the router for removal (撤去)
- If router was changed, marks for removal; if unchanged, determines removal based on auto-swap flag (`USE_KIKI_KIKI_AUTO_KOKAN_TG_UM_05`)
- Calls `changeKkopRouterNetAdd()` to update device option information when network add includes router changes
- Sets next screen to `KKW04206`

#### `actionClear()` → boolean
Clears all input data and returns to the initial state:
- Retrieves screen and common beans
- Sends clear keys and resets all form values
- Sets next screen to `KKW04202SF` with initial display state

### Popup Actions (番ポ一時的戻し補正 - Temporary Return Correction)

These methods handle popup window workflows for one-time return corrections:

#### `popupStartKojiInfo()` / `popupEndKojiInfo()`
Start and end popup workflows for construction information corrections:
- Sets up popup parameters (`KKW04202SF_POPUP_PARAM1`)
- On end, processes returned values and updates the main screen
- Sets next screen to `KKW04207`

### BMP (Installation/Removal) Actions

A family of methods handling different installation/removal scenarios:

#### `actionBmp(int Index)` / `actionBmp1()` / `actionBmp2()`
Handle BMP-related popup workflows for installation/removal work:
- `INDEX0` (1番 - first) and `INDEX1` (2番 - second) variants
- Sets popup parameters (`KKW04202SF_POPUP_PARAM1` for type 1, `KKW04202SF_POPUP_PARAM2` for type 2)
- Determines which popup to open based on the type setting and NTT equipment status
- On return, processes the result via `actionBmpRet(int Index)`

#### `actionBmpRet(int Index)`
Processes the return value from a BMP popup, updating the relevant device fields.

### Telno (Phone Number) Actions

#### `actionTelnoHtb()` / `actionTelnoHtbRet(int Index)`
Handle telephone number-related popup workflows, similar to BMP actions but for phone number operations.

### Dobaniten (Subsidiary Branch) Actions

#### `actionDobaniten(int Index)` / `actionDobanitenRet(int Index)`
Handle subsidiary branch information popup workflows.

### Before/After Timing Actions

A comprehensive family of methods handling before/after timing selections for different entity types:

- `actionBeforeToki(int Index)` / `actionBeforeTokiRet(int Index)` — Before timing
- `actionAfterToki(int Index)` / `actionAfterTokiRet(int Index)` — After timing
- `actionBeforeTokiClear(int Index)` / `actionAfterTokiClear(int Index)` — Clear timing data
- These cover multiple entity types (MaCfm, etc.) with indexed access patterns.

### MA Confirmation Actions

#### `actionMaCfm(int Index)`
Handles MA (Meter Access?) confirmation workflows with popup-based input.

## Data Transformation Methods

#### `dataConvertDispToCode(X31SDataBeanAccess[] bean)` → boolean
The most comprehensive display-to-code conversion method (~610 lines). Converts all screen display values (Japanese text, human-readable strings) to their corresponding internal codes:
- Determines if eo光 Net, Tel, or TV services are being handled
- Reconstructs full addresses from component parts via `createAddress()`
- Converts address switch selection, work re-request selection, submission/acceptance担当者 selection
- Processes STB/TV course information
- Handles contract period conversions
- Returns the conversion result flag

#### `dataConvertCodeToDisp(X31SDataBeanAccess[] bean)` / `dataConvertCodeToDisp(X31SDataBeanAccess[] bean, String chgAddPtn)` → boolean
Code-to-display conversion. Converts internal codes back to display values:
- Full conversion when called without `chgAddPtn` parameter
- Targeted conversion for specific change patterns when `chgAddPtn` is provided (handles 13+ change pattern types)
- Restores names for pulldown selections, checkbox states, and service descriptions

## STB/TV Course Management

#### `setStbTvCourseList(X31SDataBeanAccess svcFormBean)` → void
Sets up the STB/TV course list for up to 5 STB units:
- Determines if this is a restore operation (fukugenFlg)
- Calculates the number of STB units based on service change category
- For each STB:
  - Sets the display name ("STB1", "STB2", etc.)
  - If service continuation: keeps existing STB movement type and populates TV course pulldowns
  - If service change: determines available plans based on TV service and PCRS code
  - If service add: sets empty pulldowns
- Handles mansion/bukken-specific TV plan lists via `TV_HOME_PLAN_LIST`, `TV_MEZON_PLAN_LIST`, `TV_MANSION_PLAN_LIST`

#### `copyStbTvCourseInfo(X31SDataBeanAccess src, X31SDataBeanAccess dest, String stbShkaWay, String adchmStatCd)` → void
Copies STB/TV course information between beans:
- Handles re-dispatch (再出扺) logic for STB movement
- Copies plan codes, PCRS codes, and course information based on the dispatch method
- Applies different copying rules based on `adchmStatCd` (temporary save vs. final registration)

#### `remakeTvCoursePdl(...)` → void (3 overloads)
Remakes the TV course pulldown list based on current screen state:
- Filters available TV plans based on mansion type (home/mezon/mansion)
- Can apply before/after flags (`bfAfFlg`) to filter plans
- Updates the destination bean's TV course pulldown

#### `setStbTvCourseListKokanSk(X31SDataBeanAccess svcFormBean)` → void
Sets up STB/TV course list with header/skip information.

#### `clearStbTvCourseList(X31SDataBeanAccess svcFormBean)` → void
Clears all STB/TV course list data on the form bean.

## KKop (機器オプション - Device Options) Management

#### `createKKopInfoList(X31SDataBeanAccess bean, boolean tekkyoDivIsCode)` → void
Builds the KKop (device option) information list from current screen data:
- Iterates through used devices
- Collects router, VA (voice adapter), and multi-router configurations
- Populates the KKop info list bean array

#### `createKKopInfoListRouter(X31SDataBeanAccess bean, boolean tekkyoDivIsCode)` → void
Router-specific KKop info list creation, handling router device types separately.

#### `existKKop(String kkopSvcCd, String pcrsCd, boolean isMoto)` → boolean
Checks if a specific KKop service exists, supporting both "before" (isMoto=true) and "after" (isMoto=false) states.

#### `setKkopSvc(...)` → void
Sets a KKop service entry on the bean with the specified service code, PCRS code, plan code, and processing type.

#### `setTekkyoDivPdnList(...)` → void / `setTekkyoDivPdnListVA(...)` → void / `setTekkyoDivPdnListRouter(...)` → void
Populate disposal category (撤去区分) pulldown lists for different device types:
- `setTekkyoDivPdnList`: General devices (modem, ONU)
- `setTekkyoDivPdnListVA`: Voice adapter devices
- `setTekkyoDivPdnListRouter`: Router devices (including multi-router support)
- `refreshTekkyoDivMultiRouter`: Refreshes multi-router disposal categories

## Validation Methods

The class contains extensive validation, primarily through the `inputCheck(String adchmStatCd)` method (~1920 lines) and numerous specialized check methods:

#### `inputCheck(String adchmStatCd)` → boolean
The master validation method. Performs comprehensive input validation:
- Validates work scope (`TEKKYO_AD_KJ_SCOPE_PDN`) must not be empty
- Validates cancellation date format and timing (for final registration, cancellation date must be after operational date)
- Determines which EO services are being handled (eo Net, eo Tel, eo TV)
- Validates service change compatibility between services
- Calls specialized validators for phone numbers, DSL, and other service-specific checks

#### `inputCheck` helpers:
- `denwaCheck_ichidenban()` / `denwaCheck_nidenban()` — Phone number validation (1st/2nd attempt)
- `denwaAgingCheck_ichidenban()` / `denwaAgingCheck_nidenban()` — Phone aging validation
- `netMobileChk()` — Network/mobile service check
- `denbanchk1()` / `denbanchk2()` — Sub-branch number check
- `sokosuChk()` — Floor number check
- `kojiakStatChk()` / `kakteiKojiakStatChk()` — Construction request status check
- `kikiStateChk()` — Device status check
- `dempaShogaiSonzaiChk()` — Earthquake damage existence check
- `smaValStateChk()` — SMA value state check
- `mansSkrmDupChk()` — Mansion floor number duplicate check
- `mansCapaCheck()` — Mansion capacity check
- `riyouAdBottomCheck()` / `kksendAdBottomCheck()` — Usage/additional send bottom check

## Service Call Methods

#### `createKKSV0098(X31SDataBeanAccess[] bean, HashMap<String, Object> outputMap)` → HashMap<String, Object>
Sets up the KKSV0098 service call (service contract information) with extensive parameter mapping across 15+ data sections (~4000 lines).

#### `getKKSV0098(X31SDataBeanAccess[] bean, HashMap<String, Object> outputMap)` → void
Retrieves and processes KKSV0098 results.

#### `executeFirstDisp(X31SDataBeanAccess[] paramBean, HashMap outputMapClone)` → boolean
Executes first-time display processing:
- Calls `executeHederSvc()` for header information
- Builds input maps via `getHederSvcInputMap()`
- Calls `KKSV0452` for service query
- Sets up STB/TV course lists, pulldown lists, and disposal category pulldowns

#### `executeHederSvc(X31SDataBeanAccess[] paramBean)` → void
Calls the header service to retrieve common change information.

#### `getHederSvcInputMap(X31SDataBeanAccess[] bean, HashMap<String, Object> outputMap)` → void
Builds the input map for the header service call.

## Pulldown and Bean Utility Methods

#### `setPulldownList(...)` / `setPulldownListForHdd(...)` / `setTvCoursePulldownList(...)`
Populate pulldown list beans from HashMap data:
- `setPulldownList`: General pulldown population
- `setPulldownListForHdd`: HDD-specific pulldown population with special handling for blacklist entries
- `setTvCoursePulldownList`: TV course-specific pulldown population with HD/Non-HD distinction

#### `copyPdnList(...)` / `copyPdnListWithBlank(...)` / `copyPdnListChangeStb(...)` / `copyPdnListForHdd(...)`
Copy pulldown list data between beans with various transformation options.

#### `setCheckBoxStatus(X31SDataBeanAccess svcFormBean, String target, boolean checkStatus)` → void
Set checkbox state on a form bean.

#### `getTekkyoDiv(...)` → void (~1650 lines)
The most complex decision method in the class. Calculates the disposal category (撤去区分: 撤去/継続/保留/変更) for each device based on a complex matrix of factors:
- Device type (`use_kiki_div`: modem, ONU, router, VA, multi-router, etc.)
- Service change category (`svc_chg_div`)
- Work scope (`kj_scope_div`)
- Usage availability (`use_kh_div`)
- Transfer division (`kiki_tk_div`)
- PCRS code (`use_kiki_pcrs_cd`)

#### `getCtrlDspFlgTekkyoKijiran(...)` / `getCtrlDspFlgNewestaKijiran(...)`
Determine whether to control the display of disposal categories based on various conditions.

## Relationships

```mermaid
flowchart TD
    subgraph Controllers
        KKW04204["KKW04204 Controller"]
        KKW04205["KKW04205 Controller"]
        KKW04206["KKW04206 Controller"]
        KKW04207["KKW04207 Controller"]
        KKW04208["KKW04208 Controller"]
    end

    subgraph KKW04202SF["KKW04202SFLogic"]
        actionInit["actionInit - Screen init"]
        actionAdd["actionAdd - Add/change"]
        actionFix["actionFix - Confirm/register"]
        actionBack["actionBack - Go back"]
        actionFin["actionFin - Finish"]
        inputCheck["inputCheck - Validation"]
        dataConvertDispToCode["dataConvertDispToCode"]
        setStbTvCourseList["setStbTvCourseList"]
        setTekkyoDivPdn["setTekkyoDivPdn"]
        reflectionBean["reflectionBean"]
        executeHederSvc["executeHederSvc"]
        makeAdchgCmnHeader["makeAdchgCmnHeader"]
        KKSV0698Mapper["KKSV0698 Mapper"]
    end

    subgraph BaseClass
        JCCWebBusinessLogic["JCCWebBusinessLogic"]
    end

    subgraph Services
        KKSV0698["KKSV0698 Service"]
        KKSV0097["KKSV0097 Service"]
        KKSV0452["KKSV0452 Service"]
    end

    KKW04204 --> KKW04202SF
    KKW04205 --> KKW04202SF
    KKW04206 --> KKW04202SF
    KKW04207 --> KKW04202SF
    KKW04208 --> KKW04202SF

    KKW04202SF --> JCCWebBusinessLogic

    actionInit --> executeHederSvc
    actionAdd --> inputCheck
    actionAdd --> makeAdchgCmnHeader
    actionFix --> dataConvertDispToCode
    actionFix --> KKSV0698Mapper
    actionFix --> makeAdchgCmnHeader
    inputCheck --> setTekkyoDivPdn
    actionFin --> makeAdchgCmnHeader

    KKSV0698Mapper --> KKSV0698
    executeHederSvc --> KKSV0452
```

### Who Depends on KKW04202SFLogic

| Consumer | Relationship |
|---|---|
| **KKW04204 Controller** | Navigation target after `actionAdd()` — destination service contract selection |
| **KKW04205 Controller** | Navigation target for additional service operations |
| **KKW04206 Controller** | Navigation target after `actionStcRouter()` — router settings |
| **KKW04207 Controller** | Navigation target for construction information popups |
| **KKW04208 Controller** | Navigation target for additional operations |
| **JCCWebBusinessLogic** | Parent class — provides base infrastructure for message handling and service invocation |

### What KKW04202SFLogic Depends On

| Dependency | Usage |
|---|---|
| **JCCWebBusinessLogic** | Parent class providing `invokeService()`, `getServiceFormBean()`, `getCommonInfoBean()` |
| **X31SDataBeanAccess** | Form bean for passing data between screen and logic |
| **KKSV0698_KKSV0698OPDBMapper** | Mapper for the address-change registration service |
| **KKSV0097_KKSV0097OPDBMapper** | Mapper for customer/contract service |
| **KKW04202SFConst** | Constants for field names, codes, and messages |
| **JKKScreenConst** | Screen ID constants for navigation |
| **JKKCommonConst** | Common service codes, device codes, and constants |
| **JCCWebCommon** | Utility methods for screen state, dates, and messages |

## Usage Example

The typical flow for an address change registration looks like this:

```
1. KKW04202SF.actionInit()
   -> Fetches header service data via executeHederSvc()
   -> Sets up empty STB/TV course list
   -> Displays the initial screen to the operator

2. Operator selects services and clicks "Add"
   -> KKW04202SF.actionAdd()
   -> Runs inputCheck("2") for validation
   -> Checks BBR/modem/mesh WiFi conflicts
   -> Calls makeAdchgCmnHeader() to prepare common data
   -> Navigates to KKW04204

3. Operator selects destination services in KKW04204
   -> Returns to KKW04202SF
   -> reflectionBean() populates device lists
   -> setTekkyoDivPdn() calculates disposal categories for each device
   -> setStbTvCourseList() configures STB/TV course options

4. Operator confirms and clicks "Fix"
   -> KKW04202SF.actionFix()
   -> dataConvertDispToCode() converts all display values to codes
   -> KKSV0698 service is invoked with registration parameters
   -> isCheckRslt() validates the service response
   -> Additional business rule checks (work scope compatibility, etc.)

5. Operator clicks "Finish"
   -> KKW04202SF.actionFin()
   -> Final data conversion
   -> makeAdchgCmnHeader() generates final common data
   -> Navigates to KKW04210 (completion screen)
```

For a change from temporary save:

```
1. KKW04202SF.actionAdd() with RVS_PAT_ADCHM (一時保存)
   -> Saves data without final registration
   -> Subsequent screens operate in restore mode

2. When restoring from temporary save:
   -> actionInit detects RVS_PAT_ADCHM state
   -> reflectionBean() restores saved data into form beans
   -> setTekkyoDivPdn() recalculates disposal categories
```

## Notes for Developers

### Thread Safety
This class is **not thread-safe**. Each screen request creates a new instance (typical of this framework's design), so instance fields like `chgTakinoRoote` are per-request. However, static fields like `PCRS_SPEED_CD_MAP`, `TV_HOME_PLAN_LIST`, etc., are safe as they are initialized once at class loading time.

### State Machine Complexity
The class tracks state through multiple interdependent fields:
- `ido_div` (異動区分): Overall change category (e.g., "00020" for 住所変更・確定)
- `adchgStatCd` (住所変更状態コード): Whether this is a temporary save (RVS_PAT_ADCHM) or final registration (RVS_PAT_ADCHG)
- `rvsPtn` (復元パターン): Restore pattern (DEF=0, ADCHM=1, ADCHG=2)
- `chgAddPtn` (変更パターン): Specific change pattern for targeted data conversion

Changes to one state field can cascade into unexpected behavior in other methods. The `inputCheck()` method alone handles over 1900 lines of conditional logic.

### Code Conversion Pitfalls
- `dataConvertDispToCode()` converts **all** fields in the bean. Be careful not to call it partially — missing any field can cause inconsistent state on the backend service call.
- `dataConvertCodeToDisp()` with a specific `chgAddPtn` only converts the affected fields. When using targeted conversion, ensure the `chgAddPtn` value matches the actual change type.

### Validation Order Matters
The `inputCheck()` method performs validations in a specific order, and some checks depend on earlier conversions. Do not reorder validation steps — the order reflects business rule dependencies established through years of operational experience (as evidenced by the many numbered issue-fix comments throughout the code).

### Service Mapper Configuration
When adding new service calls, follow the existing pattern:
1. Create or extend the relevant mapper class (e.g., `KKSV0698_KKSV0698OPDBMapper`)
2. Use `setKKSVXXXXXXSC()` for setup (set component) calls
3. Use `setKKSVXXXXXXCC()` for check (check component) calls
4. Pass `FUNC_CODE_1` or `FUNC_CODE_2` based on whether it's an input or output operation

### Hardcoded Values
The class contains numerous hardcoded Japanese strings for display purposes and magic number comparisons (e.g., `"00020"` for change category). These are often tied to constants defined in `KKW04202SFConst`. Always prefer the constants over raw values.

### STB/TV Course Limits
The system supports a maximum of 5 STB units. This is hardcoded in the loop bounds for `setStbTvCourseList()` and related methods. Expanding this would require changes across multiple methods and likely database schema changes as well.

### Popup Workflow Pattern
The BMP, telnoHtb, dobaniTen, and beforeToki/afterToki methods follow a consistent popup pattern:
1. `actionXxx1()`/`actionXxx2()` sets popup parameters and opens the popup
2. The popup screen returns data
3. `actionXxxRet(int Index)` processes the return value and updates the main screen
This pattern repeats for each popup type with different parameter keys and processing logic.

### Legacy Code Indicators
The file contains numerous dated comments and issue-numbered sections (e.g., `ANK-XXXX-00-00`, `IT1-2012-XXXXXX`, `OM-2014-XXXXXXX`), indicating extensive evolution over many years. When modifying:
- Check if existing issue-numbered sections are still relevant
- The `//>>>` and `<<<` markers often indicate blocks that should be treated as atomic units
- Some commented-out sections (e.g., `TSUIKA_STB`, `FUYO_STB` around lines 190-198) suggest past configuration changes that may have important business context

### KKop Service Codes
The KKop (device option) system uses these service codes:
- `"G01"` — Router function
- `"G02"` — Voice adapter function
These map to specific PCRS codes and plan codes. The `changeKkopSryoriKbn()` and `reflectAdchgDtlToKkopInfoList()` methods handle the complex mapping between service changes and device option configurations.
