# Business Logic — FUW02201SFLogic.init() [246 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `eo.web.webview.FUW02201SF.FUW02201SFLogic` |
| Layer | Screen Logic (Controller/Business Integration) |
| Module | `FUW02201SF` (Package: `eo.web.webview.FUW02201SF`) |

## 1. Role

### FUW02201SFLogic.init()

This method performs the **initial display processing for the Mail Virus Check Service Subscription screen** ( メールウイルスチェックサービス申込画面 ). It serves as the entry point for the FUW02201 screen, responsible for initializing all form data, validating the subscriber's contract state, and preparing pricing information for display.

The method follows a **gate-then-fetch** design pattern: it first validates that the customer's active service contract exists and is in a valid state (not cancelled, not terminated), then counts how many sub-option mail virus check services the customer has been subscribed to, and finally invokes a composite service (FUSV0057) to fetch business parameters, price plans, and cost information.

The method performs three business operations in sequence: **(1) Contract State Validation** — verifying the operation service contract number, POP ID, mail address, and contract status codes are all set and valid; **(2) Mail Virus Service Counting** — iterating over the customer's sub-option service contract information to count matching mail virus check subscriptions; **(3) Pricing Information Fetch** — calling the FUSV0057 service (comprising 5 SC/CBS endpoints) to retrieve business parameter settings, price plan details, sub-option service agreement info, and initial fee information, then determining whether the customer qualifies for free pricing display.

