# Eo / Web / Webview / Kkw21502sf

## Overview

This module implements the **Contract Content Notice Detail Update** screen (KKW21502SF) within the K-Opticom contract management system. Its primary responsibility is to allow operators to view and modify the details of an unsent contract content notice (契約内容通知書) - a formal notification document sent to customers summarizing their service subscription, pricing, and terms. Once the notice has been mailed, it cannot be edited. The module supports the full lifecycle: initial display, update confirmation, finalization, editing correction, and PDF download.

**System name:** Contract Management System (契約管理システム)

---

## Key Classes and Interfaces

### KKW21502SFLogic

[Source](source/koptWebB/src/eo/web/webview/KKW21502SF/KKW21502SFLogic.java)

The central business logic controller for this module. It extends `JCCWebBusinessLogic` and orchestrates all screen actions. Every user interaction (button press) maps to an `actionXxx()` method.

**Role:** This class is the entry point for all screen operations. It retrieves data from backend services, validates inputs, calls update services, and manages screen navigation.

#### Key methods

- **`actionInit()`** - Initial display handler. Fetches screen state from the shared `JCCWebCommon`, retrieves the service form bean, and calls `executeInitSvc()` to query the contract notice detail inquiry service (use case `KKSV0830`). Determines whether the operation mode is read-only (`TRAN_DIV_DTL = "1"`) or update (`TRAN_DIV_UPD = "2"`) and initializes the bean accordingly via `setDtlInitBean()` or `setUpdInitBean()`. Returns `true` on success.

- **`actionUpd()`** - Update confirm button handler. Collects address fields (block/number, street name, city, etc.), validates address character limits using `isBnchigoChk()`, checks if the notice has already been mailed via `chkSendYmd()`, and calls `executeUpdSvc()` with function code `FUNC_CD_2` (confirm mode). On success, sets the next screen to KKW21503 (confirmation screen) and displays an info message.

- **`actionFix()`** - Finalize (確定) button handler. Similar to `actionUpd()` but calls `executeUpdSvc()` with function code `FUNC_CD_1` (execute mode) to actually commit the update. On success, redirects to screen KKW21504 (completion screen). Also checks that the notice has not already been mailed.

- **`actionBack()`** - Go back button handler. Restores the previous screen ID (the current screen) in the common info bean so the user can navigate back.

- **`actionShusei()`** - Edit (修正) button handler. Redirects to the registration screen (KKW21502), allowing the operator to re-edit the contract notice.

- **`actionFin()`** - Complete (完了) button handler. Simply sets the next screen to the current screen, effectively returning the user to the parent list/detail screen.

- **`actionSohusAdSearch()`** - Launches the address search screen (ZMW10601). Extracts current address fields from the bean (postal code parts, state, city, block, street), builds a parameter map, and delegates to `setNextScreenAd()`.

- **`actionSohusAdSearchRtn()`** - Handles return from the address search screen. Reads the shared screen info map and sets the resolved address fields (postal code, state, city, block, street, building name) back into the service form bean.

- **`fileDownLoad()`** - PDF download handler. Calls service `FUSV0296` to generate a PDF of the contract notice. Uses the `KKSV029601CC` mapping to populate the request with all contract data (customer name, address, services, pricing, etc.). Downloads the PDF as `Knytcs.pdf` via a dialog mode that prevents in-browser viewing.

#### Helper methods

- **`executeInitSvc()`** - Calls the contract notice detail inquiry service (use case `KKSV0830`). Uses `KKSV0830_KKSV0830OPDBMapper` for service-to-bean field mapping.

- **`executeUpdSvc()`** - Calls the contract notice update confirm service (use case `KKSV0845`). Uses `KKSV0845_KKSV0845OPDBMapper` for mapping. Returns an error flag: `"1"` means the notice update batch is currently running and the operation is rejected.

- **`isBnchigoChk()`** - Validates block/number character length based on which address components are populated: 15 chars if street name is set, 27 chars if only district name is set, 45 chars if only city name is set. Displays error message `EKB0030_TW` if the limit is exceeded.

- **`chkSendYmd()`** - Checks whether the contract notice has already been mailed. Re-calls the inquiry service to read `knytcs_print_reqymd`; if a date is present, the notice is considered already mailed and the update is rejected with error message `EKB0930_NW`.

