repository restructure: move .git to production/, rename dirs (design→基本設計書, list→品質管理, docs→参考資料), add Subsystem A KIN01-03 files, update AGENTS.md and README.md, cleanup tmp/ tools/ bk/
This commit is contained in:
@@ -0,0 +1,787 @@
|
||||
# 勤怠休暇管理システム 設計書(サブシステムA)
|
||||
|
||||
## 概要
|
||||
|
||||
休暇申請データと打刻データを処理し、日別勤怠記録(DAILY_RECORDS)および月次統計(MONTHLY_ABSENCE)を生成する。
|
||||
|
||||
9本のCOBOLプログラムで構成される。
|
||||
|
||||
拠点間SORTやCSV変換などはCOBOLではなくJCL SORTで処理する方針とし、COBOLプログラムは純粋なビジネスロジックに専念する。
|
||||
|
||||
### 設計方針(カバレッジ拡大)
|
||||
|
||||
本設計は、サブシステムBで未カバーのプログラムタイプ・ステートメントを積極的にカバーするため、以下の方針でプログラム分割・構文選定を行う。
|
||||
|
||||
| 項目 | Bの状況 | Aで狙う追加カバレッジ |
|
||||
|------|---------|---------------------|
|
||||
| プログラムタイプ | 6パターン◎ | 未カバー5パターン + **SYSIN(P28)** を追加 |
|
||||
| ステートメント | 主要構文は網羅済 | SEARCH非ALL, DELETE, EVALUATE(4分岐), PERFORM THRU, WRITE FROM, WRITE AFTER ADVANCING, **MULTIPLY, SUBTRACT, ACCEPT, DISPLAY, INSPECT** |
|
||||
| DB操作 | INSERT/UPDATE/SELECT/COMMIT/ROLLBACK | 上記に加え **DELETE FROM** を追加 |
|
||||
|
||||
---
|
||||
|
||||
## システム定数
|
||||
|
||||
全てのプログラムで共通の前提値。COBOLのCNS-定数として保持する(DBは持たない)。
|
||||
|
||||
| 定数 | 値 | 説明 |
|
||||
|------|-----|------|
|
||||
| WORK-START | 0900 | 所定労働開始時刻 |
|
||||
| WORK-END | 1800 | 所定労働終了時刻 |
|
||||
| LUNCH-START | 1200 | ランチ開始時刻 |
|
||||
| LUNCH-END | 1300 | ランチ終了時刻 |
|
||||
| DAILY-HOURS | 8.0 | 1日の所定労働時間(9h実働 − 1hランチ) |
|
||||
|
||||
---
|
||||
|
||||
## 休暇種別
|
||||
|
||||
| コード | 名称 | 給与への影響 | 備考 |
|
||||
|--------|------|------------|------|
|
||||
| 01 | 年休(年假) | 控除なし | 有給年次休暇 |
|
||||
| 02 | 事假(事假) | 全額控除 | 私事欠勤 |
|
||||
| 03 | 因公特批假(因公特批假) | 控除なし | 公務特認欠勤 |
|
||||
| 04 | 病欠(病欠) | 一部控除 | 控除率はSICK_LEAVE_RATEテーブル参照 |
|
||||
|
||||
**休暇種別は上記4種で固定。勤怠ルールはこの4種を基準とする。**
|
||||
|
||||
---
|
||||
|
||||
## DBテーブル一覧
|
||||
|
||||
全テーブルはDB2で管理する。COBOLからは埋め込みSQL(`EXEC SQL`)で直接アクセスする。
|
||||
|
||||
### 1. EMP_MASTER(社員マスタ)
|
||||
|
||||
全社員の基本情報を保持する。サブシステムAでは参照のみ。
|
||||
|
||||
| No | カラム名 | 型 | 長さ | NULL | PK | 備考 |
|
||||
|----|---------|---|------|------|----|------|
|
||||
| 1 | EMP_ID | CHAR | 8 | NOT NULL | ✓ | 社員番号 |
|
||||
| 2 | DEPT_ID | CHAR | 4 | NOT NULL | — | 部署ID |
|
||||
| 3 | EMP_NAME | VARCHAR | 50 | NOT NULL | — | 氏名 |
|
||||
| 4 | STATUS | CHAR | 1 | NOT NULL | — | '1'=在籍, '9'=退職 |
|
||||
|
||||
### 2. ABSENCE_SUMMARY(欠勤集計中間ファイル)
|
||||
|
||||
サブシステムA→Cの連携用。KIN08DBUが月次集計後に出力する。
|
||||
|
||||
| No | カラム名 | 型 | 長さ | NULL | PK | 備考 |
|
||||
|----|---------|---|------|------|----|------|
|
||||
| 1 | EMP_ID | CHAR | 8 | NOT NULL | ✓ | 社員番号 |
|
||||
| 2 | YEAR_MONTH | CHAR | 6 | NOT NULL | ✓ | YYYYMM |
|
||||
| 3 | ANNUAL_LEAVE_H | DECIMAL | 6,1 | NOT NULL | — | 年休使用合計 |
|
||||
| 4 | PERSONAL_LEAVE_H | DECIMAL | 6,1 | NOT NULL | — | 事假合計 |
|
||||
| 5 | OFFICIAL_LEAVE_H | DECIMAL | 6,1 | NOT NULL | — | 因公特批假合計 |
|
||||
| 6 | SICK_LEAVE_H | DECIMAL | 6,1 | NOT NULL | — | 病欠合計 |
|
||||
| 7 | UNAPPROVED_ABSENT_H | DECIMAL | 6,1 | NOT NULL | — | 未申請欠勤合計 |
|
||||
|
||||
### 3. HOLIDAY_CALENDAR(休日カレンダー)
|
||||
|
||||
祝日(曜日判定で休日にならない日)のみを列挙する。
|
||||
土曜・日曜は曜日判定で休日とするため、このテーブルには含めない。
|
||||
|
||||
| No | カラム名 | 型 | 長さ | NULL | PK | 備考 |
|
||||
|----|---------|---|------|------|----|------|
|
||||
| 1 | HOLIDAY_DATE | CHAR | 8 | NOT NULL | ✓ | YYYYMMDD |
|
||||
| 2 | DESCRIPTION | VARCHAR | 50 | OK | — | 任意(例:「建国記念の日」) |
|
||||
|
||||
**出勤日判定ロジック(全PGM共通):**
|
||||
```
|
||||
1. HOLIDAY_CALENDARに日付が存在する → 休日
|
||||
2. 曜日が土曜(6)または日曜(INTEGER-OF-DATE MOD 7 = 0) → 休日
|
||||
3. 上記以外 → 出勤日(WORK-START=0900, WORK-END=1800)
|
||||
```
|
||||
|
||||
### 4. SICK_LEAVE_RATE(病欠控除率)
|
||||
|
||||
全社員共通の病欠控除率を保持する。
|
||||
|
||||
| No | カラム名 | 型 | 長さ | NULL | PK | 備考 |
|
||||
|----|---------|---|------|------|----|------|
|
||||
| 1 | LEAVE_TYPE | CHAR | 2 | NOT NULL | ✓ | '04'固定 |
|
||||
| 2 | DEDUCTION_RATE | DECIMAL | 3,2 | NOT NULL | — | 例:0.50(50%控除) |
|
||||
|
||||
### 5. LEAVE_RECORDS(休暇申請記録)
|
||||
|
||||
休暇申請の生データを保持する。取消は**DELETE FROM**で行い、レコードを物理削除する。
|
||||
期間は開始日〜終了日で表現され、日別展開は行わない。
|
||||
|
||||
| No | カラム名 | 型 | 長さ | NULL | PK | 備考 |
|
||||
|----|---------|---|------|------|----|------|
|
||||
| 1 | APPLICATION_ID | INTEGER | — | NOT NULL | ✓ | 自動採番 |
|
||||
| 2 | EMP_ID | CHAR | 8 | NOT NULL | — | 社員番号 |
|
||||
| 3 | LEAVE_TYPE | CHAR | 2 | NOT NULL | — | '01'〜'04' |
|
||||
| 4 | START_DATE | CHAR | 8 | NOT NULL | — | YYYYMMDD(出勤日) |
|
||||
| 5 | START_TIME | CHAR | 4 | NOT NULL | — | HHMM(所定労働時間内) |
|
||||
| 6 | END_DATE | CHAR | 8 | NOT NULL | — | YYYYMMDD(出勤日) |
|
||||
| 7 | END_TIME | CHAR | 4 | NOT NULL | — | HHMM(所定労働時間内) |
|
||||
| 8 | STATUS | CHAR | 1 | NOT NULL | — | '1'=有効, '9'=取消 |
|
||||
|
||||
### 6. DAILY_RECORDS(日別勤怠記録)
|
||||
|
||||
1社員1日の勤怠情報。出勤日のみレコードが存在する。
|
||||
打刻がない日でも休暇または未申請欠勤の情報を持つ。
|
||||
|
||||
| No | カラム名 | 型 | 長さ | NULL | PK | 備考 |
|
||||
|----|---------|---|------|------|----|------|
|
||||
| 1 | EMP_ID | CHAR | 8 | NOT NULL | ✓ | |
|
||||
| 2 | TARGET_DATE | CHAR | 8 | NOT NULL | ✓ | YYYYMMDD |
|
||||
| 3 | TIME_IN | CHAR | 4 | NOT NULL | — | 出勤時刻、'0000'=打刻なし |
|
||||
| 4 | TIME_OUT | CHAR | 4 | NOT NULL | — | 退勤時刻、'0000'=打刻なし |
|
||||
| 5 | ANNUAL_LEAVE_H | DECIMAL | 6,1 | NOT NULL | — | 年休使用時間 |
|
||||
| 6 | PERSONAL_LEAVE_H | DECIMAL | 6,1 | NOT NULL | — | 事假時間 |
|
||||
| 7 | OFFICIAL_LEAVE_H | DECIMAL | 6,1 | NOT NULL | — | 因公特批假時間 |
|
||||
| 8 | SICK_LEAVE_H | DECIMAL | 6,1 | NOT NULL | — | 病欠時間 |
|
||||
| 9 | UNAPPROVED_ABSENT_H | DECIMAL | 6,1 | NOT NULL | — | 未申請欠勤時間 |
|
||||
| 10 | UPDATED_AT | TIMESTAMP | — | NOT NULL | — | DEFAULT CURRENT_TIMESTAMP |
|
||||
|
||||
### 7. MONTHLY_ABSENCE(月次統計)
|
||||
|
||||
DAILY_RECORDSを月次で集計したサマリ。
|
||||
|
||||
| No | カラム名 | 型 | 長さ | NULL | PK | 備考 |
|
||||
|----|---------|---|------|------|----|------|
|
||||
| 1 | EMP_ID | CHAR | 8 | NOT NULL | ✓ | |
|
||||
| 2 | YEAR_MONTH | CHAR | 6 | NOT NULL | ✓ | YYYYMM |
|
||||
| 3 | ANNUAL_LEAVE_H | DECIMAL | 6,1 | NOT NULL | — | 年休使用合計 |
|
||||
| 4 | PERSONAL_LEAVE_H | DECIMAL | 6,1 | NOT NULL | — | 事假合計 |
|
||||
| 5 | OFFICIAL_LEAVE_H | DECIMAL | 6,1 | NOT NULL | — | 因公特批假合計 |
|
||||
| 6 | SICK_LEAVE_H | DECIMAL | 6,1 | NOT NULL | — | 病欠合計 |
|
||||
| 7 | UNAPPROVED_ABSENT_H | DECIMAL | 6,1 | NOT NULL | — | 未申請欠勤合計 |
|
||||
| 8 | UPDATED_AT | TIMESTAMP | — | NOT NULL | — | DEFAULT CURRENT_TIMESTAMP |
|
||||
|
||||
---
|
||||
|
||||
## ファイル一覧
|
||||
|
||||
| # | ファイル名 | DD名 | 編成 | RECM | サイズ | 生成元 | 消費先 | 備考 |
|
||||
|---|-----------|------|------|------|--------|--------|--------|------|
|
||||
| 1 | RAW-LEAVE | KIN01R01 | SEQUENTIAL | FB | 80 | 外部システム | KIN01INP | 休暇申請CSV |
|
||||
| 2 | WORK-LEAVE | KIN01W01 | SEQUENTIAL | FB | 80 | KIN01INP | SORT→KIN02UPD | 検証済休暇申請(中間) |
|
||||
| 3 | RAW-PUNCH | KIN04R01 | SEQUENTIAL | FB | 80 | 打刻システム | KIN04CHK | 生打刻データ |
|
||||
| 4 | EDITED-PUNCH | KIN04W01 | SEQUENTIAL | FB | 80 | KIN04CHK | KIN05MAT/B-サブシステム | 項目チェック通過打刻 |
|
||||
| 5 | LEAVE-DAILY | KIN02W01 | SEQUENTIAL | FB | 80 | KIN03EXP | KIN05MAT / KIN07DAI | 日別展開済休暇 |
|
||||
| 6 | KIN-LEAVE | KIN05W01 | SEQUENTIAL | FB | 160 | KIN05MAT | KIN07DAI | 打刻+休暇照合結果 |
|
||||
| 7 | WORK-DAY-FILE | KIN06W01 | SEQUENTIAL | FB | 80 | KIN06CLD | KIN07DAI | 出勤日カレンダー |
|
||||
| 8 | DAILY-RECORD | KIN07W01 | SEQUENTIAL | FB | 200 | KIN07DAI | KIN08DBU | 日別勤怠計算結果 |
|
||||
| 9 | ERROR-LOG | KIN01E01 | SEQUENTIAL | VB | 200 | KIN01INP / KIN04CHK | — | エラーレコード退避 |
|
||||
| 10 | ABSENCE-SUMMARY | KIN08W01 | SEQUENTIAL | FB | 80 | KIN08DBU | C-サブシステム | 月次欠勤集計(Cへ連携) |
|
||||
| 11 | CSV-OUTPUT | KIN09W01 | SEQUENTIAL | FB | 200 | KIN09CSV | — | 社員確認用CSV |
|
||||
|
||||
---
|
||||
|
||||
## 処理フロー
|
||||
|
||||
```
|
||||
休暇申請(RAW-LEAVE / CSV)
|
||||
│
|
||||
│ [KINJ010] KIN01INP — 休暇申請CSV取込・検証処理
|
||||
│ UNSTRINGでCSV分解 → IF/ELSE chain(新規/取消/変更)
|
||||
│ SEARCH(非ALL)で休暇種別テーブル検索
|
||||
│ SUB04CHKで日付/時刻/数値チェック
|
||||
├──正常 → WORK-LEAVE-file
|
||||
└──異常 → ERROR-LOG
|
||||
│
|
||||
│ [KINJ011] SORT(WORK-LEAVE → APPLICATION_ID昇順)
|
||||
│
|
||||
│ [KINJ012] KIN02UPD — 休暇申請DB更新処理
|
||||
│ 新規: EXEC SQL INSERT
|
||||
│ 取消: EXEC SQL DELETE FROM ← 新カバレッジ
|
||||
│ 変更: EXEC SQL DELETE + INSERT
|
||||
│ → DB:LEAVE_RECORDS
|
||||
│
|
||||
│ [KINJ015] KIN03EXP — 休暇日別展開処理
|
||||
│ DB(SELECT/CURSOR) → PERFORM THRU(日付範囲)
|
||||
│ キーブレイク(社員番号切替) → HEADER処理
|
||||
│ 休日除外 → CONTINUE
|
||||
│ → LEAVE-DAILY-file
|
||||
▼
|
||||
LEAVE-DAILY-file(日別休暇)
|
||||
│
|
||||
|
||||
打刻生データ(RAW-PUNCH / CSV)
|
||||
│
|
||||
│ [KINJ020] KIN04CHK — 打刻項目チェック処理
|
||||
│ UNSTRING + SUB04CHK(日付/時刻/数値)
|
||||
│ IF多重ネスト(必須→日付→時刻→数値の4段階)
|
||||
├──正常 → EDITED-PUNCH
|
||||
└──異常 → ERROR-LOG
|
||||
│
|
||||
│ [KINJ022] SORT(EDITED-PUNCH → 社員番号+日付昇順)
|
||||
│
|
||||
│ [KINJ025] KIN05MAT — 打刻休暇照合処理
|
||||
│ マッチング(1:N) EDITED-PUNCH × LEAVE-DAILY
|
||||
│ 休暇種別優先順位(01/02連動, 03/04独立)
|
||||
│ → KIN-LEAVE
|
||||
▼
|
||||
KIN-LEAVE(照合結果)
|
||||
│
|
||||
│ [KINJ030] KIN06CLD — 出勤日カレンダー生成処理
|
||||
│ DB SELECT(CURSOR) + PERFORM VARYING
|
||||
│ SEARCH ALL(休日判定) / WRITE FROM ← 新カバレッジ
|
||||
│ → WORK-DAY-FILE
|
||||
▼
|
||||
WORK-DAY-FILE(出勤日カレンダー)
|
||||
│
|
||||
│ [KINJ033] KIN07DAI — 日別勤怠計算処理
|
||||
│ マッチング(1:N) + EVALUATE分岐 ← MULTIPLY/SUBTRACT新カバレッジ
|
||||
│ WORK-DAY(主駆動) × KIN-LEAVE(N側)
|
||||
│ 4パターン(A/B/C/D)をEVALUATE + PERFORMで分岐
|
||||
│ 休暇時間計算(ランチ除外) + SUB05TIM丸め(0.1h切上)
|
||||
│ → DAILY-RECORD
|
||||
▼
|
||||
DAILY-RECORD(日別計算結果)
|
||||
│
|
||||
│ [KINJ036] KIN08DBU — 勤怠DB更新処理
|
||||
│ DAILY-RECORD → DAILY_RECORDS INSERT
|
||||
│ 社員別月次集計 → MONTHLY_ABSENCE UPSERT
|
||||
│ ABSENCE_SUMMARYファイル出力(Cへ連携)
|
||||
▼
|
||||
DB: DAILY_RECORDS + DB: MONTHLY_ABSENCE
|
||||
│ ABSENCE-SUMMARY-file
|
||||
▼
|
||||
C:給与計算システム(KYU01CAL)
|
||||
│
|
||||
│ [KINJ040] KIN09CSV — 勤怠CSV出力処理
|
||||
│ DB SELECT → STRING → WRITE AFTER ADVANCING ← 新カバレッジ
|
||||
▼
|
||||
CSV(社員確認用)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## プログラム詳細
|
||||
|
||||
### STEP010: KIN01INP — 休暇申請CSV取込・検証処理
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| **PGMパターン** | **振り分け** |
|
||||
| **JCL前処理** | なし |
|
||||
| **入力** | RAW-LEAVE(80B / CSV形式)|
|
||||
| **出力** | WORK-LEAVE(80B)/ ERROR-LOG(VB)|
|
||||
|
||||
**機能:**
|
||||
|
||||
1. READ RAW-LEAVE → CSVレコード1行を取得
|
||||
2. **UNSTRING** でCSV分解(申請番号,社員番号,日付,開始時刻,終了時刻,休暇種別,ステータス)+ **TALLYING** でフィールド数カウント(項目数チェック)
|
||||
4. **SEARCH(非ALL)** でWORKING-STORAGE上の休暇種別テーブルを線形探索 → 該当種別の存在確認 ← **新カバレッジ**
|
||||
5. **IF/ELSE chain** でステータス判定(新規/取消/変更) ← **新カバレッジ(振り分けIF文)**
|
||||
6. SUB04CHKで日付・時刻・数値の各項目検証
|
||||
- IF多重ネスト:必須チェック → 日付形式 → 時刻範囲 → 数値
|
||||
7. 通過 → WORK-LEAVEに出力(検証済みレコード)
|
||||
8. エラー → ERROR-LOGに出力
|
||||
|
||||
**新規カバレッジ構文:**
|
||||
|
||||
| 構文 | 用途 |
|
||||
|------|------|
|
||||
| UNSTRING | CSVレコードの項目分解 |
|
||||
| INSPECT TALLYING | カンマ区切り数カウント |
|
||||
| **SEARCH(非ALL)** | 休暇種別テーブル線形探索 ← 新規 |
|
||||
| IF/ELSE chain | ステータス別の振り分け処理(EVALUATE不使用) |
|
||||
|
||||
---
|
||||
|
||||
### STEP020: KIN02UPD — 休暇申請DB更新処理
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| **PGMパターン** | **DB更新** |
|
||||
| **JCL前処理** | WORK-LEAVE → APPLICATION_ID昇順SORT |
|
||||
| **入力** | WORK-LEAVE(80B)|
|
||||
| **出力** | LEAVE_RECORDS(DB2)|
|
||||
|
||||
**機能:**
|
||||
|
||||
1. READ WORK-LEAVE → 検証済みレコード1件
|
||||
2. レコード種別に応じたDB操作:
|
||||
- 新規申請(ステータス='1') → **EXEC SQL INSERT**
|
||||
- 取消申請(ステータス='9') → **EXEC SQL DELETE FROM** WHERE APPLICATION_ID = :id ← **新カバレッジ**
|
||||
- 変更申請(ステータス='1', APPLICATION_ID指定済) → **DELETE + INSERT**
|
||||
3. IF SQLCODE NOT = 0 → エラーハンドリング
|
||||
|
||||
**新規カバレッジ構文:**
|
||||
|
||||
| 構文 | 用途 |
|
||||
|------|------|
|
||||
| EXEC SQL INSERT | DB登録 |
|
||||
| **EXEC SQL DELETE FROM** | DB削除(物理削除による取消)← 新規 |
|
||||
| IF | SQLCODE判定 |
|
||||
|
||||
---
|
||||
|
||||
### STEP030: KIN03EXP — 休暇日別展開処理
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| **PGMパターン** | **キーブレイク** |
|
||||
| **JCL前処理** | なし |
|
||||
| **入力** | LEAVE_RECORDS(DB2 SELECT / CURSOR) |
|
||||
| **出力** | LEAVE-DAILY-file(80B)|
|
||||
|
||||
**機能:**
|
||||
|
||||
1. LEAVE_RECORDSからSTATUS='1'(有効)の全レコードをCURSOR SELECTする(ORDER BY EMP_ID, START_DATE)。
|
||||
2. **PERFORM THRU** で処理範囲を指定 ← **新カバレッジ**
|
||||
- 2100-PROCESS-EMP THRU 2100-PROCESS-EMP-EXIT:1社員分の処理
|
||||
- 2200-EXPAND-DATE THRU 2200-EXPAND-DATE-EXIT:日付展開処理
|
||||
3. キーブレイク(社員番号切替)時に社員別小計を出力 ← **キーブレイク(その他)**
|
||||
4. 各申請の開始日〜終了日をループ(PERFORM VARYING):
|
||||
- 休日判定:HOLIDAY_CALENDARに存在 or 土日 → **CONTINUE** でスキップ
|
||||
- 出勤日 → LEAVE-DAILY-fileに出力
|
||||
|
||||
**新規カバレッジ構文:**
|
||||
|
||||
| 構文 | 用途 |
|
||||
|------|------|
|
||||
| **PERFORM THRU** | 段落範囲指定による構造化処理 ← 新規 |
|
||||
| PERFORM UNTIL | 日付ループ(開始日〜終了日)|
|
||||
| CONTINUE | 休日スキップ時の空処理 |
|
||||
| EXEC SQL SELECT(CURSOR) | DB読込(FETCH) |
|
||||
| SET | キーブレイクフラグ操作 |
|
||||
|
||||
---
|
||||
|
||||
### STEP040: KIN04CHK — 打刻項目チェック処理
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| **PGMパターン** | 項目チェック(重複なし) |
|
||||
| **JCL前処理** | なし |
|
||||
| **入力** | RAW-PUNCH(80B / CSV形式)|
|
||||
| **出力** | EDITED-PUNCH(80B)/ ERROR-LOG(VB)|
|
||||
|
||||
**機能:**
|
||||
|
||||
1. READ RAW-PUNCH → CSVレコード
|
||||
2. **UNSTRING** で分解
|
||||
3. **IF多重ネスト** で4段階チェック:
|
||||
```
|
||||
IF 社員番号 NOT = SPACE THEN
|
||||
IF 日付が有効形式 THEN
|
||||
IF 時刻が有効範囲 THEN
|
||||
IF 出勤 < 退勤 THEN
|
||||
正常出力
|
||||
ELSE → エラー
|
||||
ELSE → エラー
|
||||
ELSE → エラー
|
||||
ELSE → エラー
|
||||
END-IF
|
||||
```
|
||||
4. 各チェックは SUB04CHK を呼出
|
||||
5. 正常 → EDITED-PUNCHに出力(**WRITE FROM** 使用)
|
||||
6. 異常 → ERROR-LOGに出力(**STRING** で編集)
|
||||
|
||||
**新規カバレッジ構文:**
|
||||
|
||||
| 構文 | 用途 |
|
||||
|------|------|
|
||||
| UNSTRING | CSV分解 |
|
||||
| **IF多重ネスト(THEN句)** | 必須→日付→時刻→数値の4段階チェック ← 新規(深度) |
|
||||
| WRITE FROM | 出力レコードの一括書出 |
|
||||
| STRING | エラーメッセージ編集 |
|
||||
|
||||
---
|
||||
|
||||
### STEP050: KIN05MAT — 打刻休暇照合処理
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| **PGMパターン** | **マッチング(1:N)** |
|
||||
| **JCL前処理** | EDITED-PUNCH → 社員番号+日付昇順SORT(KINJ022)|
|
||||
| **入力R01** | EDITED-PUNCH(80B、打刻側)|
|
||||
| **入力R02** | LEAVE-DAILY-file(80B、休暇側、N件あり得る)|
|
||||
| **出力** | KIN-LEAVE(160B)|
|
||||
|
||||
**機能:**
|
||||
|
||||
EDITED-PUNCH(打刻)とLEAVE-DAILY-file(日別休暇)を社員番号+日付で照合する。
|
||||
|
||||
1. **マッチング制御**(EVALUATE TRUE):
|
||||
- R01キー < R02キー → 打刻のみ(休暇なし)→ 休暇='99'+0hで出力
|
||||
- R01キー = R02キー → マッチ → 休暇情報マージ
|
||||
- 同一キーにN件のR02がある場合は全件読み、休暇種別優先順位で1件選定
|
||||
- R01キー > R02キー → R02次へ(R01側に該当なしの休暇 → この後のR01読込で拾う)
|
||||
|
||||
2. **休暇種別優先順位**:
|
||||
- 01(年休)と02(事假)は連動:年休残あり→01, なし→02
|
||||
- 03(因公特批假)と04(病欠)は独立
|
||||
- 複数種別混在時はAPPLICATION_ID基準で時刻範囲判定
|
||||
|
||||
3. 出力:打刻情報(80B)+休暇情報(80B)=160BのKIN-LEAVE
|
||||
|
||||
**新規カバレッジ構文:**
|
||||
|
||||
| 構文 | 用途 |
|
||||
|------|------|
|
||||
| EVALUATE TRUE | マッチング3分岐制御 |
|
||||
| STRING | 出力レコード編集 |
|
||||
| CONTINUE | 空分岐処理 |
|
||||
|
||||
---
|
||||
|
||||
### STEP060: KIN06CLD — 出勤日カレンダー生成処理
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| **PGMパターン** | **GETPUT** |
|
||||
| **JCL前処理** | なし |
|
||||
| **入力** | EMP_MASTER(DB2 SELECT / CURSOR)、HOLIDAY_CALENDAR(DB2 SELECT) |
|
||||
| **出力** | WORK-DAY-FILE(80B FB)|
|
||||
|
||||
**PARM解析:**
|
||||
- `YEARMONTH=202605` — 必須。対象年月。
|
||||
|
||||
**機能:**
|
||||
|
||||
1. PARMから対象年月を取得
|
||||
2. EMP_MASTERテーブルからSTATUS='1'(在籍)の社員一覧をSELECT(CURSOR, ORDER BY EMP_ID)
|
||||
3. HOLIDAY_CALENDARテーブルから該当月の祝日一覧をSELECT(WORKING-STORAGEのテーブルに格納)
|
||||
4. 各社員について、当月1日〜月末日まで **PERFORM VARYING** でループ:
|
||||
- **SEARCH ALL** でHOLIDAY-CALENDARテーブルを二分探索
|
||||
- 土曜(6) or 日曜(7) → 休日
|
||||
- その他 → 出勤日として **WRITE FROM** で出力 ← **新カバレッジ**
|
||||
5. 出力レコードは社員番号+日付の昇順に保証(ORDER BY + ループ順)
|
||||
|
||||
**新規カバレッジ構文:**
|
||||
|
||||
| 構文 | 用途 |
|
||||
|------|------|
|
||||
| **WRITE FROM** | MOVE + WRITEを1文で記述 ← 新規 |
|
||||
| PERFORM VARYING | 日付ループ |
|
||||
| SEARCH ALL | 休日テーブル二分探索 |
|
||||
| EXEC SQL SELECT(CURSOR) | DB読込 |
|
||||
|
||||
---
|
||||
|
||||
### STEP070: KIN07DAI — 日別勤怠計算処理
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| **PGMパターン** | **マッチング(1:N)** |
|
||||
| **JCL前処理** | なし(WORK-DAY-FILE / KIN-LEAVE / LEAVE-DAILYともソート済み前提) |
|
||||
| **入力R01** | WORK-DAY-FILE(80B、主駆動、1社員1日=1件) |
|
||||
| **入力R02** | KIN-LEAVE(160B、N側、1日0〜N件) |
|
||||
| **副参照** | LEAVE-DAILY-file(80B、ファイル併走読込) |
|
||||
| **出力** | DAILY-RECORD(200B FB)|
|
||||
|
||||
**機能:**
|
||||
|
||||
WORK-DAY-FILE(出勤日カレンダー)を主駆動とし、社員番号+日付をキーにKIN-LEAVE(打刻+休暇)とLEAVE-DAILY-file(日別休暇)を照合する。
|
||||
|
||||
**EVALUATEによる4パターン分岐:**
|
||||
|
||||
マッチング結果に応じてPATTERN-NUM(1〜4)を設定し、**EVALUATE** で処理分岐(実装時にGO TO DEPENDING ONのフォールスルー問題を確認したため、EVALUATE + PERFORMに変更):
|
||||
|
||||
```
|
||||
01 PATTERN-NUM PIC 9(1).
|
||||
88 PATTERN-A VALUE 1.
|
||||
88 PATTERN-B VALUE 2.
|
||||
88 PATTERN-C VALUE 3.
|
||||
88 PATTERN-D VALUE 4.
|
||||
|
||||
EVALUATE PATTERN-NUM
|
||||
WHEN 1 PERFORM 6100-PATTERN-A
|
||||
WHEN 2 PERFORM 6200-PATTERN-B
|
||||
WHEN 3 PERFORM 6300-PATTERN-C
|
||||
WHEN 4 PERFORM 6400-PATTERN-D
|
||||
END-EVALUATE.
|
||||
```
|
||||
|
||||
| パターン | R01(WORK-DAY) | R02(KIN-LEAVE) | LEAVE-DAILY | 処理 |
|
||||
|---------|--------------|----------------|-------------|------|
|
||||
| A=1 | あり | あり | あり | 打刻情報設定+休暇時間計算(ランチ除外、0.1h切上丸め) |
|
||||
| B=2 | あり | あり | なし | 打刻情報設定のみ、休暇=0 |
|
||||
| C=3 | あり | なし | あり | 打刻=0000、休暇時間計算(所定労働時間8h上限、ランチ除外) |
|
||||
| D=4 | あり | なし | なし | 打刻=0000、休暇=0、未申請欠勤=8.0h |
|
||||
|
||||
**休暇時間計算(ランチ考慮):**
|
||||
|
||||
```
|
||||
例:終日休暇申請 0900〜1800
|
||||
0900-1200 = 3h(午前)
|
||||
1200-1300 = ランチ(除外)
|
||||
1300-1800 = 5h(午後)
|
||||
合計休暇時間 = 8h
|
||||
|
||||
例:午後休暇申請 1300〜1800
|
||||
1300-1800 = 5h(午後、ランチ除外済み)
|
||||
合計休暇時間 = 5h
|
||||
```
|
||||
|
||||
丸め:SUB05TIM(0.1h単位切上)を呼出。
|
||||
|
||||
**バリエーション構文(MULTIPLY / SUBTRACT):**
|
||||
|
||||
COMPUTEのみに依存せず、MULTIPLYとSUBTRACTも併用して時間計算のバリエーションを確保する。
|
||||
|
||||
```
|
||||
* 例:時間(hhmm)を分(minutes)に変換 → ランチ除外
|
||||
MULTIPLY WRK-HOURS BY 60 GIVING WRK-MINUTES ← MULTIPLY
|
||||
SUBTRACT LUNCH-MINUTES FROM WRK-MINUTES ← SUBTRACT
|
||||
```
|
||||
|
||||
**新規カバレッジ構文:**
|
||||
|
||||
| 構文 | 用途 |
|
||||
|------|------|
|
||||
| **GO TO ... DEPENDING ON** | 4パターンの処理分岐 ← 新規 |
|
||||
| **PERFORM THRU** | 各パターン内の段落範囲処理 |
|
||||
| COMPUTE ROUNDED ON SIZE ERROR | 時間計算のエラー処理 |
|
||||
| **MULTIPLY** | 時間→分単位変換 ← 新規 |
|
||||
| **SUBTRACT** | ランチ時間除外 ← 新規 |
|
||||
| STRING | エラーメッセージ編集 |
|
||||
| CALL 'SUB05TIM' | 時刻丸め計算 |
|
||||
|
||||
---
|
||||
|
||||
### STEP080: KIN08DBU — 勤怠DB更新処理
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| **PGMパターン** | DB更新 + **SYSIN読込(P28)** |
|
||||
| **JCL前処理** | なし |
|
||||
| **入力** | DAILY-RECORD(200B)、**SYSIN(集計対象社員指定)** |
|
||||
| **出力** | DAILY_RECORDS / MONTHLY_ABSENCE(DB2)、ABSENCE_SUMMARY(80B)|
|
||||
|
||||
**機能:**
|
||||
|
||||
1. **SYSIN読込(パターン28)**:集計対象の社員番号一覧をSYSINから読み込む(省略時は全社員が対象)。
|
||||
2. DAILY-RECORDを1レコードずつ読込み、DAILY_RECORDSに**EXEC SQL INSERT**
|
||||
3. 社員別・月別の集計値を**PERFORM VARYING**で積算(全社員ループ)
|
||||
4. 全件処理後、MONTHLY_ABSENCEを**EXEC SQL UPDATE / INSERT**(UPSERT)
|
||||
5. **INSPECT TALLYING**で社員番号の有効性チェック → 空または無効値は**DISPLAY**で警告表示
|
||||
6. 病欠時間はSICK_LEAVE_RATEテーブルを参照し、控除前時間として保持
|
||||
7. 集計後データをABSENCE_SUMMARYファイルに出力
|
||||
|
||||
**新規カバレッジ構文:**
|
||||
|
||||
| 構文 | 用途 |
|
||||
|------|------|
|
||||
| **READ SYSIN**(パターン28) | 対象社員一覧の読込 ← 新規パターン |
|
||||
| DISPLAY | 警告メッセージ表示 ← 新規 |
|
||||
| INSPECT TALLYING | 社員番号の空チェック ← 新規 |
|
||||
| PERFORM VARYING | 社員別月次集計ループ |
|
||||
| EXEC SQL INSERT / UPDATE | DB更新(INSERT+UPDATEでUPSERT) |
|
||||
|
||||
---
|
||||
|
||||
### STEP090: KIN09CSV — 勤怠CSV出力処理
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| **PGMパターン** | GETPUT |
|
||||
| **JCL前処理** | なし |
|
||||
| **入力** | DAILY_RECORDS / MONTHLY_ABSENCE(DB2)、**COMMAND-LINE PARM** |
|
||||
| **出力** | CSVファイル(社員確認用)|
|
||||
|
||||
**PARM解析:**
|
||||
- `YEARMONTH=202605` — 必須。対象年月。
|
||||
- `MODE=FULL` — オプション。`FULL`=全項目出力, `SUMMARY`=集計のみ。
|
||||
|
||||
**機能:**
|
||||
|
||||
1. **ACCEPT FROM COMMAND-LINE** でPARM解析(対象年月・出力モード)
|
||||
2. DAILY_RECORDSから当月の全レコードをCURSOR SELECT
|
||||
3. **STRING** でCSV行を編集(DELIMITED BY SIZE)
|
||||
4. **WRITE AFTER ADVANCING PAGE** でページヘッダー制御 ← **新カバレッジ**
|
||||
- 100行ごとにヘッダー行を出力
|
||||
- WRITE header-record AFTER ADVANCING PAGE
|
||||
5. CSVフォーマット:
|
||||
|
||||
```
|
||||
社員番号,日付,出勤時刻,退勤時刻,休暇種別,年休時間,事假時間,因公特批假時間,病欠時間,未申請欠勤時間
|
||||
00000101,20260501,0900,1800,99,0.0,0.0,0.0,0.0,0.0
|
||||
00000101,20260502,0900,1300,02,0.0,4.0,0.0,0.0,4.0
|
||||
00000101,20260503,0000,0000,01,8.0,0.0,0.0,0.0,0.0
|
||||
00000101,20260504,0000,0000,99,0.0,0.0,0.0,0.0,8.0
|
||||
```
|
||||
|
||||
6. 休暇種別は該当日に休暇がある場合は最初に該当した休暇種別コード、ない場合は'99'
|
||||
|
||||
**新規カバレッジ構文:**
|
||||
|
||||
| 構文 | 用途 |
|
||||
|------|------|
|
||||
| **ACCEPT FROM COMMAND-LINE** | PARM解析(対象年月・出力モード)← 新規 |
|
||||
| **WRITE AFTER ADVANCING PAGE** | ページ制御出力 ← 新規 |
|
||||
| STRING | CSV行編集(DELIMITED BY SIZE) |
|
||||
| EXEC SQL SELECT(CURSOR) | DB読込 |
|
||||
|
||||
---
|
||||
|
||||
## 共通関数(サブプログラム)
|
||||
|
||||
サブシステムAの全プログラムで使用する共通関数。SUB06DBUは使用せず、全DB操作はEXEC SQLで直接記述する。
|
||||
|
||||
| サブプログラム | I/Fコピー句 | 用途 | 使用プログラム |
|
||||
|---|---|---|---|
|
||||
| SUB01DAT | D01010AC | 運用日付取得 | KIN01INP, KIN04CHK, KIN08DBU, KIN09CSV |
|
||||
| SUB02MSG | MSG000AC | メッセージ編集出力 | 全プログラム |
|
||||
| SUB03END | MSG000AC | ABEND終了 | KIN02UPD, KIN04CHK, KIN07DAI |
|
||||
| SUB04CHK | SUB04CHK | 項目チェック(日付/時刻/数値) | KIN01INP, KIN04CHK |
|
||||
| SUB05TIM | TIME010AC | 時刻丸め計算(分→時間) | KIN07DAI |
|
||||
|
||||
---
|
||||
|
||||
## JCL構成概要
|
||||
|
||||
9本のJOB。拠点間ソートはJCL SORTで処理し、COBOLプログラムはビジネスロジックに専念する。
|
||||
|
||||
| JOB名 | 実行PGM | 処理概要 | SORT |
|
||||
|-------|--------|---------|------|
|
||||
| KINJ010 | KIN01INP | 休暇申請CSV取込・検証 | 不要 |
|
||||
| KINJ011 | SORT | WORK-LEAVE → APPLICATION_ID昇順 | 必須 |
|
||||
| KINJ012 | KIN02UPD | 休暇申請DB更新(INSERT/DELETE) | 不要 |
|
||||
| KINJ015 | KIN03EXP | 休暇日別展開(キーブレイク) | 不要 |
|
||||
| KINJ020 | KIN04CHK | 打刻項目チェック | 不要 |
|
||||
| KINJ022 | SORT | EDITED-PUNCH → 社員番号+日付昇順 | 必須 |
|
||||
| KINJ025 | KIN05MAT | 打刻休暇照合(1:N) | 不要 |
|
||||
| KINJ030 | KIN06CLD | 出勤日カレンダー生成(GETPUT) | 不要 |
|
||||
| KINJ033 | KIN07DAI | 日別計算(EVALUATE / MULTIPLY / SUBTRACT) | 不要 |
|
||||
| KINJ036 | KIN08DBU | 勤怠DB更新(集計) | 不要 |
|
||||
| KINJ040 | KIN09CSV | 勤怠CSV出力 | 不要 |
|
||||
|
||||
---
|
||||
|
||||
## 丸めルール一覧
|
||||
|
||||
| 項目 | 最小単位 | 超過後丸め | 適用プログラム |
|
||||
|------|---------|-----------|--------------|
|
||||
| 休暇時間(全種別) | 1.0h | 0.1h単位切上 | KIN07DAI(SUB05TIM) |
|
||||
| 未申請欠勤時間 | 8.0h/日 | 切捨 | KIN07DAI |
|
||||
|
||||
サブシステムB(残業計算)の丸めルールとは独立して管理する。
|
||||
|
||||
---
|
||||
|
||||
## 期待される新規カバレッジ
|
||||
|
||||
### プログラムタイプ(未カバー → Aで追加)
|
||||
|
||||
| No | パターン | 状態 | A該当プログラム | A状態 |
|
||||
|----|----------|:----:|----------------|:-----:|
|
||||
| 2 | マッチング処理(1:N) | × | KIN05MAT | ◎ |
|
||||
| 11 | キーブレイク処理(その他) | × | KIN03EXP | ◎ |
|
||||
| 12 | レイアウト編集のみ(GETPUT) | × | KIN06CLD | ◎ |
|
||||
| 15 | 振り分け(IF文) | × | KIN01INP | ◎ |
|
||||
| 17 | 内部テーブル検索 | ○ | KIN01INP(SEARCH非ALL) | ◎ |
|
||||
| 19 | CSV→FB変換(改行なし) | ○ | KIN01INP | ◎ |
|
||||
| **28** | **SYSIN読込・チェック** | **×** | **KIN08DBU** | **新規◎** |
|
||||
|
||||
### ステートメント(未カバー → Aで追加)
|
||||
|
||||
| ステートメント | 状態 | A該当プログラム |
|
||||
|---------------|:----:|----------------|
|
||||
| SEARCH(非ALL) | × | KIN01INP |
|
||||
| DELETE FROM(DB2) | × | KIN02UPD |
|
||||
| GO TO DEPENDING ON | × | — (KIN07DAIはフォールスルー問題のためEVALUATE+PERFORMに変更) |
|
||||
| PERFORM THRU | × | KIN03EXP |
|
||||
| WRITE FROM | × | KIN04CHK, KIN06CLD |
|
||||
| WRITE AFTER ADVANCING PAGE | × | KIN09CSV |
|
||||
| **MULTIPLY** | **○(ZAN06UPDのみ)** | **KIN07DAI** |
|
||||
| **SUBTRACT** | **○(ZAN06UPDのみ)** | **KIN07DAI** |
|
||||
| **ACCEPT FROM COMMAND-LINE** | **◎(ZAN05CAL,KIN06CLD)** | **KIN09CSV** |
|
||||
| **DISPLAY** | **△(SUB02MSG,SUB03ENDのみ)** | **KIN08DBU** |
|
||||
| **INSPECT** | **◎** | **KIN08DBU** |
|
||||
|
||||
---
|
||||
|
||||
## レコード構成
|
||||
|
||||
EDITED-PUNCHはBサブシステムのZAN03CHKが入力として使用するため、互換性を維持する。
|
||||
|
||||
### EDITED-PUNCH(80B)
|
||||
|
||||
Bサブシステムとの連携インターフェース。
|
||||
|
||||
| # | 項目 | 名称 | 属性 | 開始 | 備考 |
|
||||
|---|------|------|------|------|------|
|
||||
| 1 | 社員番号 | SI-EMP-ID | 9(8) | 1 | |
|
||||
| 2 | 日付 | SI-DATE | 9(8) | 9 | YYYYMMDD |
|
||||
| 3 | 出勤時刻 | SI-TIME-IN | 9(4) | 17 | HHMM |
|
||||
| 4 | 退勤時刻 | SI-TIME-OUT | 9(4) | 21 | HHMM |
|
||||
| 5 | 部署ID | SI-DEPT-ID | 9(4) | 25 | |
|
||||
| 6 | 端末ID | SI-TERMINAL | X(6) | 29 | |
|
||||
| 7 | 予備 | FILLER | X(46) | 35 | |
|
||||
|
||||
### WORK-LEAVE(80B) — 新規(KIN01INP→KIN02UPD中間)
|
||||
|
||||
| # | 項目 | 名称 | 属性 | 開始 | 備考 |
|
||||
|---|------|------|------|------|------|
|
||||
| 1 | 申請ID | WL-APPLICATION-ID | 9(9) | 1 | 新規=0, 取消/変更=APPLICATION_ID |
|
||||
| 2 | 社員番号 | WL-EMP-ID | X(8) | 10 | |
|
||||
| 3 | 休暇種別 | WL-LEAVE-TYPE | X(2) | 18 | '01'〜'04' |
|
||||
| 4 | 開始日 | WL-START-DATE | 9(8) | 20 | YYYYMMDD |
|
||||
| 5 | 開始時刻 | WL-START-TIME | 9(4) | 28 | HHMM |
|
||||
| 6 | 終了日 | WL-END-DATE | 9(8) | 32 | YYYYMMDD |
|
||||
| 7 | 終了時刻 | WL-END-TIME | 9(4) | 40 | HHMM |
|
||||
| 8 | ステータス | WL-STATUS | X(1) | 44 | '1'=新規/変更, '9'=取消 |
|
||||
| 9 | 予備 | FILLER | X(36) | 45 | |
|
||||
|
||||
### LEAVE-DAILY(80B)
|
||||
|
||||
| # | 項目 | 名称 | 属性 | 開始 | 備考 |
|
||||
|---|------|------|------|------|------|
|
||||
| 1 | 社員番号 | SL-EMP-ID | X(8) | 1 | |
|
||||
| 2 | 日付 | SL-DATE | 9(8) | 9 | YYYYMMDD |
|
||||
| 3 | 休暇種別 | SL-LEAVE-TYPE | X(2) | 17 | '01'〜'04' |
|
||||
| 4 | 開始時刻 | SL-START-TIME | 9(4) | 19 | HHMM(元申請の開始時刻) |
|
||||
| 5 | 終了時刻 | SL-END-TIME | 9(4) | 23 | HHMM(元申請の終了時刻) |
|
||||
| 6 | 申請ID | SL-APPLICATION-ID | 9(9) | 27 | LEAVE_RECORDSのAPPLICATION_ID |
|
||||
| 7 | 予備 | FILLER | X(45) | 36 | |
|
||||
|
||||
### KIN-LEAVE(160B) — EDITED-PUNCH(80B)+休暇情報(80B)
|
||||
|
||||
| # | 項目 | 名称 | 属性 | 開始 | 備考 |
|
||||
|---|------|------|------|------|------|
|
||||
| 1-7 | 打刻情報 | — | — | 1 | EDITED-PUNCHと同一 |
|
||||
| 8 | 休暇種別 | SR-LEAVE-TYPE | X(2) | 81 | '01'〜'04' or '99' |
|
||||
| 9 | 開始時刻 | SR-LEAVE-START-TIME | 9(4) | 83 | 該当休暇の申請開始時刻 |
|
||||
| 10 | 終了時刻 | SR-LEAVE-END-TIME | 9(4) | 87 | 該当休暇の申請終了時刻 |
|
||||
| 11 | 休暇時間 | SR-LEAVE-HOURS | 9(4)V9(1) | 91 | KIN07DAIが再計算(ランチ除外・丸め適用) |
|
||||
| 12 | 申請ID | SR-APPLICATION-ID | 9(9) | 96 | LEAVE_RECORDSのAPPLICATION_ID |
|
||||
| 13 | 予備 | FILLER | X(56) | 105 | |
|
||||
|
||||
### WORK-DAY-FILE(80B)
|
||||
|
||||
| # | 項目 | 名称 | 属性 | 開始 | 備考 |
|
||||
|---|------|------|------|------|------|
|
||||
| 1 | 社員番号 | SW-EMP-ID | 9(8) | 1 | |
|
||||
| 2 | 日付 | SW-DATE | 9(8) | 9 | YYYYMMDD |
|
||||
| 3 | 曜日 | SW-DAY-OF-WEEK | 9(1) | 17 | 1=月…7=日 |
|
||||
| 4 | 予備 | FILLER | X(63) | 18 | |
|
||||
|
||||
### DAILY-RECORD(200B)
|
||||
|
||||
| # | 項目 | 名称 | 属性 | 開始 | 備考 |
|
||||
|---|------|------|------|------|------|
|
||||
| 1 | 社員番号 | SD-EMP-ID | 9(8) | 1 | |
|
||||
| 2 | 日付 | SD-DATE | 9(8) | 9 | YYYYMMDD |
|
||||
| 3 | 出勤時刻 | SD-TIME-IN | 9(4) | 17 | '0000'=打刻なし |
|
||||
| 4 | 退勤時刻 | SD-TIME-OUT | 9(4) | 21 | '0000'=打刻なし |
|
||||
| 5 | 年休時間 | SD-ANNUAL-H | 9(4)V9(1) | 25 | |
|
||||
| 6 | 事假時間 | SD-PERSONAL-H | 9(4)V9(1) | 30 | |
|
||||
| 7 | 因公特批假時間 | SD-OFFICIAL-H | 9(4)V9(1) | 35 | |
|
||||
| 8 | 病欠時間 | SD-SICK-H | 9(4)V9(1) | 40 | |
|
||||
| 9 | 未申請欠勤時間 | SD-ABSENT-H | 9(4)V9(1) | 45 | |
|
||||
| 10 | 予備 | FILLER | X(151) | 50 | |
|
||||
|
||||
### CSV-OUTPUT(200B)
|
||||
|
||||
| # | 項目 | 名称 | 属性 | 開始 | 備考 |
|
||||
|---|------|------|------|------|------|
|
||||
| 1 | CSV行データ | SC-CSV-LINE | X(200) | 1 | STRING編集済みCSV1行 |
|
||||
|
||||
### ERROR-LOG(VB 200B)
|
||||
|
||||
| # | 項目 | 名称 | 属性 | 開始 | 備考 |
|
||||
|---|------|------|------|------|------|
|
||||
| 1 | エラー区分 | ER-CATEGORY | 9(2) | 1 | 01=休暇エラー, 02=打刻エラー |
|
||||
| 2 | 発生日時 | ER-DATETIME | X(16) | 3 | |
|
||||
| 3 | プログラムID | ER-PGM-ID | X(8) | 19 | |
|
||||
| 4 | エラー内容 | ER-MESSAGE | X(100) | 27 | |
|
||||
| 5 | 原データ | ER-RAW-DATA | X(80) | 127 | エラー原因となった入力レコード |
|
||||
|
||||
@@ -0,0 +1,817 @@
|
||||
# 残業統計管理システム 設計書(サブシステムB)
|
||||
|
||||
## システム概要
|
||||
|
||||
本サブシステムは、社員からの加班申請データを元に、振り分け・重複チェック・打刻照合・取消マッチング・キーブレイク集約を行い、月次の加班統計データをDBに保存する。
|
||||
|
||||
### サブシステム情報
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| サブシステムID | ZAN(残業→ZANgyo) |
|
||||
| COBOLプログラム数 | 6 |
|
||||
| JCL数 | 6 |
|
||||
| DB | 1(OVERTIME-DB / DB2、2テーブル) |
|
||||
|
||||
### システム定数
|
||||
|
||||
| 定数 | 値 | 説明 |
|
||||
|------|-----|------|
|
||||
| WORK-START | 0900 | 所定労働開始時刻 |
|
||||
| WORK-END | 1800 | 所定労働終了時刻 |
|
||||
| DINNER-START | 1830 | 食事時間開始(1830以前は加班不可) |
|
||||
| MIN-OVT-HOURS | 0.5 | 加班最小単位 |
|
||||
|
||||
### 入力CSV形式(OVT-APPLY)
|
||||
|
||||
各レコードはCSV形式。
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| フォーマット | `申請番号,社員番号,日付(YYYYMMDD),開始時刻(HHMM),終了時刻(HHMM),ステータス` |
|
||||
| ステータス 0 | 申請(新規) |
|
||||
| ステータス 1 | 承認済(後続処理で状態更新) |
|
||||
| ステータス 9 | 取消 |
|
||||
|
||||
---
|
||||
|
||||
## ファイル一覧
|
||||
|
||||
| # | ファイル名 | 編成 | RECM | サイズ | 用途 | 区分 |
|
||||
|---|-----------|------|------|-------|------|------|
|
||||
| 1 | OVT-APPLY | SEQUENTIAL | FB | 80 | 加班申請CSV(入力) | 新規 |
|
||||
| 2 | OVT-VALID | SEQUENTIAL | FB | 80 | 振り分け通過(有効申請) | 新規 |
|
||||
| 3 | OVT-CANCEL | SEQUENTIAL | FB | 80 | 振り分け通過(取消) | 新規 |
|
||||
| 4 | OVT-NODUP | SEQUENTIAL | FB | 80 | 重複チェック通過データ | 新規 |
|
||||
| 5 | OVT-CHECKED | SEQUENTIAL | FB | 80 | 打刻照合通過(OVT-TYPE付加) | 新規 |
|
||||
| 6 | OVT-MATCHED | SEQUENTIAL | FB | 80 | マッチング通過(処理番号付加) | 新規 |
|
||||
| 7 | OVT-DBCLEAN | SEQUENTIAL | FB | 80 | 孤立取消(DB削除対象) | 新規 |
|
||||
| 8 | OVT-SUMMARY | SEQUENTIAL | FB | 80 | 集約結果 | 新規 |
|
||||
| 9 | ERROR-LOG | SEQUENTIAL | VB | 200 | エラーレコード退避 | Aと共用 |
|
||||
| 10 | EDITED-PUNCH | SEQUENTIAL | FB | 80 | 打刻データ(Aシステム出力) | Aから連携 |
|
||||
| 11 | HOLIDAY-FILE | SEQUENTIAL | FB | 80 | 休日マスタファイル(Aシステム提供) | Aから連携 |
|
||||
|
||||
### DBテーブル管理方針
|
||||
|
||||
DB2インスタンスは全サブシステムで共有するが、テーブルはサブシステム別に機能分割する。
|
||||
BサブシステムのテーブルはOVT-APPLICATIONS, OVT-MONTHLYの2つであり、これらの管理・更新はBのみが行う。
|
||||
Aサブシステムのテーブル(DAILY_RECORDS, LEAVE_RECORDS等)は参照せず、A→Bの連携はEDITED-PUNCHファイル経由に限定する。
|
||||
HOLIDAY_CALENDARテーブルについては、Aサブシステムによって提供されるHOLIDAY-FILEを使用することで参照を代替する。
|
||||
|
||||
### DB二重対応
|
||||
|
||||
本サブシステムのDB操作はDB2の埋め込みSQL(`EXEC SQL`)で直接記述する。
|
||||
ただし、休日マスタに関するDBアクセスはファイルベースで処理するため、
|
||||
ZAN06UPD以外の全プログラムはDBアクセスを伴わない。
|
||||
各プログラム内でEXEC SQL INSERT/UPDATE/SELECTを発行する。
|
||||
|
||||
### 共通関数利用方針
|
||||
|
||||
Aサブシステムの共通関数のうち、安定した汎用API(SUB01DAT, SUB02MSG, SUB03END, SUB04CHK, SUB05TIM)はBでも利用する。
|
||||
SUB06DBUはサブシステムAで使用するDB更新用サブプログラムであり、Bでは使用しない(EXEC SQLを直接記述)。
|
||||
|
||||
---
|
||||
|
||||
## DB構成
|
||||
|
||||
### DB名称:残業統計データベース(OVERTIME-DB)
|
||||
|
||||
#### テーブル1:OVT-APPLICATIONS(個別加班申請テーブル)
|
||||
|
||||
| カラム | 型 | 内容 |
|
||||
|--------|---|------|
|
||||
| APPL-ID | CHAR(8) | 申請番号(PK) |
|
||||
| EMP-ID | CHAR(8) | 社員番号 |
|
||||
| APPL-DATE | CHAR(8) | 申請日 YYYYMMDD |
|
||||
| OVT-TYPE | CHAR(1) | W=平日 / H=休日 |
|
||||
| START-TIME | CHAR(4) | 開始時刻 HHMM |
|
||||
| END-TIME | CHAR(4) | 終了時刻 HHMM |
|
||||
| OVT-HOURS | DECIMAL(4,1) | 加班時間 |
|
||||
| STATUS | CHAR(1) | 0=有効 / 9=取消 |
|
||||
| UPDATED-AT | TIMESTAMP | 更新日時 |
|
||||
|
||||
#### テーブル2:OVT-MONTHLY(月次集計テーブル)
|
||||
|
||||
| カラム | 型 | 内容 |
|
||||
|--------|---|------|
|
||||
| EMP-ID | CHAR(8) | 社員番号(PK) |
|
||||
| YEAR-MONTH | CHAR(6) | 対象年月 YYYYMM(PK) |
|
||||
| OVT-TYPE | CHAR(1) | W=平日 / H=休日(PK) |
|
||||
| OVT-HOURS | DECIMAL(6,1) | 加班時間合計 |
|
||||
| OVT-COUNT | INTEGER | 加班回数 |
|
||||
| UPDATED-AT | TIMESTAMP | 更新日時 |
|
||||
|
||||
---
|
||||
|
||||
## 処理フロー
|
||||
|
||||
```
|
||||
OVT-APPLY(CSV、任意順)
|
||||
レコード: 申請番号,社員番号,日付,開始時刻,終了時刻,ステータス(0/1/9)
|
||||
│
|
||||
╞══ ZANJ010 ═══════════════════════════════════╡
|
||||
│ ZAN01CHK(残業申請振分処理)— 振り分け
|
||||
│ UNSTRINGでCSV分解 / EVALUATEでステータス判定
|
||||
│ SUB04CHKで日付/時刻/数値チェック / 0.5h未満チェック
|
||||
├── ステータス=0,1 → OVT-VALID
|
||||
├── ステータス=9 → OVT-CANCEL
|
||||
└── 異常 → ERROR-LOG
|
||||
│
|
||||
╞══ ZANJ012 ═══════════════════════════════════╡
|
||||
│ SORT(OVT-VALID → 社員番号+日付+開始時刻昇順)
|
||||
│
|
||||
│ ZAN02CHK(時間帯重複チェック処理)— 項目チェック
|
||||
│ 同社員+同日の前レコード終了時刻 > 現レコード開始時刻
|
||||
│ → 重複(境界接続は重複としない)
|
||||
├── 通過 → OVT-NODUP
|
||||
└── 重複 → ERROR-LOG
|
||||
│
|
||||
╞══ ZANJ013 ═══════════════════════════════════╡
|
||||
│ SORT(EDITED-PUNCH → 社員番号+日付昇順)
|
||||
│
|
||||
│ ZAN03CHK(打刻時間照合処理)— マッチング(N:1)
|
||||
│ OVT-NODUP + PUNCH-SORTED を社員番号+日付で突合
|
||||
│ 申請時間帯が出勤〜退勤の範囲内か確認
|
||||
│ HOLIDAY_CALENDAR検索+曜日関数で休日判定→OVT-TYPE(W/H)設定
|
||||
├── 通過 → OVT-CHECKED
|
||||
└── 異常 → ERROR-LOG
|
||||
│
|
||||
╞══ ZANJ015 ═══════════════════════════════════╡
|
||||
│ SORT(OVT-CHECKED → 申請番号昇順)
|
||||
│ SORT(OVT-CANCEL → 申請番号昇順)
|
||||
│
|
||||
│ ZAN04MAT(取消マッチング処理)— マッチング1:1
|
||||
│ キー=申請番号で VALID vs CANCEL を突合
|
||||
├── VALID有 + CANCEL無 → OVT-MATCHED
|
||||
├── VALID有 + CANCEL有 → 消滅
|
||||
└── VALID無 + CANCEL有 → OVT-DBCLEAN
|
||||
│
|
||||
╞══ ZANJ020 ═══════════════════════════════════╡
|
||||
│ SORT(OVT-MATCHED → 申請番号+処理番号昇順)
|
||||
│
|
||||
│ ZAN05CAL(残業時間集計処理)— キーブレイク集計
|
||||
│ 同一申請番号内の最終レコードを集計
|
||||
│ DIVIDE 分→時間変換 / SUB05TIMで丸め
|
||||
│ COMPUTE ROUNDED ON SIZE ERROR
|
||||
│ → OVT-SUMMARY
|
||||
│
|
||||
╞══ ZANJ025 ═══════════════════════════════════╡
|
||||
│ ZAN06UPD(残業統計DB更新処理)— DB更新
|
||||
├── OVT-SUMMARY → OVT-APPLICATIONS INSERT/UPDATE
|
||||
│ → OVT-MONTHLY UPSERT(平日/休日別)
|
||||
└── OVT-DBCLEAN → OVT-APPLICATIONS STATUS='9' UPDATE
|
||||
→ OVT-MONTHLY 減算UPDATE
|
||||
→ 該当なし → ERROR-LOG
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## JCL
|
||||
|
||||
### ZANJ010 — 残業申請振分
|
||||
|
||||
```jcl
|
||||
//ZANJ010 JOB (ACCT),'残業申請振分',CLASS=A
|
||||
//*
|
||||
//*--- パラメータ定義 ---
|
||||
//SETPARM SET YEARMONTH=202605
|
||||
//*
|
||||
//*=====================================================================
|
||||
//* STEP010: 振り分け(SORT不要)
|
||||
//* 注:YEARMONTH PARMは他プログラムとの一貫性のため渡すが、ZAN01CHK内では未使用
|
||||
//*=====================================================================
|
||||
//STEP010 EXEC PGM=ZAN01CHK
|
||||
//ZAN01R01 DD DSN=OVT-APPLY.DAT,DISP=SHR
|
||||
//ZAN01W01 DD DSN=OVT-VALID.DAT,DISP=(NEW,PASS)
|
||||
//ZAN01W02 DD DSN=OVT-CANCEL.DAT,DISP=(NEW,PASS)
|
||||
//ZAN01W03 DD DSN=ERROR-LOG.DAT,DISP=(NEW,PASS)
|
||||
```
|
||||
|
||||
### ZANJ012 — 時間帯重複チェック
|
||||
|
||||
```jcl
|
||||
//ZANJ012 JOB (ACCT),'時間帯重複チェック',CLASS=A
|
||||
//*
|
||||
//*--- パラメータ定義 ---
|
||||
//SETPARM SET YEARMONTH=202605
|
||||
//*
|
||||
//*=====================================================================
|
||||
//* STEP012S: 有効申請 SORT
|
||||
//*=====================================================================
|
||||
//STEP012S EXEC PGM=SORT
|
||||
//SORTIN DD DSN=OVT-VALID.DAT,DISP=(OLD,DELETE)
|
||||
//SORTOUT DD DSN=OVT-VSORT.DAT,DISP=(NEW,PASS)
|
||||
//SYSIN DD *
|
||||
SORT FIELDS=(9,8,CH,A,17,8,CH,A,25,4,CH,A),EQUALS
|
||||
/*
|
||||
//*
|
||||
//*=====================================================================
|
||||
//* STEP012: 重複チェック
|
||||
//*=====================================================================
|
||||
//STEP012 EXEC PGM=ZAN02CHK,PARM='YEARMONTH=&YEARMONTH'
|
||||
//ZAN02R01 DD DSN=OVT-VSORT.DAT,DISP=(OLD,DELETE)
|
||||
//ZAN02W01 DD DSN=OVT-NODUP.DAT,DISP=(NEW,PASS)
|
||||
//ZAN02W02 DD DSN=ERROR-LOG.DAT,DISP=(NEW,PASS)
|
||||
```
|
||||
|
||||
### ZANJ013 — 打刻時間照合
|
||||
|
||||
```jcl
|
||||
//ZANJ013 JOB (ACCT),'打刻時間照合',CLASS=A
|
||||
//*
|
||||
//*--- パラメータ定義 ---
|
||||
//SETPARM SET YEARMONTH=202605
|
||||
//*
|
||||
//*=====================================================================
|
||||
//* STEP013S: 打刻データ SORT
|
||||
//*=====================================================================
|
||||
//STEP013S EXEC PGM=SORT
|
||||
//SORTIN DD DSN=EDITED-PUNCH.DAT,DISP=SHR
|
||||
//SORTOUT DD DSN=PUNCH-SORTED.DAT,DISP=(NEW,PASS)
|
||||
//SYSIN DD *
|
||||
SORT FIELDS=(1,8,CH,A,9,8,CH,A),EQUALS
|
||||
/*
|
||||
//*
|
||||
//*=====================================================================
|
||||
//* STEP013: 打刻照合 + 曜日判定
|
||||
//*=====================================================================
|
||||
//STEP013 EXEC PGM=ZAN03CHK,PARM='YEARMONTH=&YEARMONTH'
|
||||
//ZAN03R01 DD DSN=OVT-NODUP.DAT,DISP=(OLD,DELETE)
|
||||
//ZAN03R02 DD DSN=PUNCH-SORTED.DAT,DISP=(OLD,DELETE)
|
||||
//ZAN03R03 DD DSN=HOLIDAY-FILE.DAT,DISP=SHR
|
||||
//ZAN03W01 DD DSN=OVT-CHECKED.DAT,DISP=(NEW,PASS)
|
||||
//ZAN03W02 DD DSN=ERROR-LOG.DAT,DISP=(NEW,PASS)
|
||||
```
|
||||
|
||||
### ZANJ015 — 取消マッチング
|
||||
|
||||
```jcl
|
||||
//ZANJ015 JOB (ACCT),'取消マッチング',CLASS=A
|
||||
//*
|
||||
//*--- パラメータ定義 ---
|
||||
//SETPARM SET YEARMONTH=202605
|
||||
//*
|
||||
//*=====================================================================
|
||||
//* STEP015S1: チェック済データ SORT
|
||||
//*=====================================================================
|
||||
//STEP015SA EXEC PGM=SORT
|
||||
//SORTIN DD DSN=OVT-CHECKED.DAT,DISP=(OLD,DELETE)
|
||||
//SORTOUT DD DSN=OVT-SORTED.DAT,DISP=(NEW,PASS)
|
||||
//SYSIN DD *
|
||||
SORT FIELDS=(1,8,CH,A),EQUALS
|
||||
/*
|
||||
//*
|
||||
//*=====================================================================
|
||||
//* STEP015S2: 取消データ SORT
|
||||
//*=====================================================================
|
||||
//STEP015SB EXEC PGM=SORT
|
||||
//SORTIN DD DSN=OVT-CANCEL.DAT,DISP=(OLD,DELETE)
|
||||
//SORTOUT DD DSN=OVT-CSORT.DAT,DISP=(NEW,PASS)
|
||||
//SYSIN DD *
|
||||
SORT FIELDS=(1,8,CH,A),EQUALS
|
||||
/*
|
||||
//*
|
||||
//*=====================================================================
|
||||
//* STEP015: マッチング
|
||||
//*=====================================================================
|
||||
//STEP015 EXEC PGM=ZAN04MAT,PARM='YEARMONTH=&YEARMONTH'
|
||||
//ZAN04R01 DD DSN=OVT-SORTED.DAT,DISP=(OLD,DELETE)
|
||||
//ZAN04R02 DD DSN=OVT-CSORT.DAT,DISP=(OLD,DELETE)
|
||||
//ZAN04W01 DD DSN=OVT-MATCHED.DAT,DISP=(NEW,PASS)
|
||||
//ZAN04W02 DD DSN=OVT-DBCLEAN.DAT,DISP=(NEW,PASS)
|
||||
//ZAN04W03 DD DSN=ERROR-LOG.DAT,DISP=(NEW,PASS)
|
||||
```
|
||||
|
||||
### ZANJ020 — 残業時間集計
|
||||
|
||||
```jcl
|
||||
//ZANJ020 JOB (ACCT),'残業時間集計',CLASS=A
|
||||
//*
|
||||
//*--- パラメータ定義 ---
|
||||
//SETPARM SET YEARMONTH=202605
|
||||
//*
|
||||
//*=====================================================================
|
||||
//* STEP020S: マッチング済データ SORT
|
||||
//*=====================================================================
|
||||
//STEP020S EXEC PGM=SORT
|
||||
//SORTIN DD DSN=OVT-MATCHED.DAT,DISP=(OLD,DELETE)
|
||||
//SORTOUT DD DSN=OVT-SORTED2.DAT,DISP=(NEW,PASS)
|
||||
//SYSIN DD *
|
||||
SORT FIELDS=(1,8,CH,A,35,2,CH,A),EQUALS
|
||||
/*
|
||||
//*
|
||||
//*=====================================================================
|
||||
//* STEP020: キーブレイク集計
|
||||
//*=====================================================================
|
||||
//STEP020 EXEC PGM=ZAN05CAL,PARM='YEARMONTH=&YEARMONTH'
|
||||
//ZAN05R01 DD DSN=OVT-SORTED2.DAT,DISP=(OLD,DELETE)
|
||||
//ZAN05W01 DD DSN=OVT-SUMMARY.DAT,DISP=(NEW,PASS)
|
||||
```
|
||||
|
||||
### ZANJ025 — 残業統計DB更新
|
||||
|
||||
```jcl
|
||||
//ZANJ025 JOB (ACCT),'残業統計DB更新',CLASS=A
|
||||
//*
|
||||
//*--- パラメータ定義 ---
|
||||
//SETPARM SET YEARMONTH=202605
|
||||
//*
|
||||
//*=====================================================================
|
||||
//* STEP025: DB更新(SORT不要)
|
||||
//*=====================================================================
|
||||
//STEP025 EXEC PGM=ZAN06UPD,PARM='YEARMONTH=&YEARMONTH'
|
||||
//ZAN06R01 DD DSN=OVT-SUMMARY.DAT,DISP=(OLD,DELETE)
|
||||
//ZAN06R02 DD DSN=OVT-DBCLEAN.DAT,DISP=(OLD,DELETE)
|
||||
//ZAN06W01 DD DSN=ERROR-LOG.DAT,DISP=(NEW,PASS)
|
||||
```
|
||||
|
||||
### 実行順序
|
||||
|
||||
BサブシステムのJOBは、AサブシステムのKINJ020(打刻チェック)出力を入力とする。
|
||||
そのためJCL起動時は以下の順序を保証すること。
|
||||
|
||||
1. Aサブシステム KINJ020(KIN03PCK)→ EDITED-PUNCH生成
|
||||
2. Bサブシステム ZANJ010〜ZANJ025(必要時順次実行)
|
||||
|
||||
KINJ030(日別計算)は各打刻確定後であればいつでも実行可能で、ZANJ系列との依存関係はない。
|
||||
|
||||
---
|
||||
|
||||
## プログラム詳細
|
||||
|
||||
### STEP010: ZAN01CHK(残業申請振分処理) — 振り分け
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| **プログラム名称** | 残業申請振分処理 |
|
||||
| **PGMパターン** | 振り分け |
|
||||
| **SORT前処理** | 不要 |
|
||||
| **入力ファイル** | OVT-APPLY(80B / CSV形式) |
|
||||
| **出力ファイル** | OVT-VALID(80B)/ OVT-CANCEL(80B)/ ERROR-LOG(VB) |
|
||||
| **件数変化** | N件 → 有効M件 + 取消K件 + 異常L件(M+K+L=N) |
|
||||
| **使用共通関数** | SUB01DAT(運用日付), SUB02MSG(メッセージ), SUB03END(ABEND), SUB04CHK(項目チェック) |
|
||||
|
||||
**入力CSVレコード例:** `A001,EMP001,20260610,1800,2000,0`
|
||||
|
||||
**機能:**
|
||||
|
||||
1. READ OVT-APPLY
|
||||
2. **UNSTRING** でCSVレコードを各項目に分解
|
||||
3. **UNSTRING TALLYING** でカンマ区切り数をカウント(項目数妥当性確認)
|
||||
4. **EVALUATE** でステータスを判定
|
||||
- 0 or 1 → 有効申請として次へ
|
||||
- 9 → OVT-CANCEL に書出し
|
||||
- その他 → エラーとして処理
|
||||
5. SUB04CHK で日付(DATE8)・時刻(TIME4)・社員番号(NUMERIC)を検証
|
||||
6. 加班時間計算(時刻はHHMM形式のため分単位に変換してから減算)
|
||||
```
|
||||
開始分 = (開始時刻 / 100) * 60 + (開始時刻 - (開始時刻 / 100) * 100)
|
||||
終了分 = (終了時刻 / 100) * 60 + (終了時刻 - (終了時刻 / 100) * 100)
|
||||
加班時間(分) = 終了分 - 開始分
|
||||
```
|
||||
- 開始時刻 < DINNER-START(1830) → エラー(18:30以前は食事時間のため加班不可)
|
||||
- 加班時間 < 30分 → エラー(0.5h未満)
|
||||
- 開始時刻 ≧ 終了時刻 → エラー
|
||||
7. 通過 → OVT-VALID に書出し
|
||||
8. エラー → 該当レコードをERROR-LOG用01レコードにMOVEしてWRITE出力
|
||||
|
||||
**新規カバレッジ構文:**
|
||||
|
||||
| 構文 | 用途 |
|
||||
|------|------|
|
||||
| UNSTRING | CSVレコードの項目分解(TALLYING句で区切り数カウント) |
|
||||
| STRING | エラーレコード編集 |
|
||||
|
||||
---
|
||||
|
||||
### STEP012: ZAN02CHK(時間帯重複チェック処理) — 項目チェック
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| **プログラム名称** | 時間帯重複チェック処理 |
|
||||
| **PGMパターン** | 項目チェック |
|
||||
| **SORT前処理** | OVT-VALID → 社員番号+日付+開始時刻昇順 |
|
||||
| **入力ファイル** | OVT-VSORT(80B) |
|
||||
| **出力ファイル** | OVT-NODUP(80B)/ ERROR-LOG(VB) |
|
||||
| **件数変化** | M件 → 通過K件 + 重複エラー(M-K)件 |
|
||||
| **使用共通関数** | SUB01DAT(運用日付), SUB02MSG(メッセージ), SUB03END(ABEND) |
|
||||
|
||||
**機能:**
|
||||
|
||||
OVT-VSORT は既に社員番号+日付+開始時刻でソート済。順次READしながら直前レコードと比較する。
|
||||
|
||||
1. READ OVT-VSORT → 現レコード取得成功
|
||||
2. 直前レコードと同一社員番号+日付 かつ 前終了時刻 > 現開始時刻 の場合 → **時間帯重複**
|
||||
- 境界接続(前終了時刻 = 現開始時刻)は重複としない
|
||||
3. 重複 → ERROR-LOG へ
|
||||
4. 重複なし → OVT-NODUP へ書出し
|
||||
5. 社員番号 or 日付が変わったら直前レコードをリセット
|
||||
6. **SET** で重複有無フラグを設定
|
||||
|
||||
**新規カバレッジ構文:**
|
||||
|
||||
| 構文 | 用途 |
|
||||
|------|------|
|
||||
| SET | 重複有無フラグ設定 |
|
||||
| CONTINUE | リセット時の空処理 |
|
||||
|
||||
---
|
||||
|
||||
### STEP013: ZAN03CHK(打刻時間照合処理) — マッチング(N:1)
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| **プログラム名称** | 打刻時間照合処理 |
|
||||
| **PGMパターン** | マッチング(N:1) |
|
||||
| **SORT前処理** | EDITED-PUNCH → 社員番号+日付昇順 |
|
||||
| **入力ファイル** | OVT-NODUP(80B)/ PUNCH-SORTED(80B) |
|
||||
| **出力ファイル** | OVT-CHECKED(80B)/ ERROR-LOG(VB) |
|
||||
| **件数変化** | K件 → 通過P件 + エラー(K-P)件 |
|
||||
| **使用共通関数** | SUB02MSG(メッセージ) |
|
||||
|
||||
**機能:**
|
||||
|
||||
#### Step1:打刻時間内チェック
|
||||
|
||||
OVT-NODUP と PUNCH-SORTED を社員番号+日付で突合(共にソート済のため順次READで処理可)。
|
||||
|
||||
1. READ OVT-NODUP → 現レコード
|
||||
2. 該当社員番号+日付の打刻レコードを PUNCH-SORTED から READ
|
||||
3. 打刻データあり かつ 以下を両方満たすことを確認:
|
||||
- 申請開始時刻 ≧ 出勤時刻
|
||||
- 申請終了時刻 ≦ 退勤時刻
|
||||
4. 範囲外 または 打刻データなし → ERROR-LOG
|
||||
|
||||
#### Step2:曜日判定
|
||||
|
||||
**SEARCH ALL** で休日マスタファイル(WORKING-STORAGE)を検索し、申請日の種別を判定。
|
||||
Aサブシステムと同一の休日定義に従う(HOLIDAY-FILEファイル相当のデータを保持)。
|
||||
|
||||
##### 休日ファイル初期化手順
|
||||
|
||||
初期処理(1000ITTSOR)でHOLIDAY-FILEを全件READし、WORKING-STORAGEのHOLIDAY-TABLEに格納する。
|
||||
|
||||
```
|
||||
* 休日データ取得(ファイル読込み)
|
||||
OPEN INPUT HOLIDAY-FILE
|
||||
READ HOLIDAY-FILE
|
||||
... 逐次処理
|
||||
CLOSE HOLIDAY-FILE
|
||||
```
|
||||
|
||||
```
|
||||
01 HOLIDAY-TABLE.
|
||||
05 HOLIDAY-CNT PIC 9(004).
|
||||
05 HOLIDAY-DATA OCCURS 1 TO 366 TIMES
|
||||
DEPENDING ON HOLIDAY-CNT
|
||||
INDEXED BY HD-IDX.
|
||||
10 HD-DATE PIC 9(008).
|
||||
10 HD-TYPE PIC X(001).
|
||||
88 HD-HOLIDAY VALUE 'H'.
|
||||
```
|
||||
|
||||
```
|
||||
SET HD-IDX TO 1
|
||||
SEARCH ALL HOLIDAY-DATA
|
||||
AT END
|
||||
SET OVT-TYPE TO 'W'
|
||||
WHEN HD-DATE(HD-IDX) = APPL-DATE
|
||||
IF HD-HOLIDAY(HD-IDX)
|
||||
SET OVT-TYPE TO 'H'
|
||||
ELSE
|
||||
SET OVT-TYPE TO 'W'
|
||||
END-IF
|
||||
END-SEARCH
|
||||
```
|
||||
|
||||
- HOLIDAY-FILE該当 → OVT-TYPE='H'
|
||||
- 該当なし → OVT-TYPE='W'
|
||||
|
||||
**MOVE** で OVT-TYPE を設定。
|
||||
|
||||
全通過レコードは OVT-TYPE を付加して OVT-CHECKED に書出し。
|
||||
|
||||
**新規カバレッジ構文:**
|
||||
|
||||
| 構文 | 用途 |
|
||||
|------|------|
|
||||
| SEARCH ALL | 休日マスタテーブル二分探索 |
|
||||
| SET | テーブル添字操作 |
|
||||
|
||||
---
|
||||
|
||||
### STEP015: ZAN04MAT(取消マッチング処理) — マッチング1:1
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| **プログラム名称** | 取消マッチング処理 |
|
||||
| **PGMパターン** | マッチング(1:1) |
|
||||
| **SORT前処理** | OVT-CHECKED → 申請番号昇順 |
|
||||
| | OVT-CANCEL → 申請番号昇順 |
|
||||
| **入力ファイル** | OVT-SORTED(80B)/ OVT-CSORT(80B) |
|
||||
| **出力ファイル** | OVT-MATCHED(80B)/ OVT-DBCLEAN(80B)/ ERROR-LOG(VB) |
|
||||
| **件数変化** | 有効P件 + 取消R件 → 通過Q件 + 消滅S件 + DB削除T件(P=Q+S, R=S+T) |
|
||||
| **使用共通関数** | SUB01DAT(運用日付), SUB02MSG(メッセージ), SUB03END(ABEND) |
|
||||
|
||||
**機能:**
|
||||
|
||||
キー=**申請番号(APPL-ID)** で OVT-SORTED(有効申請)と OVT-CSORT(取消)をマッチング1:1。
|
||||
|
||||
マッチング制御の分岐:
|
||||
|
||||
| 条件 | 結果 | 処理 |
|
||||
|------|------|------|
|
||||
| SORTED.APPL-ID < CSORT.APPL-ID | 申請のみ(取消なし) | OVT-MATCHEDへ |
|
||||
| SORTED.APPL-ID = CSORT.APPL-ID | 両方あり(取消済) | 消滅(出力なし)。ただし監査のため取消情報をERROR-LOGに記録(エラー区分=03、取消申請番号+原本データ) |
|
||||
| SORTED.APPL-ID > CSORT.APPL-ID | 取消のみ(既DB登録済) | OVT-DBCLEANへ |
|
||||
|
||||
同一申請番号グループ内の出力順に **処理番号(OA-PROC-SEQ)** を1から付与する。
|
||||
|
||||
**STRING** で申請情報を編集して OVT-MATCHED に書出す。
|
||||
|
||||
**新規カバレッジ構文:**
|
||||
|
||||
| 構文 | 用途 |
|
||||
|------|------|
|
||||
| STRING | 申請情報編集出力 |
|
||||
|
||||
---
|
||||
|
||||
### STEP020: ZAN05CAL(残業時間集計処理) — キーブレイク集計
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| **プログラム名称** | 残業時間集計処理 |
|
||||
| **PGMパターン** | キーブレイク(集計) |
|
||||
| **SORT前処理** | OVT-MATCHED → 申請番号+処理番号昇順 |
|
||||
| **入力ファイル** | OVT-SORTED2(80B) |
|
||||
| **出力ファイル** | OVT-SUMMARY(80B) |
|
||||
| **件数変化** | Q件 → 申請番号ユニーク数(L件、L≦Q) |
|
||||
| **使用共通関数** | SUB01DAT(運用日付), SUB02MSG(メッセージ), SUB03END(ABEND), SUB05TIM(時刻丸め) |
|
||||
|
||||
**機能:**
|
||||
|
||||
#### Step1:キーブレイク制御
|
||||
|
||||
同一申請番号内に複数レコード(例:申請(0) + 承認済(1))がある場合、グループ内の**最終レコード**を集約結果として採用する。
|
||||
|
||||
```
|
||||
入力(申請番号+処理番号昇順):
|
||||
A001,EMP01,6/10,1800,2000,0 ← 申請(処理番号1)
|
||||
A001,EMP01,6/10,1800,2000,1 ← 承認済(処理番号2 → 最新)
|
||||
|
||||
集約結果: 承認済(1) を採用、申請(0) は捨てる
|
||||
```
|
||||
|
||||
- READ → 申請番号が変わるまで読み進める
|
||||
- ブレイク(申請番号切替)時に、**直前に保持していたレコード**を出力
|
||||
- グループ内の途中レコードは **CONTINUE** で読み飛ばす
|
||||
- **SET** で集約結果の有無フラグを設定
|
||||
|
||||
#### Step2:加班時間計算
|
||||
|
||||
終了時刻 - 開始時刻 を分数で計算 → **DIVIDE** で時間に変換。
|
||||
|
||||
```
|
||||
DIVIDE 分 BY 60 GIVING 時間 REMAINDER 剰余
|
||||
```
|
||||
|
||||
**SUB05TIM(mode 2:0.1h単位切捨)** を呼び出して丸め処理。加班の丸めは0.1h単位切捨が正となる。
|
||||
|
||||
**COMPUTE ROUNDED ON SIZE ERROR** で内部計算のエラー処理。
|
||||
|
||||
```
|
||||
COMPUTE WRK-OVT-HOURS ROUNDED = WRK-MINUTES / 60
|
||||
ON SIZE ERROR
|
||||
CONTINUE
|
||||
MOVE ZERO TO WRK-OVT-HOURS
|
||||
END-COMPUTE
|
||||
```
|
||||
|
||||
**新規カバレッジ構文:**
|
||||
|
||||
| 構文 | 用途 |
|
||||
|------|------|
|
||||
| COMPUTE ROUNDED ON SIZE ERROR | 丸め計算+エラー処理 |
|
||||
| DIVIDE | 分→時間変換 |
|
||||
| CONTINUE | キーブレイク制御の空分岐 |
|
||||
| SET | 集計結果フラグ設定 |
|
||||
| ACCEPT FROM DATE | 処理日付取得 |
|
||||
|
||||
---
|
||||
|
||||
### STEP025: ZAN06UPD(残業統計DB更新処理) — DB更新
|
||||
|
||||
| 項目 | 内容 |
|
||||
|------|------|
|
||||
| **プログラム名称** | 残業統計DB更新処理 |
|
||||
| **PGMパターン** | DB更新 |
|
||||
| **SORT前処理** | 不要 |
|
||||
| **入力ファイル** | OVT-SUMMARY(80B)/ OVT-DBCLEAN(80B) |
|
||||
| **出力ファイル** | OVERTIME-DB(DB2)/ ERROR-LOG(VB) |
|
||||
| **使用共通関数** | SUB01DAT(運用日付), SUB02MSG(メッセージ), SUB03END(ABEND) |
|
||||
|
||||
**機能:**
|
||||
|
||||
全DB操作は埋め込みSQL(`EXEC SQL`)で直接記述する。
|
||||
|
||||
#### 処理1:OVT-SUMMARY → DB登録
|
||||
|
||||
**EXEC SQL** でDB2にINSERT/UPDATEを発行する。
|
||||
|
||||
```
|
||||
EXEC SQL
|
||||
INSERT INTO OVT-APPLICATIONS
|
||||
(APPL-ID, EMP-ID, APPL-DATE, OVT-TYPE,
|
||||
START-TIME, END-TIME, OVT-HOURS, STATUS)
|
||||
VALUES
|
||||
(:WRK-APPL-ID, :WRK-EMP-ID, :WRK-APPL-DATE,
|
||||
:WRK-OVT-TYPE, :WRK-START-TIME, :WRK-END-TIME,
|
||||
:WRK-OVT-HOURS, :WRK-STATUS)
|
||||
END-EXEC.
|
||||
|
||||
IF SQLCODE NOT = 0
|
||||
* 同一APPL-ID存在 → UPDATEに変更
|
||||
EXEC SQL
|
||||
UPDATE OVT-APPLICATIONS SET
|
||||
STATUS = :WRK-STATUS,
|
||||
UPDATED-AT = CURRENT TIMESTAMP
|
||||
WHERE APPL-ID = :WRK-APPL-ID
|
||||
END-EXEC
|
||||
END-IF.
|
||||
```
|
||||
|
||||
OVT-MONTHLY のUPSERTも同様。
|
||||
|
||||
```
|
||||
EXEC SQL
|
||||
SELECT OVT-HOURS, OVT-COUNT
|
||||
INTO :DB-OVT-HOURS, :DB-OVT-COUNT
|
||||
FROM OVT-MONTHLY
|
||||
WHERE EMP-ID = :WRK-EMP-ID
|
||||
AND YEAR-MONTH = :WRK-YEAR-MONTH
|
||||
AND OVT-TYPE = :WRK-OVT-TYPE
|
||||
END-EXEC.
|
||||
|
||||
IF SQLCODE = 0
|
||||
* UPDATE(加算)
|
||||
EXEC SQL
|
||||
UPDATE OVT-MONTHLY SET
|
||||
OVT-HOURS = OVT-HOURS + :WRK-OVT-HOURS,
|
||||
OVT-COUNT = OVT-COUNT + 1,
|
||||
UPDATED-AT = CURRENT TIMESTAMP
|
||||
WHERE EMP-ID = :WRK-EMP-ID
|
||||
AND YEAR-MONTH = :WRK-YEAR-MONTH
|
||||
AND OVT-TYPE = :WRK-OVT-TYPE
|
||||
END-EXEC
|
||||
ELSE
|
||||
* INSERT(新規)
|
||||
EXEC SQL
|
||||
INSERT INTO OVT-MONTHLY
|
||||
(EMP-ID, YEAR-MONTH, OVT-TYPE,
|
||||
OVT-HOURS, OVT-COUNT, UPDATED-AT)
|
||||
VALUES
|
||||
(:WRK-EMP-ID, :WRK-YEAR-MONTH, :WRK-OVT-TYPE,
|
||||
:WRK-OVT-HOURS, 1, CURRENT TIMESTAMP)
|
||||
END-EXEC
|
||||
END-IF.
|
||||
```
|
||||
|
||||
#### 処理2:OVT-DBCLEAN → DB取消
|
||||
|
||||
```
|
||||
EXEC SQL
|
||||
UPDATE OVT-APPLICATIONS SET
|
||||
STATUS = '9',
|
||||
UPDATED-AT = CURRENT TIMESTAMP
|
||||
WHERE APPL-ID = :WRK-APPL-ID
|
||||
END-EXEC.
|
||||
|
||||
IF SQLCODE NOT = 0
|
||||
該当なし → ERROR-LOG に書出し
|
||||
PERFORM 9999ABDSOR
|
||||
END-IF.
|
||||
```
|
||||
|
||||
OVT-MONTHLY の減算UPDATE:
|
||||
|
||||
```
|
||||
EXEC SQL
|
||||
UPDATE OVT-MONTHLY SET
|
||||
OVT-HOURS = OVT-HOURS - :WRK-OVT-HOURS,
|
||||
OVT-COUNT = OVT-COUNT - 1,
|
||||
UPDATED-AT = CURRENT TIMESTAMP
|
||||
WHERE EMP-ID = :WRK-EMP-ID
|
||||
AND YEAR-MONTH = :WRK-YEAR-MONTH
|
||||
AND OVT-TYPE = :WRK-OVT-TYPE
|
||||
END-EXEC.
|
||||
|
||||
IF SQLCODE NOT = 0
|
||||
* OVT-MONTHLYレコード不存在 → データ不整合の可能性
|
||||
該当エラー → ERROR-LOG に書出し
|
||||
PERFORM 9999ABDSOR
|
||||
END-IF.
|
||||
```
|
||||
|
||||
**注意**: OVT-MONTHLY減算UPDATEの失敗時は、OVT-MONTHLYに対応レコードが存在しないことを意味する。
|
||||
ファイルとDBの不整合としてエラーログに記録した上でABENDさせる。
|
||||
|
||||
**SQLCODE** でDB操作の成否を確認し、異常時は ERROR-LOG に出力。
|
||||
|
||||
**新規カバレッジ構文:**
|
||||
|
||||
| 構文 | 用途 |
|
||||
|------|------|
|
||||
| EXEC SQL | DB2埋め込みSQLによるDB操作 |
|
||||
| IF | SQLCODE判定による分岐 |
|
||||
| PERFORM VARYING | 月バリデーションループ(1〜12月) |
|
||||
| PERFORM TEST AFTER | OVT-MONTHLY減算リトライ制御 |
|
||||
| MULTIPLY | 時間→分変換(MULTIPLY BY 60 GIVING) |
|
||||
| SUBTRACT | 残容量検証(SUBTRACT FROM GIVING) |
|
||||
|
||||
---
|
||||
|
||||
## レコード構成
|
||||
|
||||
### OVT-VALID / OVT-CANCEL / OVT-NODUP / OVT-CHECKED(80B)
|
||||
|
||||
| # | 項目 | 名称 | 開始 | 長さ | 属性 | 備考 |
|
||||
|---|------|------|------|------|------|------|
|
||||
| 1 | 申請番号 | OA-APPL-ID | 1 | 8 | X(8) | |
|
||||
| 2 | 社員番号 | OA-EMP-ID | 9 | 8 | 9(8) | |
|
||||
| 3 | 申請日 | OA-APPL-DATE | 17 | 8 | 9(8) | YYYYMMDD |
|
||||
| 4 | 開始時刻 | OA-START-TIME | 25 | 4 | 9(4) | HHMM |
|
||||
| 5 | 終了時刻 | OA-END-TIME | 29 | 4 | 9(4) | HHMM |
|
||||
| 6 | ステータス | OA-STATUS | 33 | 1 | X(1) | 0/1/9 |
|
||||
| 7 | OVT-TYPE | OA-OVT-TYPE | 34 | 1 | X(1) | W/H(OVT-CHECKED以降のみ有効) |
|
||||
| 8 | 予備 | OA-FILLER | 35 | 46 | X(46) | |
|
||||
|
||||
### OVT-MATCHED(80B)
|
||||
|
||||
| # | 項目 | 名称 | 開始 | 長さ | 属性 | 備考 |
|
||||
|---|------|------|------|------|------|------|
|
||||
| 1 | 申請番号 | OA-APPL-ID | 1 | 8 | X(8) | |
|
||||
| 2 | 社員番号 | OA-EMP-ID | 9 | 8 | 9(8) | |
|
||||
| 3 | 申請日 | OA-APPL-DATE | 17 | 8 | 9(8) | YYYYMMDD |
|
||||
| 4 | 開始時刻 | OA-START-TIME | 25 | 4 | 9(4) | HHMM |
|
||||
| 5 | 終了時刻 | OA-END-TIME | 29 | 4 | 9(4) | HHMM |
|
||||
| 6 | ステータス | OA-STATUS | 33 | 1 | X(1) | 0/1 |
|
||||
| 7 | OVT-TYPE | OA-OVT-TYPE | 34 | 1 | X(1) | W/H |
|
||||
| 8 | 処理番号 | OA-PROC-SEQ | 35 | 2 | 9(2) | 同申請内連番 |
|
||||
| 9 | 予備 | OA-FILLER | 37 | 44 | X(44) | |
|
||||
|
||||
社員名・部署コードは DB2(OVT-APPLICATIONSテーブル)側で保持する。
|
||||
|
||||
### OVT-SUMMARY(80B)
|
||||
|
||||
| # | 項目 | 名称 | 開始 | 長さ | 属性 | 備考 |
|
||||
|---|------|------|------|------|------|------|
|
||||
| 1 | 申請番号 | OS-APPL-ID | 1 | 8 | X(8) | |
|
||||
| 2 | 社員番号 | OS-EMP-ID | 9 | 8 | 9(8) | |
|
||||
| 3 | 申請日 | OS-APPL-DATE | 17 | 8 | 9(8) | YYYYMMDD |
|
||||
| 4 | 開始時刻 | OS-START-TIME | 25 | 4 | 9(4) | HHMM |
|
||||
| 5 | 終了時刻 | OS-END-TIME | 29 | 4 | 9(4) | HHMM |
|
||||
| 6 | 加班時間 | OS-OVT-HOURS | 33 | 5 | 9(4)V9(1) | SUB05TIM丸め後 |
|
||||
| 7 | OVT-TYPE | OS-OVT-TYPE | 38 | 1 | X(1) | W/H |
|
||||
| 8 | 予備 | OS-FILLER | 39 | 42 | X(42) | |
|
||||
|
||||
### OVT-DBCLEAN(80B)
|
||||
|
||||
| # | 項目 | 名称 | 開始 | 長さ | 属性 |
|
||||
|---|------|------|------|------|------|
|
||||
| 1 | 申請番号 | OD-APPL-ID | 1 | 8 | X(8) |
|
||||
| 2 | 予備 | OD-FILLER | 9 | 72 | X(72) |
|
||||
|
||||
---
|
||||
|
||||
## 新規COBOL構文カバレッジ一覧(14種)
|
||||
|
||||
| # | 構文 | ZAN01CHK | ZAN02CHK | ZAN03CHK | ZAN04MAT | ZAN05CAL | ZAN06UPD |
|
||||
|---|------|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|
|
||||
| 1 | UNSTRING | ● | | | | | |
|
||||
| 2 | STRING | ● | | | ● | | |
|
||||
| 3 | SEARCH ALL | | | ● | | | |
|
||||
| 4 | SET | | ● | ● | | ● | |
|
||||
| 5 | COMPUTE ROUNDED ON SIZE ERROR | | | | | ● | |
|
||||
| 6 | DIVIDE | ● | | | | ● | |
|
||||
| 7 | CONTINUE | | ● | | | ● | |
|
||||
| 8 | ACCEPT FROM DATE | | | | | ● | |
|
||||
| 9 | EXEC SQL(INSERT/UPDATE/SELECT/COMMIT/ROLLBACK) | | | | | | ● |
|
||||
|10 | IF(SQLCODE分岐) | | | | | | ● |
|
||||
|11 | PERFORM VARYING | | | | | | ● |
|
||||
|12 | PERFORM TEST AFTER | | | | | | ● |
|
||||
|13 | MULTIPLY | | | | | | ● |
|
||||
|14 | SUBTRACT | | | | | | ● |
|
||||
|
||||
---
|
||||
|
||||
## 丸めルール
|
||||
|
||||
| 条件 | ルール |
|
||||
|------|--------|
|
||||
| 加班開始時刻 < DINNER-START(1830) | エラー(申請不可、食事時間のため) |
|
||||
| 加班時間 < 30分 | エラー(申請不可) |
|
||||
| 加班時間 ≧ 30分 かつ < 0.5h換算 | 0.5hに切上 |
|
||||
| 加班時間 ≧ 0.5h | 0.1h単位切捨(SUB05TIM mode 2) |
|
||||
|
||||
例:0.5h→0.5, 0.7h→0.7, 1.55h→1.5(切捨のため1.5、切上なら1.6)
|
||||
Reference in New Issue
Block a user