This is a **screen entry point** — it is the initialization method called by the X31 web framework when the FUW02201 screen is first accessed. It populates the form DataBean with pre-computed display values and sets navigation metadata for subsequent screen transitions.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["init() Entry"])
    CHECK_OROSI["Check Orosi / Device Integrity"]
    GET_SERVICE_BEAN["Get Service Form DataBean"]
    GET_COMMON_BEAN["Get Common Info DataBean"]
    NAVIGATE_BEAN["Navigate DataBean hierarchy:
CommonInfo -> WEB_CHG_INFO -> GEN_CUST_KEI_INFO
-> SVC_KEI_INFO -> SEIKY_KEI_INFO -> SVC_KEI_UCWK_INFO
-> OP_SVC_KEI_INFO -> SBOP_SVC_KEI_INFO"]
    GET_PRC_GRP["Get PrcGrpCd and KanyuKeiPayHoshikiCd from svcKeiInfoBean"]
    SET_MANSION_INIT["Set MANSION_DIV = (prcGrpCd == CD00133_04
&& kanyuKeiPayHoshikiCd == CD01216_003)"]
    CHECK_SEIKY_STAT["Check seikyKeiStat != CD00037_100"]
    ERROR_SEIKY["Throw Error Code 0102
(Contract Status Error)"]
    GET_OP_FIELDS["Get opSvcKeiInfo fields:
opSvcStat, popid, mlad, opSvcNo"]
    CHECK_OP_SVC_NO["Check opSvcNo is null"]
    ERROR_OP_SVC_NO["Throw Error Code 0002
(System Error - No Contract Number)"]
    CHECK_POPID_MLAD["Check popid OR mlad is null"]
    ERROR_POP_MLAD["Throw Error Code 0102
(Contract Status Error)"]
    CHECK_OP_STAT["Check opSvcStat not in (020, 030, 100)"]
    ERROR_OP_STAT["Throw Error Code 0102
(Contract Status Error)"]
    MAIL_VIRUS_LOOP["Loop SBOP_SVC_KEI_INFO array"]
    CHECK_SBOP_SVC_CD["Check sbopSvcCd != CD00137_D03
(Mail Virus Check)"]
    SKIP_SBOP["Continue to next iteration"]
    CHECK_SBOP_STAT["Check sbopSvcKeiStat in (910, 920)
(Terminated / Cancelled)"]
    SKIP_SBOP_STAT["Continue to next iteration"]
    CHECK_OP_SVC_NO_MATCH["Check opSvcKeiNo == opSvcKeiInfoOpSvcNo"]
    COUNT_MAIL_VIRUS["Increment countMailVirus"]
    TRANSLATE_FIELDS["Set NOW_MLAD and NOW_POP_ID into bean"]
    CREATE_PARAM_MAP["Create paramMap with
USECASE_ID = FUSV0057"]
    CREATE_MAPPER["Create FUSV0057_FUSV0057OPDBMapper"]
    MAP_INPUT_SC["Set mapper input:
setFUSV005701SC (EZM0321A010)
setFUSV005702SC (EZM0321A010)
setFUSV005703SC (EKK0601B001)
setFUSV005704SC (EKK1881A010)
setFUSV005701CC"]
    CREATE_OUTPUT_MAP["Create outputMap"]
    INVOKE_SERVICE["invokeService(paramMap, dataMap, outputMap)"]
    CATCH_WS_EXCEPTION["Catch JCCWebServiceException"]
    ERROR_WS["Throw Error Code 0002
(System Error)"]
    GET_OUTPUT_SC["Get mapper output:
getFUSV005701SC, getFUSV005702SC
getFUSV005703SC, getFUSV005704SC
getFUSV005701CC"]
    CHECK_FREE_OR_NO_BASIC["Check isMuryo OR isNoBasicCost"]
    SET_FREE_PRCS["Set FreePrcInfoMap and
MANSION_DIV = false"]
    SET_PAY_FLG["Set PAY_FLG = true, COST_FLG = true"]
    CHECK_MANSION_TYPE["Check prcGrpCd == CD00133_04
&& kanyuKeiPayHoshikiCd == CD01216_003"]
    SET_MANSION_TRUE["Set MANSION_DIV = true
(Mansion All-inclusive)"]
    SET_MANSION_FALSE["Set MANSION_DIV = false
(Non-mansion type)"]
    CHECK_NO_INIT_COST["Check !isNoInitCost"]
    NO_INIT_COST_MANSION["Re-evaluate MANSION_DIV
based on prcGrpCd and kanyuKeiPayHoshikiCd"]
    SET_PRC_INFO["Set prcInfoArea via
setPrcInfoArea(bean, outputMap, FUSV005703SC,
FUSV005701CC, SCREEN_ID_FUW02201)"]
    SET_DEFAULTS["Set KEIYAKU_YAKKAN_DOI = false
RIYO_KIYAKU_DOI = false"]
    SET_NOW_DAY["Set price display current date
via setPrcDspNowDay"]
    SET_NEXT_SCREEN["Set next screen name and screen ID
in commoninfoBean"]
    GET_OPE_DATE["Get operation date and set to commoninfoBean"]
    RETURN_TRUE["Return true (Normal End)"]

    START --> CHECK_OROSI
    CHECK_OROSI --> GET_SERVICE_BEAN
    GET_SERVICE_BEAN --> GET_COMMON_BEAN
    GET_COMMON_BEAN --> NAVIGATE_BEAN
    NAVIGATE_BEAN --> GET_PRC_GRP
    GET_PRC_GRP --> SET_MANSION_INIT
    SET_MANSION_INIT --> CHECK_SEIKY_STAT
    CHECK_SEIKY_STAT -->|true| ERROR_SEIKY
    CHECK_SEIKY_STAT -->|false| GET_OP_FIELDS
    GET_OP_FIELDS --> CHECK_OP_SVC_NO
    CHECK_OP_SVC_NO -->|true| ERROR_OP_SVC_NO
    CHECK_OP_SVC_NO -->|false| CHECK_POPID_MLAD
    CHECK_POPID_MLAD -->|true| ERROR_POP_MLAD
    CHECK_POPID_MLAD -->|false| CHECK_OP_STAT
    CHECK_OP_STAT -->|true| ERROR_OP_STAT
    CHECK_OP_STAT -->|false| MAIL_VIRUS_LOOP
    MAIL_VIRUS_LOOP --> CHECK_SBOP_SVC_CD
    CHECK_SBOP_SVC_CD -->|true| SKIP_SBOP
    CHECK_SBOP_SVC_CD -->|false| CHECK_SBOP_STAT
    CHECK_SBOP_STAT -->|true| SKIP_SBOP_STAT
    CHECK_SBOP_STAT -->|false| CHECK_OP_SVC_NO_MATCH
    CHECK_OP_SVC_NO_MATCH -->|true| COUNT_MAIL_VIRUS
    CHECK_OP_SVC_NO_MATCH -->|false| MAIL_VIRUS_LOOP
    COUNT_MAIL_VIRUS --> MAIL_VIRUS_LOOP
    SKIP_SBOP --> MAIL_VIRUS_LOOP
    SKIP_SBOP_STAT --> MAIL_VIRUS_LOOP
    MAIL_VIRUS_LOOP -->|end| TRANSLATE_FIELDS
    TRANSLATE_FIELDS --> CREATE_PARAM_MAP
    CREATE_PARAM_MAP --> CREATE_MAPPER
    CREATE_MAPPER --> MAP_INPUT_SC
    MAP_INPUT_SC --> CREATE_OUTPUT_MAP
    CREATE_OUTPUT_MAP --> INVOKE_SERVICE
    INVOKE_SERVICE --> CATCH_WS_EXCEPTION
    CATCH_WS_EXCEPTION -->|exception| ERROR_WS
    CATCH_WS_EXCEPTION -->|no exception| GET_OUTPUT_SC
    GET_OUTPUT_SC --> CHECK_FREE_OR_NO_BASIC
    CHECK_FREE_OR_NO_BASIC -->|true| SET_FREE_PRCS
    CHECK_FREE_OR_NO_BASIC -->|false| SET_PAY_FLG
    SET_FREE_PRCS --> CHECK_NO_INIT_COST
    SET_PAY_FLG --> CHECK_MANSION_TYPE
    CHECK_MANSION_TYPE -->|true| SET_MANSION_TRUE
    CHECK_MANSION_TYPE -->|false| SET_MANSION_FALSE
    SET_MANSION_TRUE --> CHECK_NO_INIT_COST
    SET_MANSION_FALSE --> CHECK_NO_INIT_COST
    CHECK_NO_INIT_COST -->|true| NO_INIT_COST_MANSION
    CHECK_NO_INIT_COST -->|false| SET_PRC_INFO
    NO_INIT_COST_MANSION --> CHECK_MANSION_TYPE_2["Re-evaluate MANSION_DIV
based on prcGrpCd and kanyuKeiPayHoshikiCd"]
    CHECK_MANSION_TYPE_2 -->|true| SET_MANSION_TRUE_2["Set MANSION_DIV = true"]
    CHECK_MANSION_TYPE_2 -->|false| SET_MANSION_FALSE_2["Set MANSION_DIV = false"]
    SET_MANSION_TRUE_2 --> SET_PRC_INFO
    SET_MANSION_FALSE_2 --> SET_PRC_INFO
    SET_PRC_INFO --> SET_DEFAULTS
    SET_DEFAULTS --> SET_NOW_DAY
    SET_NOW_DAY --> SET_NEXT_SCREEN
    SET_NEXT_SCREEN --> GET_OPE_DATE
    GET_OPE_DATE --> RETURN_TRUE
    ERROR_SEIKY --> END_FAIL(["End: false"])
    ERROR_OP_SVC_NO --> END_FAIL
    ERROR_POP_MLAD --> END_FAIL
    ERROR_OP_STAT --> END_FAIL
    ERROR_WS --> END_FAIL
```

**Constant Resolution:**

| Constant | Value | Business Meaning |
|----------|-------|-----------------|
| `JFUStrConst.CD00133_04` | `"04"` | Price group code — Mansion (all-inclusive) type |
| `JFUStrConst.CD01216_003` | `"003"` | Subscription contract payment method code — Mansion collective payment |
| `JFUStrConst.CD00037_100` | `"100"` | Contract status — Service provision in progress |
| `JFUStrConst.CD00037_030` | `"030"` | Contract status — Contract completed (settled) |
| `JFUStrConst.CD00037_020` | `"020"` | Contract status — Inspection completed |
| `JFUStrConst.CD00037_910` | `"910"` | Contract status — Contract terminated |
| `JFUStrConst.CD00037_920` | `"920"` | Contract status — Cancelled |
| `JFUStrConst.CD00137_D03` | `"D03"` | Sub-option service code — Mail Virus Check service |
| `JFUStrConst.ERROR_CODE_0102` | `"0102"` | Error code — Contract status error |
| `JFUStrConst.ERROR_CODE_0002` | `"0002"` | Error code — System error |

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| - | `(none)` | - | - |

**Instance fields / external state read by this method:**

| Source | Description |
|--------|-------------|
| `this` (FUW02201SFLogic) | Screen logic instance providing operation date, screen ID, and other screen context via `JFUWebCommon` accessors |
| `super.getServiceFormBean()` | Service form DataBean holding screen-specific form data and display values |
| `super.getCommonInfoBean()` | Common information DataBean holding cross-screen shared data (customer info, contract info, next screen navigation) |
| `commoninfoBean` | Shared bean containing the full customer-contract hierarchy: WEB_CHG_INFO -> GEN_CUST_KEI_INFO -> SVC_KEI_INFO -> SEIKY_KEI_INFO -> SVC_KEI_UCWK_INFO -> OP_SVC_KEI_INFO -> SBOP_SVC_KEI_INFO |

## 4. CRUD Operations / Called Services

### Pre-computed evidence from code analysis graph:

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| - | `JFUWebCommon.checkOrosi` | JFUWebCommon | - | Checks device/oroshi integrity before processing |
| R | `OneStopDataBeanAccessArray.getDataBean` | - | - | Navigates nested DataBean hierarchy to extract customer/contract information |
| - | `OneStopDataBeanAccess.sendMessageString` | - | - | Reads string values (prcGrpCd, kanyuKeiPayHoshikiCd, seikyKeiStat, popid, mlad, opSvcNo, sbopSvcCd, sbopSvcKeiStat) from DataBeans |
| - | `OneStopDataBeanAccess.sendMessageBoolean` | - | - | Sets boolean values (MANSION_DIV, PAY_FLG, COST_FLG, KEIYAKU_YAKKAN_DOI, RIYO_KIYAKU_DOI) into DataBeans |
| R | `OneStopDataBeanAccess.getDataBeanArray` | - | - | Traverses hierarchical DataBean structure for customer/contract/service info |
| W | `OneStopDataBeanAccess.sendMessageString` | - | - | Writes NOW_MLAD, NOW_POP_ID, NEXT_SCREEN_NAME, NEXT_SCREEN_ID into DataBeans |
| W | `OneStopDataBeanAccess.sendMessageBoolean` | - | - | Writes MANSION_DIV, PAY_FLG, COST_FLG, KEIYAKU_YAKKAN_DOI, RIYO_KIYAKU_DOI into DataBeans |
| R | `OneStopDataBeanAccessArray.getCount` | - | - | Iterates over SBOP_SVC_KEI_INFO array to count mail virus check services |
| - | `FUSV0057_FUSV0057OPDBMapper.setFUSV005701SC` | EZM0321A010 | - | Maps input parameters for Business Parameter Management Agreement SC |
| - | `FUSV0057_FUSV0057OPDBMapper.setFUSV005702SC` | EZM0321A010 | - | Maps input parameters for Business Parameter Management Agreement SC (second call) |
| - | `FUSV0057_FUSV0057OPDBMapper.setFUSV005703SC` | EKK0601B001 | - | Maps input parameters for Price Plan Fixed Unit Price (Option Submission Fee) List SC |
| - | `FUSV0057_FUSV0057OPDBMapper.setFUSV005704SC` | EKK1881A010 | - | Maps input parameters for Price Code - Sub-option Service Agreement SC |
| - | `FUSV0057_FUSV0057OPDBMapper.setFUSV005701CC` | EKK0721A010 | - | Maps input parameters for Initial Fee List CC |
| - | `JCCBatCommon.invokeService` | - | - | Invokes composite service FUSV0057 with paramMap, dataMap, and outputMap |
| R | `FUSV0057_FUSV0057OPDBMapper.getFUSV005701SC` | EZM0321A010 | - | Retrieves Business Parameter Management Agreement results (POP server, SMTP server) |
| R | `FUSV0057_FUSV0057OPDBMapper.getFUSV005702SC` | EZM0321A010 | - | Retrieves second Business Parameter Management Agreement result |
| R | `FUSV0057_FUSV0057OPDBMapper.getFUSV005703SC` | EKK0601B001 | - | Retrieves Price Plan Fixed Unit Price list; returns isNoBasicCost flag |
| R | `FUSV0057_FUSV0057OPDBMapper.getFUSV005704SC` | EKK1881A010 | - | Retrieves Price Code - Sub-option Service Agreement list; returns isMuryo (free) flag |
| R | `FUSV0057_FUSV0057OPDBMapper.getFUSV005701CC` | EKK0721A010 | - | Retrieves Initial Fee list; returns isNoInitCost flag |
| - | `JFUWebCommon.setFreePrcInfoMap` | JFUWebCommon | - | Sets free pricing information display map for the screen |
| R | `JFUWebCommon.getOpeDate` | JFUWebCommon | - | Retrieves the current operation date |
| - | `JFUWebCommon.setPrcInfoArea` | JFUWebCommon | - | Assembles and sets price information area display data for the screen |
| - | `JFUWebCommon.setPrcDspNowDay` | JFUWebCommon | - | Sets the current date display for price table presentation |
| - | `JFUWebCommon.getScreenId` | JFUWebCommon | - | Retrieves the screen ID for the current screen context |
| - | `setFuOpedate` | FUW02201SFLogic | - | Sets the operation date into the common info bean |

**SC Code Reference Table:**

| SC Code | Full Name (from mapper comments) |
|---------|---------------------------------|
| EZM0321A010 | Business Parameter Management Agreement SC (業務パラメータ管理同意SC) |
| EKK0601B001 | Price Plan Fixed Unit Price (Option Submission Fee) List SC (料金プラン固定単価（オプション申込料金）一覧照会SC) |
| EKK1881A010 | Price Code - Sub-option Service Agreement SC (料金コード_サブオプションサービス同意照会SC) |
| EKK0721A010 | Initial Fee List CC (初期費用一覧照会CC) |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Screen: FUW02201 | `X31 Screen Controller` -> `FUW02201SFLogic.init()` | `setFUSV005701SC [R] EZM0321A010 (POP/SMTP server)`<br>`setFUSV005702SC [R] EZM0321A010 (Business params)`<br>`setFUSV005703SC [R] EKK0601B001 (Price plan list)`<br>`setFUSV005704SC [R] EKK1881A010 (Sub-option price code)`<br>`setFUSV005701CC [R] EKK0721A010 (Initial fee list)` |

**Notes:**
- This method is the **screen initialization entry point** for the FUW02201 Mail Virus Check Service Subscription screen. It is invoked by the X31 web framework's screen controller when the screen is first loaded, based on the screen ID configuration mapping `FUW02201` to `FUW02201SFLogic.init()`.
- No other application classes explicitly call `init()` — the X31 framework handles dispatch via screen ID routing.
- The terminal endpoints are all **Read (R)** operations — this method is purely an initialization/display method that fetches data for screen rendering without modifying persistent data.

## 6. Per-Branch Detail Blocks

**Block 1** — [CALL] `(L93)` Device integrity check

> Performs Orosi (device) integrity check before processing.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `JFUWebCommon.checkOrosi(this)` | Check device/oroshi integrity |

**Block 2** — [SET] `(L96)` Service form DataBean acquisition

> Retrieves the service form DataBean for screen-specific data.

| # | Type | Code |
|---|------|------|
| 1 | SET | `X31SDataBeanAccess bean = super.getServiceFormBean()` | Service form bean |

**Block 3** — [SET] `(L100)` Common info DataBean acquisition

> Retrieves the common information DataBean for cross-screen shared data.

| # | Type | Code |
|---|------|------|
| 1 | SET | `X31SDataBeanAccess commoninfoBean = super.getCommonInfoBean()` | Common info bean |

**Block 4** — [SET] `(L103-104)` Navigate to WEB_CHG_INFO sub-bean

| # | Type | Code |
|---|------|------|
| 1 | SET | `X31SDataBeanAccessArray subBeanArray = commoninfoBean.getDataBeanArray(CommonInfoCFConst.WEB_CHG_INFO)` | Web change info array |
| 2 | SET | `X31SDataBeanAccess webChgInfoBean = subBeanArray.getDataBean(0)` | First WEB_CHG_INFO element |

**Block 5** — [SET] `(L107-108)` Navigate to GEN_CUST_KEI_INFO (Current Customer Contract Info)

| # | Type | Code |
|---|------|------|
| 1 | SET | `X31SDataBeanAccessArray genCustKeiInfoArray = webChgInfoBean.getDataBeanArray(CommonInfoCFConst.GEN_CUST_KEI_INFO)` | Current customer contract info array |
| 2 | SET | `X31SDataBeanAccess genCustKeiInfoBean = genCustKeiInfoArray.getDataBean(0)` | First element |

**Block 6** — [SET] `(L111-112)` Navigate to SVC_KEI_INFO (Service Contract Info)

| # | Type | Code |
|---|------|------|
| 1 | SET | `X31SDataBeanAccessArray svcKeiInfoArray = genCustKeiInfoBean.getDataBeanArray(CommonInfoCFConst.SVC_KEI_INFO)` | Service contract info array |
| 2 | SET | `X31SDataBeanAccess svcKeiInfoBean = svcKeiInfoArray.getDataBean(0)` | First element |

**Block 7** — [SET] `(L115-116)` Navigate to SEIKY_KEI_INFO (Billing Contract Info)

| # | Type | Code |
|---|------|------|
| 1 | SET | `X31SDataBeanAccessArray seikyKeiInfoArray = svcKeiInfoBean.getDataBeanArray(CommonInfoCFConst.SEIKY_KEI_INFO)` | Billing contract info array |
| 2 | SET | `X31SDataBeanAccess seikyKeiInfoBean = seikyKeiInfoArray.getDataBean(0)` | First element |

**Block 8** — [SET] `(L119-120)` Navigate to SVC_KEI_UCWK_INFO (Service Contract Details Info)

| # | Type | Code |
|---|------|------|
| 1 | SET | `X31SDataBeanAccessArray svcKeiUcwkInfoArray = svcKeiInfoBean.getDataBeanArray(CommonInfoCFConst.SVC_KEI_UCWK_INFO)` | Service contract details array |
| 2 | SET | `X31SDataBeanAccess svcKeiUcwkInfoBean = svcKeiUcwkInfoArray.getDataBean(0)` | First element |

**Block 9** — [SET] `(L123-124)` Navigate to OP_SVC_KEI_INFO (Option Service Contract Info)

| # | Type | Code |
|---|------|------|
| 1 | SET | `X31SDataBeanAccessArray opSvcKeiInfoArray = svcKeiUcwkInfoBean.getDataBeanArray(CommonInfoCFConst.OP_SVC_KEI_INFO)` | Option service contract info array |
| 2 | SET | `X31SDataBeanAccess opSvcKeiInfoBean = opSvcKeiInfoArray.getDataBean(0)` | First element |

**Block 10** — [SET] `(L127)` Navigate to SBOP_SVC_KEI_INFO (Sub-Option Service Contract Info)

| # | Type | Code |
|---|------|------|
| 1 | SET | `X31SDataBeanAccessArray sbOpSvcKeiInfoArray = opSvcKeiInfoBean.getDataBeanArray(CommonInfoCFConst.SBOP_SVC_KEI_INFO)` | Sub-option service contract info array |

**Block 11** — [SET] `(L130-131)` Get price group code and subscription contract payment method code

| # | Type | Code |
|---|------|------|
| 1 | SET | `String prcGrpCd = svcKeiInfoBean.sendMessageString(CommonInfoCFConst.PRC_GRP_CD_23, X31CWebConst.DATABEAN_GET_VALUE)` | Price group code |
| 2 | SET | `String kanyuKeiPayHoshikiCd = svcKeiInfoBean.sendMessageString(CommonInfoCFConst.KANYU_KEI_PAY_HOSHIKI_CD_23, X31CWebConst.DATABEAN_GET_VALUE)` | Subscription contract payment method code |

**Block 12** — [CALL] `(L134-135)` Set initial MANSION_DIV value

> Sets MANSION_DIV based on whether the customer is a mansion (all-inclusive) type.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `bean.sendMessageBoolean(FUW02201SFConst.MANSION_DIV, X31CWebConst.DATABEAN_SET_VALUE, JFUStrConst.CD00133_04.equals(prcGrpCd) && JFUStrConst.CD01216_003.equals(kanyuKeiPayHoshikiCd))` | Set true if mansion all-inclusive type |

**Block 13** — [IF] `(L138)` seikyKeiStat validation [SEIKY_KEI_STAT_32 != "100"] (L138)

> Checks that the billing contract status is "100" (Service provision in progress). If not, throws a contract status error.

| # | Type | Code |
|---|------|------|
| 1 | SET | `String seikyKeiStat = seikyKeiInfoBean.sendMessageString(CommonInfoCFConst.SEIKY_KEI_STAT_32, X31CWebConst.DATABEAN_GET_VALUE)` | Billing contract status |
| 2 | IF | `if (!JFUStrConst.CD00037_100.equals(seikyKeiStat))` | [SEIKY_KEI_STAT_32 != "100" (Service provision in progress)] |
| 3 | THROW | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0102)` | Contract status error |

**Block 14** — [SET] `(L144-152)` Get option service contract fields

| # | Type | Code |
|---|------|------|
| 1 | SET | `String opSvcKeiInfoOpSvcStat = opSvcKeiInfoBean.sendMessageString(CommonInfoCFConst.OP_SVC_KEI_STAT_28, X31CWebConst.DATABEAN_GET_VALUE)` | Option service contract status |
| 2 | SET | `String opSvcKeiInfoPopid = opSvcKeiInfoBean.sendMessageString(CommonInfoCFConst.POP_ID_28, X31CWebConst.DATABEAN_GET_VALUE)` | POP ID |
| 3 | SET | `String opSvcKeiInfoMlad = opSvcKeiInfoBean.sendMessageString(CommonInfoCFConst.MLAD_28, X31CWebConst.DATABEAN_GET_VALUE)` | Mail address |
| 4 | SET | `String opSvcKeiInfoOpSvcNo = opSvcKeiInfoBean.sendMessageString(CommonInfoCFConst.OP_SVC_KEI_NO_28, X31CWebConst.DATABEAN_GET_VALUE)` | Option service contract number |

**Block 15** — [IF] `(L153)` opSvcNo null check (L153)

> If the option service contract number is not set, throws a system error.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if (JFUWebCommon.isNull(opSvcKeiInfoOpSvcNo))` | [opSvcNo is null — No Contract Number] |
| 2 | EXEC | `X31SWebLog.DEBUG_LOG.debug("【オプション契約番号未設定エラー】")` | Log: "Option contract number not set error" |
| 3 | THROW | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0002)` | System error |

**Block 16** — [IF] `(L158)` popid/mlad null check (L158)

> If POP ID or mail address is not set, throws a contract status error.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if (JFUWebCommon.isNull(opSvcKeiInfoPopid) || JFUWebCommon.isNull(opSvcKeiInfoMlad))` | [popid or mlad is null — Contract Status Error] |
| 2 | THROW | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0102)` | Contract status error |

**Block 17** — [IF] `(L166)` opSvcStat validation [not in (020, 030, 100)] (L166)

> Checks that the option service contract status is one of the valid states: "020" (Inspection completed), "030" (Contract completed), or "100" (Service provision in progress). If not, throws a contract status error.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if (!JFUStrConst.CD00037_100.equals(opSvcKeiInfoOpSvcStat) && !JFUStrConst.CD00037_030.equals(opSvcKeiInfoOpSvcStat) && !JFUStrConst.CD00037_020.equals(opSvcKeiInfoOpSvcStat))` | [opSvcStat not in (CD00037_100="100", CD00037_030="030", CD00037_020="020")] |
| 2 | THROW | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0102)` | Contract status error |

**Block 18** — [FOR LOOP] `(L172)` Mail virus check service count loop (L172)

> Iterates over the sub-option service contract info array to count how many mail virus check services the customer has been subscribed to. Only counts services that match the mail virus check sub-option code (CD00137_D03 = "D03"), are in active status (not 910/920), and belong to the same option service contract (matching opSvcKeiNo).

| # | Type | Code |
|---|------|------|
| 1 | SET | `int countMailVirus = 0` | Initialize counter |
| 2 | FOR | `for (int i = 0; i < sbOpSvcKeiInfoArray.getCount(); i++)` | Loop over sub-option service contracts |

**Block 18.1** — [IF] `(L178)` sbopSvcCd check [sbopSvcCd != "D03"] (L178)

> Skip iterations where the sub-option service code is not the mail virus check code.

| # | Type | Code |
|---|------|------|
| 1 | SET | `X31SDataBeanAccess sbOpSvcKeiInfoBean = sbOpSvcKeiInfoArray.getDataBean(i)` | Current sub-option bean |
| 2 | SET | `String sbopSvcCd = sbOpSvcKeiInfoBean.sendMessageString(CommonInfoCFConst.SBOP_SVC_CD_29, X31CWebConst.DATABEAN_GET_VALUE)` | Sub-option service code |
| 3 | IF | `if (!JFUStrConst.CD00137_D03.equals(sbopSvcCd))` | [sbopSvcCd != "D03" (Mail Virus Check)] |
| 4 | EXEC | `continue` | Skip to next iteration |

**Block 18.2** — [IF] `(L185)` sbopSvcKeiStat check [in (910, 920)] (L185)

> Skip iterations where the sub-option service contract status is terminated or cancelled.

| # | Type | Code |
|---|------|------|
| 1 | SET | `String sbopSvcKeiStat = sbOpSvcKeiInfoBean.sendMessageString(CommonInfoCFConst.SBOP_SVC_KEI_STAT_29, X31CWebConst.DATABEAN_GET_VALUE)` | Sub-option service contract status |
| 2 | IF | `if (JFUStrConst.CD00037_910.equals(sbopSvcKeiStat) || JFUStrConst.CD00037_920.equals(sbopSvcKeiStat))` | [sbopSvcKeiStat in (910="Terminated", 920="Cancelled")] |
| 3 | EXEC | `continue` | Skip to next iteration |

**Block 18.3** — [IF] `(L191)` opSvcKeiNo match check (L191)

> If the sub-option service contract number matches the main option service contract number, increment the mail virus count.

| # | Type | Code |
|---|------|------|
| 1 | SET | `String opSvcKeiNo = sbOpSvcKeiInfoBean.sendMessageString(CommonInfoCFConst.OP_SVC_KEI_NO_29, X31CWebConst.DATABEAN_GET_VALUE)` | Sub-option service contract number |
| 2 | IF | `if (opSvcKeiInfoOpSvcNo.equals(opSvcKeiNo))` | [Matching option service contract number] |
| 3 | SET | `countMailVirus++` | Increment mail virus check service count |

**Block 19** — [CALL] `(L205-208)` Translate fields to bean

> Sets the current mail address and POP ID into the service form bean for screen display.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `bean.sendMessageString(FUW02201SFConst.NOW_MLAD, X31CWebConst.DATABEAN_SET_VALUE, opSvcKeiInfoMlad)` | Set current mail address [-> "現在のメールアドレス"] |
| 2 | CALL | `bean.sendMessageString(FUW02201SFConst.NOW_POP_ID, X31CWebConst.DATABEAN_SET_VALUE, opSvcKeiInfoPopid)` | Set current POP ID [-> "現在のPOP ID"] |

**Block 20** — [SET] `(L213-218)` Create service call parameter structure

> Creates the use case parameter map and mapper instance for the FUSV0057 service call. Sets up input mapping for 5 SC/CBS endpoints.

| # | Type | Code |
|---|------|------|
| 1 | SET | `HashMap<String, String> paramMap = new HashMap<String, String>(16)` | Use case parameter map |
| 2 | SET | `paramMap.put(X31CWebConst.TELEGRAM_INFO_USECASE_ID, USECASE_ID_FUSV0057)` | [-> USECASE_ID_FUSV0057 = "FUSV0057"] |
| 3 | SET | `FUSV0057_FUSV0057OPDBMapper mapper = new FUSV0057_FUSV0057OPDBMapper()` | Mapper instance |
| 4 | SET | `HashMap<String, Object> dataMap = new HashMap<String, Object>()` | Input data map |
| 5 | SET | `X31SDataBeanAccess[] paramBean = { bean, svcKeiInfoBean }` | [0]=form bean, [1]=service contract info bean |
| 6 | CALL | `mapper.setFUSV005701SC(paramBean, dataMap, JPCModelConstant.FUNC_CD_1)` | Business Parameter Management Agreement SC input [FUNC_CD_1] |
| 7 | CALL | `mapper.setFUSV005702SC(paramBean, dataMap, JPCModelConstant.FUNC_CD_1)` | Business Parameter Management Agreement SC input [FUNC_CD_1] |
| 8 | CALL | `mapper.setFUSV005703SC(paramBean, dataMap, JPCModelConstant.FUNC_CD_1)` | Price Plan Fixed Unit Price (Option Fee) List SC input [FUNC_CD_1] |
| 9 | CALL | `mapper.setFUSV005704SC(paramBean, dataMap, JPCModelConstant.FUNC_CD_1)` | Price Code - Sub-option Service Agreement SC input [FUNC_CD_1] |
| 10 | CALL | `mapper.setFUSV005701CC(paramBean, dataMap, null)` | Initial Fee List CC input [null func_code] |

**Block 21** — [TRY-CATCH] `(L224-234)` Service invocation (L224)

> Invokes the FUSV0057 composite service. Catches web service exceptions and converts them to system errors.

| # | Type | Code |
|---|------|------|
| 1 | SET | `HashMap<String, Object> outputMap = new HashMap<String, Object>()` | Output result map |
| 2 | CALL | `invokeService(paramMap, dataMap, outputMap)` | Invoke FUSV0057 composite service |
| 3 | CATCH | `catch (JCCWebServiceException se)` | Web service exception |
| 4 | THROW | `throw new JCCBusinessException(JFUStrConst.ERROR_CODE_0002)` | System error |

**Block 22** — [CALL] `(L238-242)` Get SC/CBS output results

> Retrieves results from the FUSV0057 service call. The `getFUSV005703SC` returns isNoBasicCost (boolean) and `getFUSV005704SC` returns isMuryo (free flag), `getFUSV005701CC` returns isNoInitCost (no initial fee flag).

| # | Type | Code |
|---|------|------|
| 1 | CALL | `mapper.getFUSV005701SC(bean, outputMap)` | Business Parameter Management Agreement SC output |
| 2 | CALL | `mapper.getFUSV005702SC(bean, outputMap)` | Business Parameter Management Agreement SC output |
| 3 | SET | `boolean isNoBasicCost = mapper.getFUSV005703SC(bean, outputMap)` | Price plan fixed unit price result |
| 4 | SET | `boolean isMuryo = mapper.getFUSV005704SC(bean, outputMap, countMailVirus)` | Sub-option service price code result (free flag + mail virus count) |
| 5 | SET | `boolean isNoInitCost = mapper.getFUSV005701CC(bean, outputMap)` | Initial fee list result (no initial fee flag) |

**Block 23** — [IF-ELSE] `(L244)` Free pricing vs. paid pricing determination (L244)

> Determines whether the customer qualifies for free pricing display. If either isMuryo (free service count) or isNoBasicCost (no basic cost) is true, sets free pricing info map and forces MANSION_DIV to false. Otherwise, sets paid pricing flags.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if (isMuryo || isNoBasicCost)` | [Free pricing or no basic cost] |
| 2 | CALL | `JFUWebCommon.setFreePrcInfoMap(outputMap, SC_TITLE_FUSV005703)` | Set free pricing info map [-> "FUSV005703SC"] |
| 3 | CALL | `bean.sendMessageBoolean(FUW02201SFConst.MANSION_DIV, X31CWebConst.DATABEAN_SET_VALUE, false)` | Force MANSION_DIV = false (free case) |

**Block 23.1** — [ELSE] `(L258)` Paid pricing path [Paid Flag]

> Customer is paying for the service. Set PAY_FLG and COST_FLG to true, then re-evaluate MANSION_DIV.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `bean.sendMessageBoolean(FUW02201SFConst.PAY_FLG, X31CWebConst.DATABEAN_SET_VALUE, true)` | Set paid flag |
| 2 | CALL | `bean.sendMessageBoolean(FUW02201SFConst.COST_FLG, X31CWebConst.DATABEAN_SET_VALUE, true)` | Set cost flag |

**Block 23.1.1** — [IF-ELSE] `(L263)` Mansion type re-evaluation [prcGrpCd == "04" && kanyuKeiPayHoshikiCd == "003"] (L263)

> Re-evaluates MANSION_DIV based on price group and payment method.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if (JFUStrConst.CD00133_04.equals(prcGrpCd) && JFUStrConst.CD01216_003.equals(kanyuKeiPayHoshikiCd))` | [Mansion all-inclusive type] |
| 2 | CALL | `bean.sendMessageBoolean(FUW02201SFConst.MANSION_DIV, X31CWebConst.DATABEAN_SET_VALUE, true)` | MANSION_DIV = true |
| 3 | ELSE | — | Non-mansion type |
| 4 | CALL | `bean.sendMessageBoolean(FUW02201SFConst.MANSION_DIV, X31CWebConst.DATABEAN_SET_VALUE, false)` | MANSION_DIV = false |

**Block 24** — [IF] `(L275)` Initial fee paid check [!isNoInitCost] (L275)

> If the initial fee is not free (paid), re-evaluate MANSION_DIV based on price group and payment method, same logic as Block 23.1.1.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if (!isNoInitCost)` | [Initial fee is paid] |
| 2 | CALL | `bean.sendMessageBoolean(FUW02201SFConst.COST_FLG, X31CWebConst.DATABEAN_SET_VALUE, true)` | Ensure COST_FLG = true |
| 3 | IF | `if (JFUStrConst.CD00133_04.equals(prcGrpCd) && JFUStrConst.CD01216_003.equals(kanyuKeiPayHoshikiCd))` | [Mansion all-inclusive type] |
| 4 | CALL | `bean.sendMessageBoolean(FUW02201SFConst.MANSION_DIV, X31CWebConst.DATABEAN_SET_VALUE, true)` | MANSION_DIV = true |
| 5 | ELSE | — | Non-mansion type |
| 6 | CALL | `bean.sendMessageBoolean(FUW02201SFConst.MANSION_DIV, X31CWebConst.DATABEAN_SET_VALUE, false)` | MANSION_DIV = false |

**Block 25** — [CALL] `(L304)` Set price information area

> Assembles and sets the price information area display data for the screen, combining results from FUSV005703SC (price plan) and FUSV005701CC (initial fee).

| # | Type | Code |
|---|------|------|
| 1 | CALL | `JFUWebCommon.setPrcInfoArea(bean, outputMap, SC_TITLE_FUSV005703, CC_TITLE_FUSV005701, JFUScreenConst.SCREEN_ID_FUW02201)` | Set price info area display [-> "FUSV005703SC", "FUSV005701CC", "FUW02201"] |

**Block 26** — [SET] `(L307-309)` Set default agreement flags to false

> Initializes contract terms agreement and usage agreement checkboxes to unchecked state.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `bean.sendMessageBoolean(FUW02201SFConst.KEIYAKU_YAKKAN_DOI, X31CWebConst.DATABEAN_SET_VALUE, false)` | Contract terms agreement [-> "契約約款同意"] |
| 2 | CALL | `bean.sendMessageBoolean(FUW02201SFConst.RIYO_KIYAKU_DOI, X31CWebConst.DATABEAN_SET_VALUE, false)` | Usage agreement [-> "利用規約同意"] |

**Block 27** — [CALL] `(L311)` Set current date for price display

| # | Type | Code |
|---|------|------|
| 1 | CALL | `JFUWebCommon.setPrcDspNowDay(this)` | Set price display current date |

**Block 28** — [SET] `(L314-319)` Set next screen navigation info

> Sets the next screen name and screen ID for navigation after the user submits the subscription form.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `commoninfoBean.sendMessageString(CommonInfoCFConst.NEXT_SCREEN_NAME, X31CWebConst.DATABEAN_SET_VALUE, JFUScreenConst.SCREEN_NAME_FUW02201)` | Next screen name |
| 2 | CALL | `commoninfoBean.sendMessageString(CommonInfoCFConst.NEXT_SCREEN_ID, X31CWebConst.DATABEAN_SET_VALUE, JFUWebCommon.getScreenId(this))` | Next screen ID |
| 3 | SET | `String opeDate = JFUWebCommon.getOpeDate(this, null)` | Get operation date |
| 4 | CALL | `setFuOpedate(commoninfoBean, opeDate)` | Set operation date into common info bean |

**Block 29** — [RETURN] `(L321)` Normal end

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return true` | Normal end |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `FUW02201` | Screen ID | Mail Virus Check Service Subscription screen — allows users to subscribe to the optional mail virus check service |
| `sbopSvcCd` | Field | Sub-option service code — classifies the type of sub-option service (CD00137_D03 = "D03" identifies Mail Virus Check service) |
| `sbopSvcKeiStat` | Field | Sub-option service contract status — 910=Terminated, 920=Cancelled, other values indicate active status |
| `opSvcKeiNo` | Field | Option service contract number — internal identifier for the option service contract line item |
| `opSvcKeiInfoOpSvcNo` | Field | Option service contract number (from main contract) — used to match sub-option services to their parent contract |
| `opSvcKeiInfoPopid` | Field | POP ID — post office protocol server identifier for the customer's email account |
| `opSvcKeiInfoMlad` | Field | Mail address — the customer's email address for the option service |
| `opSvcKeiInfoOpSvcStat` | Field | Option service contract status — 020=Inspection completed, 030=Contract completed, 100=Service provision in progress |
| `seikyKeiStat` | Field | Billing contract status — 100 indicates the billing contract is active and service is being provided |
| `prcGrpCd` | Field | Price group code — classifies the pricing tier (CD00133_04 = "04" indicates mansion all-inclusive type) |
| `kanyuKeiPayHoshikiCd` | Field | Subscription contract payment method code — CD01216_003 = "003" indicates mansion collective payment |
| `MANSION_DIV` | Field | Mansion division flag — indicates whether the customer is a mansion (apartment complex) with all-inclusive pricing (true) or an individual/non-mansion customer (false) |
| `PAY_FLG` | Field | Paid flag — indicates whether the service is a paid service (true) or free (false) |
| `COST_FLG` | Field | Cost flag — indicates whether initial fees apply to the service |
| `KEIYAKU_YAKKAN_DOI` | Field | Contract terms agreement checkbox — user consent to contract terms (initialized to false on screen load) |
| `RIYO_KIYAKU_DOI` | Field | Usage agreement checkbox — user consent to service usage terms (initialized to false on screen load) |
| `NOW_MLAD` | Field | Current mail address — displays the customer's current email address on the subscription screen |
| `NOW_POP_ID` | Field | Current POP ID — displays the customer's current POP server identifier on the subscription screen |
| `countMailVirus` | Local | Mail virus check service count — number of active mail virus check subscriptions matching the main option service contract |
| `isMuryo` | Return | Free flag — indicates whether the sub-option service price code configuration qualifies for free service |
| `isNoBasicCost` | Return | No basic cost flag — indicates whether the price plan has no basic fixed unit price (i.e., no ongoing charges) |
| `isNoInitCost` | Return | No initial cost flag — indicates whether there are no initial setup fees for the service |
| `FUSV0057` | Service ID | Mail Virus Check Service Subscription (initial display) composite service — invokes multiple SC/CBS endpoints to gather pricing and parameter data |
| `EZM0321A010` | SC Code | Business Parameter Management Agreement SC — retrieves business parameter settings (POP server, SMTP server) for the service |
| `EKK0601B001` | SC Code | Price Plan Fixed Unit Price (Option Submission Fee) List SC — retrieves price plan pricing details for optional services |
| `EKK1881A010` | SC Code | Price Code - Sub-option Service Agreement SC — retrieves pricing codes and agreement details for sub-option services |
| `EKK0721A010` | CC Code | Initial Fee List CC — retrieves initial setup fees for the service subscription |
| FTTH | Business term | Fiber To The Home — fiber-optic broadband service (K-Opticom's primary broadband offering) |
| SOD | Acronym | Service Order Data — telecom order fulfillment data entity |
| POP | Acronym | Post Office Protocol — email retrieval protocol; POP ID identifies the mail server |
| SMTP | Acronym | Simple Mail Transfer Protocol — email transmission protocol; SMTP server is used for sending mail |
| SC | Acronym | Service Component — a service-layer component that performs data access and business operations |
| CC | Acronym | Common Component — a reusable component for common business functions (e.g., data lookups) |
| CBS | Acronym | CBS Service — Customer Business System service; a backend service call |
| DataBean | Technical | X31 framework data transfer object for screen form data and navigation info |
| invokeService | Method | Framework method that invokes a composite service with input maps and populates output maps |