- **`setEditPcd()`** - Formats a postal code with a hyphen (e.g., `123-4567`) and prepends the postal code symbol for display.

- **`setConcatPcdBean()`** - Splits a hyphenated postal code into two parts (3-digit / 4-digit) for the screen form, then calls `setEditPcd()` to restore the hyphenated display version.

- **`setPcdBean()`** - The reverse: splits a full 7-digit postal code into its `Sohus_pcd1` (top 3) and `Sohus_pcd2` (bottom 4) parts for input fields.

- **`setFUSV029601CC()`** - Maps all bean fields into the request structure for the PDF generation service (FUSV0296). Handles line-break conversion via `changeKaigyo()` (converts `\r`, `
`, `\r
` to `<br/>`) and date formatting via `editDate()` (converts `YYYYMMDD` to the Japanese date format). This mapping covers every field in the contract notice: customer name, address, net/phone/TV subscription details, pricing breakdowns, courses, discount services, and optional services.

- **`delKaigyo()`** - Removes all line-break characters from a string (legacy method, largely superseded by `changeKaigyo()`).

- **`clearBean()`** - Clears postal code fields in the bean before an update operation.

### KKW21502SFBean

[Source](source/koptWebB/src/eo/web/webview/KKW21502SF/KKW21502SFBean.java)

The data model / form bean for this screen. It extends `X33VViewBaseBean` and implements `X33VListedBeanInterface` and `X31CBaseBean`. It holds over 80 protected string (and one Boolean) fields, each with a getter and setter pair.

**Role:** This bean carries all form data between the screen (JSP), the logic controller, and the backend services. It is the single data carrier for the screen's entire state.

The fields can be grouped as follows:

- **Identification:** `tran_div_value`, `knytcs_no_value`, `sysid_value`, `same_kaisen_grp_skbt_no_value`, `ido_div_value`
- **Recipient address:** `sohus_nm_value` (recipient name), `sohus_pcd1_value` / `sohus_pcd2_value` / `sohus_pcd_value` / `sohus_pcd_hy_value` (postal code parts and hyphenated display), `sohus_state_nm_value` (prefecture), `sohus_city_nm_value` (city), `sohus_oaztsu_nm_value` (district), `sohus_azcho_nm_value` (street), `sohus_bnchigo_value` (block/number), `sohus_adrttm_value` / `sohus_adrrm_value` (building name / room number)
- **Customer and contract info:** `cust_cust_nm_value`, `cust_keisha_ad_value`, `ryobsy_ad_value`, `svc_tk_sta_jiki_value`, `hakko_ymd_value` (issue date), `knytcs_mngo_value`, `kei_seirt_ymd_value` (contract establishment date)
- **Net subscription:** `net_mskm_no_value`, `net_corse_value`, `net_wrib_svc_value`, `net_op_svc_value`, `net_aply_cp_value`, `net_knyhen_can_value`
- **Phone subscription:** `tel_mskm_no_value`, `tel_corse_value`, `tel_wrib_svc_value`, `tel_aply_cp_value`, `tel1_tel_no_value`, `tel1_op_svc_value`, `tel2_tel_no_value`, `tel2_op_svc_value`
- **TV subscription:** `tv_mskm_no_value`, `tv_wrib_svc_value`, `tv_aply_cp_value`, `tv_op_svc_value`, plus five TV title/detail pairs (`tv1_title_value` through `tv5_title_value`, `tv1_dtl_value` through `tv5_dtl_value`)
- **Pricing details** (for net, phone, and TV): base price, standard work fee, commission, discount service details, campaign details - each with three categories. Includes TV1-TV5 specific price title/detail fields.
- **Control flags:** `kanuoreso_dofu_ctrl_cd_value` (envelope inclusion flag), `letter_hasso_shiwake_div_value` (letter dispatch division), `dlyd_trn_req_sbt_cd_value`, `knytcs_kohu_way_cd_value` (notice delivery method code), `knytcs_print_jssi_sk_cd_value` (notice print execution code), `knytcs_sohus_ad_cd_value`, `knytcs_sohus_telno_value`, `knytcs_print_reqymd_value` (mailed date)
- **Audit timestamps:** `upd_dtm_value` (update datetime - added in IT1-2016-0000144), `teise_upd_dtm_value` (correction update datetime - added in ANK-3639-00-00)

