---

# Business Logic — JBSbatKKKjFinClDataInTrn.updateKktkSvcKei() [99 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `eo.business.service.JBSbatKKKjFinClDataInTrn` |
| Layer | Service (Inferred from package: `eo.business.service`, class naming `JBSbat*FinClDataInTrn` — Financial Data Input Service) |
| Module | `service` (Package: `eo.business.service`) |

## 1. Role

### JBSbatKKKjFinClDataInTrn.updateKktkSvcKei()

This method performs an **update operation on an equipment-provided service contract** (機器提供サービス契約の更新処理 — *Kiki Teikyou Service Contract*). In the business context of K-Opticom's customer core system, an "equipment-provided service contract" represents a customer agreement where the telecom provider supplies physical hardware (e.g., routers, set-top boxes, ONU devices) as part of a broadband or TV service package. This method handles the renewal or modification of such a contract by reconciling plan start dates against existing stored values and persisting the updated state.

The method implements the **pessimistic locking + update** design pattern: it first acquires an exclusive row-level lock via `selectByPrimaryKeysForUpdateWait`, then conditionally computes update values based on whether the input plan dates differ from the stored dates (if equal, the field is set to empty, signaling "no change"; if different, the old stored value is written, effectively reverting to a prior plan), and finally executes a primary-key-based database update. This pattern ensures that concurrent batch updates on the same contract record are serialized, preventing lost-update anomalies.

Within the larger system, this method serves as a **dedicated financial data input service handler**, specifically invoked by the `execute()` method of the same class (`JBSbatKKKjFinClDataInTrn`) during batch processing cycles. It is a shared utility consumed by the batch entry point, not a screen-facing API. The method's role is to bridge the gap between the input envelope (`kktkSvcKeiMap`) and the persisted database row (`KK_T_KKTK_SVC_KEI`), performing data transformation and concurrency control.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["updateKktkSvcKei method start"])

    START --> INIT["Initialize: map, where_map, value, param arrays"]
    INIT --> FETCH_STR["Fetch strings from kktkSvcKeiMap"]

    FETCH_STR --> GET_NO["Get kktkSvcKeiNoStr from KKTK_SVC_KEI_NO"]
    GET_NO --> GET_GENE["Get geneAddDtmStr from GENE_ADD_DTM"]
    GET_GENE --> GET_PLAN["Get planStaymdStr from PLAN_STAYMD"]
    GET_PLAN --> GET_CHRG["Get planChrgStaymdStr from PLAN_CHRG_STAYMD"]

    GET_CHRG --> BUILD_WHERE["Build where_map: KKTK_SVC_KEI_NO and GENE_ADD_DTM"]
    BUILD_WHERE --> SELECT["selectByPrimaryKeysForUpdateWait - Pessimistic lock"]
    SELECT --> CHECK_MAP{map != null?}

    CHECK_MAP -->|True| PREP_VALUES["Prepare value and param arrays"]

    PREP_VALUES --> SET_KIKI_CHG["value[0]: Equipment change date (empty)"]
    SET_KIKI_CHG --> COMPARE_PLAN{planStart dates match?}

    COMPARE_PLAN -->|Equal| SET_PLAN_EMPTY["value[1]: Plan start date (empty)"]
    COMPARE_PLAN -->|Not Equal| SET_PLAN_OLD["value[1]: Old plan start date"]

    SET_PLAN_EMPTY --> COMPARE_CHRG{planCharge dates match?}
    SET_PLAN_OLD --> COMPARE_CHRG

    COMPARE_CHRG -->|Equal| SET_CHRG_EMPTY["value[2]: Charge plan start date (empty)"]
    COMPARE_CHRG -->|Not Equal| SET_CHRG_OLD["value[2]: Old charge plan start date"]

    SET_CHRG_EMPTY --> SET_APLY_YMD["value[3]: Reservation apply date (empty)"]
    SET_CHRG_OLD --> SET_APLY_YMD

    SET_APLY_YMD --> SET_APLY_CD["value[4]: RSV_APLY_CD_TTDK = 1"]

    SET_APLY_CD --> SET_PARAMS["param[0]: kktkSvcKeiNoStr, param[1]: geneAddDtmStr"]
    SET_PARAMS --> CHECK_DEBUG{Debug logging enabled?}

    CHECK_DEBUG -->|True| LOG_DATA["Print debug log for all values"]
    CHECK_DEBUG -->|False| CALL_EXEC["executeKK_T_KKTK_SVC_KEI_PKUPDATE"]
    LOG_DATA --> CALL_EXEC

    CALL_EXEC --> END_METHOD(["Return / Next"])

    CHECK_MAP -->|False| THROW_ERROR["Throw JBSbatBusinessException EKKB0210CE"]
    THROW_ERROR --> ERROR_END(["End with Exception"])