The `typeModelData()` method provides type introspection for the framework's data-binding layer, looking up the type of a given field by name and optional subkey.

### KKW21502SFChecker

[Source](source/koptWebB/src/eo/web/webview/KKW21502SF/KKW21502SFChecker.java)

A GUI validation class implementing `X31SGuiCheckBase`. It holds a reference to the `KKW21502SFLogic` business logic instance via its constructor.

**Role:** This class is designed to perform screen-level validation (format checks, required field checks, cross-field consistency) before data reaches the business logic layer. The `checkMethod()` receives a pattern ID from the validation definition XML and a message stock for error messages.

**Current state:** The `checkMethod()` implementation currently returns `true` unconditionally - no validation logic is implemented. All input validation is handled directly in the `actionUpd()` method of `KKW21502SFLogic` (address character limit checks, mailed-date checks). This appears to be a placeholder or an area where validation definition is managed externally via XML.

### KKW21502SFConst

[Source](source/koptWebB/src/eo/web/webview/KKW21502SF/KKW21502SFConst.java)

A utility class holding all field name constants used by the bean, logic, and screens. It has a private constructor (prevents instantiation) and all fields are `public static final String`.

**Role:** Centralizes Japanese label strings for all form fields. Using constants instead of magic strings ensures consistency across the bean, logic, and validation definition files.

---

## How It Works

### Screen Flow

```mermaid
flowchart TD
    subgraph Controller["KKW21502SFLogic Controller"]
        actionInit["actionInit<br/>Initial Display"]
        actionUpd["actionUpd<br/>Update Confirm"]
        actionFix["actionFix<br/>Finalize"]
        actionBack["actionBack<br/>Go Back"]
        actionShusei["actionShusei<br/>Edit"]
        actionFin["actionFin<br/>Complete"]
        actionSohusAdSearch["actionSohusAdSearch<br/>Address Search"]
        actionSohusAdSearchRtn["actionSohusAdSearchRtn<br/>Address Search Return"]
        fileDownLoad["fileDownLoad<br/>PDF Download"]
    end

    subgraph Validation["KKW21502SFChecker"]
        checkMethod["checkMethod<br/>GUI Validation"]
    end

    subgraph DataModel["KKW21502SFBean Data Model"]
        bean["Service Form Bean<br/>Holds all form fields"]
    end

    subgraph Constants["KKW21502SFConst Constants"]
        const["Field name constants<br/>Japanese label strings"]
    end

    subgraph Services["Backend Services"]
        svcInit["KKSV0830<br/>Contract Notice Inquiry"]
        svcUpd["KKSV0845<br/>Contract Notice Update"]
        svcPdf["FUSV0296<br/>PDF Generation"]
    end

    subgraph External["External Screens"]
        adSearch["ZMW10601<br/>Address Search Screen"]
    end

    actionInit --> svcInit
    actionUpd --> svcUpd
    actionFix --> svcUpd
    actionFix --> svcInit
    actionBack --> bean
    actionShusei --> bean
    actionFin --> bean
    actionSohusAdSearch --> adSearch
    actionSohusAdSearchRtn --> bean
    fileDownLoad --> svcPdf

    actionInit --> bean
    actionUpd --> bean
    actionFix --> bean
    actionSohusAdSearch --> bean

    bean --> const
    bean --> checkMethod
```

### Detailed Operation Flows

#### 1. Initial Display (`actionInit`)

1. Retrieve shared screen info via `JCCWebCommon.getScreenInfo(this)`.
2. Get the service form bean and call `executeInitSvc()` to invoke use case `KKSV0830` (Contract Notice Detail Inquiry).
3. The `KKSV0830_KKSV0830OPDBMapper` maps service results to bean fields.
4. Read `tran_div` from the bean:
   - If `"2"` (update mode): call `setUpdInitBean()` which splits the postal code into its parts.
   - Otherwise (read mode): call `setDtlInitBean()` which formats the postal code with hyphens and a postal code prefix.
5. Dump the bean state to the debug log.

#### 2. Update Confirm (`actionUpd`)

1. Read address fields from the bean.
2. If block/number (`sohus_bnchigo`) is populated, validate character length based on which other address components are filled:
   - Street name set: max 15 chars for block/number.
   - District name only (no street): max 27 chars.
   - City name only (no district): max 45 chars.
3. Check if the notice has already been mailed via `chkSendYmd()` - if so, reject the update.
4. Call `executeUpdSvc()` with function code `FUNC_CD_2` (confirm mode).
5. If the service returns error flag `"1"` (update batch in progress), show error message.
6. Otherwise, set next screen to `KKW21503` (confirmation screen) and show info message.

#### 3. Finalize (`actionFix`)

1. Same mailed-date check as `actionUpd()`.
2. Call `executeUpdSvc()` with function code `FUNC_CD_1` (execute mode) to commit the update.
3. If successful, set next screen to `KKW21504` (completion screen).
4. If the update batch is running, show error and remain on the current screen.

#### 4. PDF Download (`fileDownLoad`)

1. Call service `FUSV0296` (PDF generation) with all contract data mapped via `setFUSV029601CC()`.
2. The data mapping converts line breaks to `<br/>` tags and formats dates in Japanese format.
3. The PDF is downloaded as `Knytcs.pdf` via a dialog that forces download (not inline browser rendering).

#### 5. Address Search (two-step flow)

1. `actionSohusAdSearch()`: User clicks the address search button. The current partial address is sent to screen `ZMW10601`.
2. After the user selects an address, `actionSohusAdSearchRtn()` retrieves the result from the shared screen info map and populates the address fields in the bean.

---

## Data Model

The `KKW21502SFBean` carries all screen data. Here is a summary of the key data groupings:

### Identification fields
| Field | Description |
|-------|-------------|
| `tran_div_value` | Operation mode (1 = read, 2 = update) |
| `knytcs_no_value` | Contract notice number |
| `sysid_value` | System ID |
| `same_kaisen_grp_skbt_no_value` | Same-line group number |
| `ido_div_value` | Change flag |
| `knytcs_print_reqymd_value` | Mailed date (if already sent) |

### Recipient address fields
| Field | Description |
|-------|-------------|
| `sohus_nm_value` | Recipient name |
| `sohus_pcd1_value` / `sohus_pcd2_value` | Postal code (3-digit / 4-digit parts) |
| `sohus_pcd_value` / `sohus_pcd_hy_value` | Full postal code / hyphenated display |
| `sohus_state_nm_value` | Prefecture |
| `sohus_city_nm_value` | City / ward |
| `sohus_oaztsu_nm_value` | District |
| `sohus_azcho_nm_value` | Street name |
| `sohus_bnchigo_value` | Block / number |
| `sohus_adrttm_value` / `sohus_adrrm_value` | Building name / room number |

### Subscription service fields
Each service category (Net, Phone, TV) carries:
- Application number (`_mskm_no_value`)
- Course (`_corse_value`)
- Discount service (`_wrib_svc_value`)
- Optional service (`_op_svc_value`)
- Applied campaign (`_aply_cp_value`)
- Content change / termination terms (Net/TV only, `_knyhen_can_value` / `_kynyh_jyoko_value`)

### Pricing breakdown fields
Each category has:
- Base price detail (`_prc_kihonprc_dtl_value`)
- Standard work fee (`_stdard_kojihi_value`)
- Commission (`_commision_value`)
- Discount service detail (`_prc_wribsvc_dtl_value`)
- Campaign detail (`_prc_cp_dtl_value`)

TV also supports 5 customizable title/detail entries for service names.

---

## Dependencies and Integration

### Inbound dependencies (who calls this module)
| Config / JSP | Depends on |
|-------------|------------|
| `KKW215020PJP.jsp` | `KKW21502SFBean` |
| `KKW215030PJP.jsp` | `KKW21502SFBean` |
| `WEBGAMEN_KKW215020PJP.xml` | `KKW21502SFBean`, `KKW21502SFLogic` |
| `WEBGAMEN_KKW215030PJP.xml` | `KKW21502SFBean`, `KKW21502SFLogic` |
| `WEBGAMEN_KKW215040PJP.xml` | `KKW21502SFBean`, `KKW21502SFLogic` |
| `x31business_logic_KKW21502SF.xml` | `KKW21502SFLogic` |