```

**Business logic summary:**
1. **Data extraction phase**: Reads four fields from the input `kktkSvcKeiMap` — the equipment-provided service contract number, generation registration timestamp, plan start date, and plan charge start date. All values are right-trimmed using `JBSbatStringUtil.Rtrim`.
2. **Pessimistic lock phase**: Builds a WHERE clause from the contract number and generation timestamp, then calls `selectByPrimaryKeysForUpdateWait` to acquire a row-level exclusive lock (with wait), ensuring no other transaction can modify this record concurrently.
3. **Conditional update value computation phase**: If the record exists, computes five update values. Fields `value[0]` and `value[3]` are always set to empty (equipment change date and reservation apply date). For `value[1]` (plan start date) and `value[2]` (charge plan start date), the method compares input dates against stored dates — if they match, the update value is empty (no change); if they differ, the old stored value is used (reverting the field).
4. **Reservation apply code**: Always set to `RSV_APLY_CD_TTDK = "1"` (Reservation Processing / 予約手続き中) per the v20.00.00 change.
5. **Debug logging phase**: If debug-level logging is enabled, outputs all computed values and parameters to the debug log.
6. **Persistence phase**: Invokes `executeKK_T_KKTK_SVC_KEI_PKUPDATE` to perform the actual database UPDATE against `KK_T_KKTK_SVC_KEI`.
7. **Exception handling**: If the pessimistic lock returns no record (null), throws `JBSbatBusinessException` with error code `EKKB0210CE`, indicating the equipment-provided service contract record was not found.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `planStaymd_svcKeiUw` | `String` | Plan start date (service contract detail) — the **expected** plan start date (YYYYMMDD format) derived from the service contract inquiry result. Used to compare against the stored plan start date in the database. If equal, the update field is set to empty (no modification needed); if different, the stored value is carried forward. |
| 2 | `planChrgStaymd_svcKeiUw` | `String` | Plan charge start date (service contract detail) — the **expected** charge plan start date (YYYYMMDD format) derived from the service contract inquiry result. Analogous to `planStaymd_svcKeiUw` but for the billing/charge aspect of the plan. Same comparison logic applies. |
| 3 | `kktkSvcKeiMap` | `JBSbatCommonDBInterface` | Input message (入力電文) — a database interface object carrying the current state of the equipment-provided service contract record. It provides access to key fields including contract number (`KKTK_SVC_KEI_NO`), generation registration timestamp (`GENE_ADD_DTM`), plan start date (`PLAN_STAYMD`), and plan charge start date (`PLAN_CHRG_STAYMD`). Acts as the primary data source for all fetch operations. |

**Instance fields / external state read:**
| Field | Source Class | Business Meaning |
|-------|-------------|------------------|
| `db_KK_T_KKTK_SVC_KEI` | `JBSbatKKKjFinClDataInTrn` (inherited) | DAO/DataAccess object for the `KK_T_KKTK_SVC_KEI` table — provides `selectByPrimaryKeysForUpdateWait` and `updateByPrimaryKeys` operations. |
| `super.logPrint` | Base class (logPrint) | Logging utility for debug-level log output via `printDebugLog` and `chkLogLevel`. |

## 4. CRUD Operations / Called Services

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

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `JBSbatCommonDBInterface.getString` | JBSbatCommon | kktkSvcKeiMap (in-memory) | Reads fields from the input message map — extracts contract number, generation timestamp, plan dates. |
| U | `JBSbatCommonDBInterface.setValue` | JBSbatCommon | where_map (in-memory) | Sets WHERE clause fields for the pessimistic lock query (contract number + generation timestamp). |
| U | `db_KK_T_KKTK_SVC_KEI.selectByPrimaryKeysForUpdateWait` | (inferred: KKFxxxxSC) | KK_T_KKTK_SVC_KEI | Pessimistic lock (select-for-update with wait) — reads the current record to acquire exclusive lock before update. |
| U | `executeKK_T_KKTK_SVC_KEI_PKUPDATE` | (inferred: KKFxxxxCBS) | KK_T_KKTK_SVC_KEI | Executes the actual UPDATE against the database, setting 5 fields (equipment change date, plan start date, charge plan start date, reservation apply date, reservation apply code) keyed by contract number + generation timestamp. |
| R | `super.logPrint.chkLogLevel` | JBSbatLogUtil | - | Checks if debug-level logging is enabled. |
| R | `super.logPrint.printDebugLog` | JBSbatLogUtil | - | Outputs debug log lines with all computed values and parameters. |
| - | `JBSbatStringUtil.Rtrim` | JBSbatStringUtil | - | Right-trims string values extracted from the input map. |
| - | `JBSbatKKConst.RSV_APLY_CD_TTDK` | JBSbatKKConst | - | Constant reference: reservation apply code for "Reservation Processing" = "1". |

**Derived SC Code / Entity analysis:**

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `db_KK_T_KKTK_SVC_KEI.selectByPrimaryKeysForUpdateWait` | KKFxxxxSC | KK_T_KKTK_SVC_KEI | Pessimistic lock on equipment-provided service contract — SELECT FOR UPDATE with wait for concurrency control. |
| U | `executeKK_T_KKTK_SVC_KEI_PKUPDATE` | KKFxxxxCBS | KK_T_KKTK_SVC_KEI | Primary-key-based update of equipment-provided service contract fields — updates KIKI_CHG_YMD, PLAN_STAYMD, PLAN_CHRG_STAYMD, RSV_APLY_YMD, RSV_APLY_CD. |

## 5. Dependency Trace

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

No screen/batch entry points found within 8 hops. Direct callers found: 1 methods.
Terminal operations from this method: `Rtrim` [-], `selectByPrimaryKeysForUpdateWait` [U], `setValue` [-], `chkLogLevel` [-], `printDebugLog` [-], `executeKK_T_KKTK_SVC_KEI_PKUPDATE` [U]  # NOSONAR

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Batch: JBSbatKKKjFinClDataInTrn | `JBSbatKKKjFinClDataInTrn.execute()` -> `updateKktkSvcKei(planStaymd_svcKeiUw, planChrgStaymd_svcKeiUw, kktkSvcKeiMap)` | `selectByPrimaryKeysForUpdateWait [U] KK_T_KKTK_SVC_KEI` → `executeKK_T_KKTK_SVC_KEI_PKUPDATE [U] KK_T_KKTK_SVC_KEI` |

**Call Chain Details:**
- `JBSbatKKKjFinClDataInTrn.execute()` is the batch entry point (a private method in the same class) that orchestrates financial data input processing. It invokes `updateKktkSvcKei()` to update the equipment-provided service contract record as part of a larger batch workflow.
- The `execute()` method acts as a data input processor for financial settlement data, and `updateKktkSvcKei` is one of its sub-steps.

**Terminal operations reached FROM this method:**
- `selectByPrimaryKeysForUpdateWait` [U] `KK_T_KKTK_SVC_KEI` — pessimistic lock acquisition
- `executeKK_T_KKTK_SVC_KEI_PKUPDATE` [U] `KK_T_KKTK_SVC_KEI` — database update

## 6. Per-Branch Detail Blocks

**Block 1** — [VARIABLE INITIALIZATION] (L2308)

> Initializes working variables and arrays for the update operation.

| # | Type | Code |
|---|------|------|
| 1 | SET | `map = new JBSbatCommonDBInterface()` // Select result storage |
| 2 | SET | `where_map = new JBSbatCommonDBInterface()` // WHERE clause for pessimistic lock |
| 3 | SET | `value = null` // Update value array (initialized later) |
| 4 | SET | `param = null` // WHERE parameter array (initialized later) |
| 5 | SET | `kktkSvcKeiNoStr = ""` // Equipment-provided service contract number (機器提供サービス契約番号) |
| 6 | SET | `geneAddDtmStr = ""` // Generation registration timestamp (世代登録年月日時刻分秒) |
| 7 | SET | `planStaymdStr = ""` // Plan start date (プラン開始年月日) |
| 8 | SET | `planChrgStaymdStr = ""` // Plan charge start date (プラン課金開始年月日) |

**Block 2** — [EXEC — FIELD EXTRACTION FROM INPUT MAP] (L2318–L2325)

> Extracts four fields from the input `kktkSvcKeiMap` and right-trims them. These represent the current database state of the equipment-provided service contract.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `kktkSvcKeiNoStr = JBSbatStringUtil.Rtrim(kktkSvcKeiMap.getString(KKTK_SVC_KEI_NO))` // Contract number |
| 2 | EXEC | `geneAddDtmStr = JBSbatStringUtil.Rtrim(kktkSvcKeiMap.getString(GENE_ADD_DTM))` // Generation registration timestamp |
| 3 | EXEC | `planStaymdStr = JBSbatStringUtil.Rtrim(kktkSvcKeiMap.getString(PLAN_STAYMD))` // Plan start date |
| 4 | EXEC | `planChrgStaymdStr = JBSbatStringUtil.Rtrim(kktkSvcKeiMap.getString(PLAN_CHRG_STAYMD))` // Charge plan start date |

**Block 3** — [EXEC — BUILD WHERE CLAUSE FOR PESSIMISTIC LOCK] (L2327–L2328)

> Constructs the WHERE clause for the pessimistic lock query. The WHERE clause uses the primary key (contract number) and the generation timestamp for optimistic concurrency validation.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `where_map.setValue(KKTK_SVC_KEI_NO, kktkSvcKeiNoStr)` // Set contract number in WHERE |
| 2 | EXEC | `where_map.setValue(GENE_ADD_DTM, geneAddDtmStr)` // Set generation timestamp in WHERE |

**Block 4** — [CALL — PESSIMISTIC LOCK ACQUISITION] (L2331)

> Performs a select-for-update query with wait to acquire an exclusive row-level lock. This prevents concurrent batch updates from corrupting the same record.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `map = db_KK_T_KKTK_SVC_KEI.selectByPrimaryKeysForUpdateWait(where_map)` // Pessimistic lock |

**Block 5** — [IF/ELSE — RECORD EXISTS CHECK] `(map != null)` (L2333 / L2380)

> Determines whether the pessimistic lock query found the target record. If null, the contract record does not exist (or was already deleted), and a business exception is thrown.

**Block 5.1** — [IF — PLAN START DATE MATCH] `planStaymd_svcKeiUw.equals(planStaymdStr)` (L2340)

> When the input plan start date equals the stored plan start date, no plan start date modification is needed — set update value to empty. This signals "keep the existing database value unchanged."

| # | Type | Code |
|---|------|------|
| 1 | SET | `value[1] = ""` // Plan start date (empty — no change needed) |

**Block 5.2** — [ELSE — PLAN START DATE DIFFERS] (L2344)

> When the input plan start date differs from the stored value, carry the old stored date into the update value. This effectively "reverts" the plan start date.

| # | Type | Code |
|---|------|------|
| 1 | SET | `value[1] = planStaymdStr` // Plan start date (old stored value) |

**Block 5.3** — [IF/ELSE — CHARGE PLAN START DATE MATCH] `planChrgStaymd_svcKeiUw.equals(planChrgStaymdStr)` (L2349 / L2354)

> Same comparison logic as Block 5.1/5.2 but for the charge plan start date field.

**Block 5.3.1** — [IF — CHARGE DATE MATCH] (L2350)

| # | Type | Code |
|---|------|------|
| 1 | SET | `value[2] = ""` // Charge plan start date (empty — no change) |

**Block 5.3.2** — [ELSE — CHARGE DATE DIFFERS] (L2355)

| # | Type | Code |
|---|------|------|
| 1 | SET | `value[2] = planChrgStaymdStr` // Charge plan start date (old stored value) |

**Block 5.4** — [SET — ALWAYS-EMPTY FIELDS] (L2359, L2362)

> Two fields are always set to empty: equipment change date and reservation apply date. These fields are not updated in this operation.

| # | Type | Code |
|---|------|------|
| 1 | SET | `value[0] = ""` // Equipment change date (machine change year/month/day — 機器変更年月日) |
| 2 | SET | `value[3] = ""` // Reservation apply date (予約適用年月日) |
| 3 | SET | `value[4] = JBSbatKKConst.RSV_APLY_CD_TTDK` // Reservation apply code [-> RSV_APLY_CD_TTDK = "1"] (Reservation processing — 予約手続き中) |

> **Note (v20.00.00 change):** Prior to v20.00.00, `value[4]` was hardcoded as `"1"`. It was refactored to use the constant `JBSbatKKConst.RSV_APLY_CD_TTDK` for maintainability.

**Block 5.5** — [SET — WHERE PARAMETER ARRAY] (L2365–L2366)

> Prepares the WHERE parameters for the update query. Uses the same key fields as the pessimistic lock.

| # | Type | Code |
|---|------|------|
| 1 | SET | `param[0] = kktkSvcKeiNoStr` // Equipment-provided service contract number |
| 2 | SET | `param[1] = geneAddDtmStr` // Generation registration timestamp |

**Block 6** — [IF/ELSE — DEBUG LOGGING] `super.logPrint.chkLogLevel(JBSbatLogUtil.MODE_DEBUG)` (L2369–L2384)

> Conditionally logs all computed values when debug-level logging is enabled. Provides full traceability for batch processing audits.

**Block 6.1** — [IF — DEBUG ENABLED] (L2369)

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `super.logPrint.printDebugLog("Service contract inquiry result - Plan start date: " + planStaymd_svcKeiUw)` // Input plan start date |
| 2 | EXEC | `super.logPrint.printDebugLog("Equipment-provided service contract - Plan start date: " + planStaymdStr)` // Stored plan start date |
| 3 | EXEC | `super.logPrint.printDebugLog("Service contract inquiry result - Plan charge start date: " + planChrgStaymd_svcKeiUw)` // Input charge date |
| 4 | EXEC | `super.logPrint.printDebugLog("Equipment-provided service contract - Plan charge start date: " + planChrgStaymdStr)` // Stored charge date |
| 5 | EXEC | `super.logPrint.printDebugLog("param(equipment-provided service contract number): " + param[0])` // Contract number |
| 6 | EXEC | `super.logPrint.printDebugLog("param(generation registration timestamp): " + param[1])` // Generation timestamp |
| 7 | EXEC | `super.logPrint.printDebugLog("value(equipment change date (empty)): " + value[0])` // Equipment change date |
| 8 | EXEC | `super.logPrint.printDebugLog("value(plan start date): " + value[1])` // Plan start date |
| 9 | EXEC | `super.logPrint.printDebugLog("value(plan charge start date): " + value[2])` // Charge plan start date |
| 10 | EXEC | `super.logPrint.printDebugLog("value(reservation apply date (empty)): " + value[3])` // Reservation apply date |
| 11 | EXEC | `super.logPrint.printDebugLog("value(reservation apply code (1: reservation processing): " + value[4])` // Reservation apply code |

**Block 7** — [CALL — DATABASE UPDATE] (L2389)

> Executes the primary-key-based update against `KK_T_KKTK_SVC_KEI`. Writes 5 fields to the database, using contract number + generation timestamp as the WHERE clause. The generation timestamp serves as an optimistic concurrency check — if the row's generation timestamp no longer matches, the update affects zero rows (though this is not explicitly handled here).

| # | Type | Code |
|---|------|------|
| 1 | CALL | `executeKK_T_KKTK_SVC_KEI_PKUPDATE(value, param)` // Update DB: set KIKI_CHG_YMD, PLAN_STAYMD, PLAN_CHRG_STAYMD, RSV_APLY_YMD, RSV_APLY_CD |

**Block 8** — [ELSE — RECORD NOT FOUND EXCEPTION] (L2382)

> If the pessimistic lock query returns null, the equipment-provided service contract record does not exist. Throws a business exception with error code `EKKB0210CE`.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `throw new JBSbatBusinessException(JPCBatchMessageConstant.EKKB0210CE, new String[]{"Equipment-provided service contract", "Contract number: " + kktkSvcKeiNoStr})` |

> **Error code `EKKB0210CE`**: Record not found — "The specified equipment-provided service contract record does not exist." The error message includes the contract number for troubleshooting.

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `KKTK_SVC_KEI_NO` | Field | Equipment-provided service contract number — unique identifier for a hardware-supplied service contract line item |
| `GENE_ADD_DTM` | Field | Generation registration timestamp — creation/modification timestamp used for optimistic concurrency control |
| `PLAN_STAYMD` | Field | Plan start date — the date (YYYYMMDD) when a service plan begins |
| `PLAN_CHRG_STAYMD` | Field | Plan charge start date — the date (YYYYMMDD) when billing for a service plan begins |
| `KIKI_CHG_YMD` | Field | Equipment change date — date when supplied hardware was changed or replaced |
| `RSV_APLY_YMD` | Field | Reservation apply date — date when a reservation (e.g., cancellation or modification) is applied |
| `RSV_APLY_CD` | Field | Reservation apply code — status code indicating the reservation processing state |
| `RSV_APLY_CD_TTDK` | Constant | Reservation apply code for "Reservation Processing" — value `"1"`, meaning 予約手続き中 (reservation procedures in progress) |
| `RSV_APLY_CD_FIX` | Constant | Reservation apply code for "Fixed/Confirmed" — value `"2"` |
| `RSV_APLY_CD_CL` | Constant | Reservation apply code for "Cancelled" — value `"3"` |
| KK_T_KKTK_SVC_KEI | DB Table | Equipment-provided service contract table — stores all equipment-supplied service contract records in the customer core system |
| 機器提供サービス契約 | Japanese term | Equipment-provided service contract — a customer agreement where K-Opticom supplies physical equipment (router, ONU, set-top box) as part of a broadband/TV service |
| サービス契約内訳 | Japanese term | Service contract detail — line-item breakdown within a service contract, specifying individual plan details |
| プラン開始年月日 | Japanese term | Plan start date — YYYYMMDD format date when the service plan takes effect |
| プラン課金開始年月日 | Japanese term | Plan charge start date — YYYYMMDD format date when the customer starts being billed for the plan |
| 予約手続き中 | Japanese term | Reservation processing — intermediate state where a reservation (modification/cancellation) has been submitted but not yet finalized |
| 世代登録年月日時刻分秒 | Japanese term | Generation registration timestamp — full timestamp (year/month/day/hour/minute/second) when the contract record was registered or last updated |
| 排他制御 | Japanese term | Exclusive control / concurrency control — mechanism (pessimistic locking) to prevent concurrent modifications |
| 排他検索 | Japanese term | Exclusive search — SELECT FOR UPDATE query with wait to acquire row-level lock |
| 該当レコードなしのエラー | Japanese term | Record-not-found error — business exception thrown when the target contract record does not exist |
| JBSbatKKConst | Class | Business constant definition class for K-Opticom equipment-related constants |
| JPCBatchMessageConstant | Class | Batch message constant definition class — contains error message codes like `EKKB0210CE` |
| EKKB0210CE | Error code | "Record not found" — thrown when a pessimistic lock query returns no rows |
| selectByPrimaryKeysForUpdateWait | Method | Pessimistic lock method — SELECT FOR UPDATE with row-level wait lock |
| executeKK_T_KKTK_SVC_KEI_PKUPDATE | Method | Primary-key update — updates specific fields of `KK_T_KKTK_SVC_KEI` by contract number + generation timestamp |

---