### Outbound dependencies (this module calls)
| Service | Use case | Purpose |
|---------|----------|---------|
| `KKSV0830_KKSV0830OPDBMapper` | `KKSV0830` | Contract notice detail inquiry |
| `KKSV0845_KKSV0845OPDBMapper` | `KKSV0845` | Contract notice update confirm |
| `FUSV0296` (via `setFUSV029601CC`) | `FUSV0296` | PDF generation for contract notice |

### External screen interactions
| Screen ID | Purpose |
|-----------|---------|
| `ZMW10601` | Address search - launched for recipient address lookup |
| `KKW21503` | Confirmation screen - shown after update confirm |
| `KKW21504` | Completion screen - shown after finalization |

### Framework integration
- The module uses the **Futurity X31/X33 framework** for web presentation layer (bean base class, data bean access, business logic interface).
- **Screen navigation** is managed through `CommonInfoCF` shared bean (`NEXT_SCREEN_ID`, `NEXT_SCREEN_NAME`).
- **Message handling** uses `JPCOnlineMessageConstant` codes (e.g., `EKB0030_TW` for text width errors, `EKB0370__I` for info messages, `EKB0930_NW` for "already mailed" errors, `EKB4390__I` for completion info).
- **Logging** uses `JSYwebLog.println()` with `DataBean_Dump` to record full bean state at each action entry.

---

## Notes for Developers

### Already-mailed notice protection
The `chkSendYmd()` method is the key guard against modifying sent notices. It calls the inquiry service to read `knytcs_print_reqymd` - if this field contains a date, the notice is considered mailed and the update is blocked. This check runs in both `actionUpd()` and `actionFix()`. Note that `chkSendYmd()` also re-invokes the inquiry service, so if the inquiry service is slow, this adds noticeable latency.

### Address character limit validation
The `isBnchigoChk()` method enforces variable-length limits on the block/number field based on how much of the address is already populated. This is unusual validation logic - it assumes that more address components filled means less room for the block/number. The limits (15, 27, 45) are hardcoded as constants in the logic class.

### Validation gap
The `KKW21502SFChecker.checkMethod()` currently returns `true` without doing anything. If you need to add screen-level validation, this is the class to modify. Alternatively, validation definition files (XML) may handle it externally - check the project's validation configuration for this screen.

### PDF generation migration
The PDF generation code (`setFUSV029601CC`) went through a significant migration in IT2-2016-0000056: the old `delKaigyo()` method (which stripped line breaks) was replaced with `changeKaigyo()` (which converts line breaks to `<br/>` HTML tags). The old code is heavily commented out - do not uncomment it without understanding the migration reasoning.

### Bean field additions
New fields were added in two projects:
- **IT1-2016-0000144**: Added `upd_dtm_value` and `UPD_DTM` constant for update timestamp tracking.
- **ANK-3639-00-00**: Added `teise_upd_dtm_value` and `TEISE_UPD_DTM` constant, and changed `executeUpdSvc()` to use `setKKSV084501CC` instead of `setKKSV084502SC`.

### Debug logging
Every action method ends with a `JSYwebLog.println()` call that outputs the entire bean state to logs. Be aware this can be verbose in high-volume scenarios.

### Service error handling
The update service (`KKSV0845`) returns an error flag `"1"` when an update batch is in progress. This is a concurrency protection mechanism - the system prevents simultaneous updates to prevent data inconsistency. The user-facing message indicates the contract notice sending batch is currently running.

### Screen navigation pattern
All screen navigation goes through `getCommonInfoBean().sendMessageString(CommonInfoCFConst.NEXT_SCREEN_ID, ..., value)`. This is the standard pattern for the Futurity X31 framework's screen forwarding mechanism. The `NEXT_SCREEN_NAME` is always set alongside the ID for UI purposes.

### Constants naming
The `KKW21502SFConst` class uses Japanese string values as constants, not English keys. This is the project's convention for field naming - the Japanese strings serve as the canonical field identifiers across the bean, service mappers, and screen definitions.
