diff --git a/bin/KIN01INP.exe b/bin/KIN01INP.exe new file mode 100644 index 0000000..2a96690 Binary files /dev/null and b/bin/KIN01INP.exe differ diff --git a/bin/KIN02UPD.exe b/bin/KIN02UPD.exe new file mode 100644 index 0000000..d5f9fff Binary files /dev/null and b/bin/KIN02UPD.exe differ diff --git a/bin/KIN03EXP.exe b/bin/KIN03EXP.exe new file mode 100644 index 0000000..9b1fc64 Binary files /dev/null and b/bin/KIN03EXP.exe differ diff --git a/bin/SUB04CHK.dll b/bin/SUB04CHK.dll index d72a42e..bff4aaa 100644 Binary files a/bin/SUB04CHK.dll and b/bin/SUB04CHK.dll differ diff --git a/bin/ZAN01CHK.exe b/bin/ZAN01CHK.exe index 51388bc..6bd3d5a 100644 Binary files a/bin/ZAN01CHK.exe and b/bin/ZAN01CHK.exe differ diff --git a/design/01_勤怠休暇管理システム_設計書(サブシステムA).md b/design/01_勤怠休暇管理システム_設計書(サブシステムA).md new file mode 100644 index 0000000..4b144bb --- /dev/null +++ b/design/01_勤怠休暇管理システム_設計書(サブシステムA).md @@ -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 | エラー原因となった入力レコード | + diff --git a/src/KIN01INP.cbl b/src/KIN01INP.cbl new file mode 100644 index 0000000..f59308e --- /dev/null +++ b/src/KIN01INP.cbl @@ -0,0 +1,594 @@ + IDENTIFICATION DIVISION. + PROGRAM-ID. KIN01INP. + ***************************************************************** + * システム名 : 勤怠休暇管理システム * + * プログラムID : KIN01INP * + * プログラム名 : 休暇申請CSV取込・検証処理 * + * 作成日 : 2026-06-17 * + * 処理概要 : CSV形式の休暇申請ファイルを読み込み、 * + * 休暇種別テーブル検索と項目チェックを行い、 * + * ステータスによってWORK-LEAVEまたは * + * ERROR-LOGへ振り分ける。 * + ***************************************************************** + * 更新履歴 * + *---------------------------------------------------------------* + * 更新日付 担当者 更新内容 * + *---------------------------------------------------------------* + * 26-06-17 @@@ 新規作成 * + * * + ***************************************************************** + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + SOURCE-COMPUTER. IBM-ZSERIES. + OBJECT-COMPUTER. IBM-ZSERIES. + * + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT R01INNFIL ASSIGN TO KIN01R01. + SELECT W01OUTFIL ASSIGN TO KIN01W01. + SELECT W02OUTFIL ASSIGN TO KIN01W02. + * + DATA DIVISION. + FILE SECTION. + * + ***************************************************************** + * ##R01## * + ***************************************************************** + FD R01INNFIL + LABEL RECORD IS STANDARD + BLOCK CONTAINS 0 + RECORDING MODE IS F. + 01 R01INNREC. + 03 R01LINE PIC X(80). + * + ***************************************************************** + * ##W01## * + ***************************************************************** + FD W01OUTFIL + LABEL RECORD IS STANDARD + BLOCK CONTAINS 0 + RECORDING MODE IS F. + 01 W01OUTREC. + COPY KIN01REC REPLACING ==(A)== BY ==W01==. + * + ***************************************************************** + * ##W02## * + ***************************************************************** + FD W02OUTFIL + LABEL RECORD IS STANDARD + BLOCK CONTAINS 0 + RECORDING MODE IS V. + 01 W02OUTREC. + COPY KIN05REC REPLACING ==(A)== BY ==W02==. + * + WORKING-STORAGE SECTION. + * + ***************************************************************** + * コンスタント領域 * + ***************************************************************** + 01 CNSARA. + 03 CNS-PRGIDX PIC X(008) VALUE 'KIN01INP'. + 03 CNS-MSGSTR PIC 9(003) VALUE 001. + 03 CNS-MSGFIN PIC 9(003) VALUE 002. + 03 CNS-MSGSUBEEK PIC 9(003) VALUE 005. + 03 CNS-MSGIINKES PIC 9(003) VALUE 006. + 03 CNS-MSGOUTKES PIC 9(003) VALUE 007. + 03 CNS-MSGKEYINF PIC 9(003) VALUE 033. + 03 CNS-KN0002 PIC 9(001) VALUE 2. + 03 CNS-ABD999 PIC 9(003) VALUE 999. + 03 CNS-STAT-1 PIC X(001) VALUE '1'. + 03 CNS-STAT-9 PIC X(001) VALUE '9'. + 03 CNS-LEAVE-01 PIC X(002) VALUE '01'. + 03 CNS-LEAVE-02 PIC X(002) VALUE '02'. + 03 CNS-LEAVE-03 PIC X(002) VALUE '03'. + 03 CNS-LEAVE-04 PIC X(002) VALUE '04'. + * + ***************************************************************** + * カウンタ領域 * + ***************************************************************** + 01 CUNARA. + 03 CUN-R01INN PIC S9(009) COMP-3 + VALUE ZERO. + 03 CUN-W01OUT PIC S9(009) COMP-3 + VALUE ZERO. + 03 CUN-W02OUT PIC S9(009) COMP-3 + VALUE ZERO. + * + ***************************************************************** + * 作業領域 * + ***************************************************************** + 01 WRKARA. + *** 運用日付 + 03 WRK-U06 PIC 9(008). + *** 読込フラグ + 03 WRK-R01EOF PIC X(001). + *** CSV分解用 + 03 WRK-COMMA-CNT PIC 9(002) COMP. + 03 WRK-COMMA-DISP PIC 9(002). + 03 WRK-LT-FOUND PIC X(001). + 03 WRK-ERR-TYPE PIC X(001). + 03 WRK-CSV-APPL-ID PIC X(009). + 03 WRK-CSV-EMP-ID PIC X(008). + 03 WRK-CSV-START-DATE PIC X(008). + 03 WRK-CSV-START-TIME PIC X(004). + 03 WRK-CSV-END-DATE PIC X(008). + 03 WRK-CSV-END-TIME PIC X(004). + 03 WRK-CSV-LEAVE-TYPE PIC X(002). + 03 WRK-CSV-STATUS PIC X(001). + *** ステータス再定義(数値+88条件) + 03 WRK-STATUS-NUM REDEFINES WRK-CSV-STATUS + PIC 9(001). + 88 WRK-STATUS-ACTIVE VALUE 1. + 88 WRK-STATUS-CANCEL VALUE 9. + *** 休暇種別内部テーブル(4件) + 03 WRK-LEAVE-TYPE-TABLE. + 05 WRK-LT-ENTRY OCCURS 4 TIMES + INDEXED BY WRK-LT-IDX. + 07 WRK-LT-CODE PIC X(002). + *** REDEFINESデモ(同一領域 複数型 来回代入) + 03 WRK-DEMO-AREA PIC 9(008). + 03 WRK-DEMO-ALPHA REDEFINES WRK-DEMO-AREA + PIC X(008). + 03 WRK-DEMO-GRP REDEFINES WRK-DEMO-AREA. + 05 WRK-DEMO-TYPE PIC 9(004). + 05 WRK-DEMO-VALUE PIC 9(004). + * + ***************************************************************** + * サブプログラム連絡領域 * + ***************************************************************** + *** 運用日付取得 + COPY ZANDATAC. + *** メッセージ編集出力SR用 + COPY ZANMSGAC. + *** ABEND処理SR用 + COPY ZANENDAC. + *** 項目チェックSR用 + COPY ZANCHKAC. + * + PROCEDURE DIVISION. + ***************************************************************** + * サブモジュールNO: (0.0) * + * サブモジュール名: 制御処理 * + * 処理概要 : メインコントロール処理 * + ***************************************************************** + 0000MAJCOLSOR SECTION. + * + *** 初期処理 + PERFORM 1000ITTSOR. + * + *** メイン処理 + PERFORM 2000MAJSOR + UNTIL WRK-R01EOF = '1'. + * + *** 終了処理 + PERFORM 3000STPSOR. + * + 0000MAJCOLSOR-EXT. + GOBACK. + ***************************************************************** + * サブモジュールNO: (1.0) * + * サブモジュール名: 初期処理 * + * 処理概要 : 開始メッセージ出力・各種初期化処理 * + ***************************************************************** + 1000ITTSOR SECTION. + * + *** 開始メッセージ出力 + INITIALIZE M00MHOPAR. + MOVE CNS-MSGSTR TO M00MSGCOD. + PERFORM 4000MSGOUTSOR. + * + *** コンパイル日時出力 + INITIALIZE M00MHOPAR. + MOVE CNS-MSGKEYINF TO M00MSGCOD. + MOVE FUNCTION WHEN-COMPILED TO M00UMKDATS22-01. + MOVE 'COMPILED' TO M00UMKDATS22-02. + PERFORM 4000MSGOUTSOR. + * + *** ワークエリア初期化 + INITIALIZE WRKARA. + * + *** 休暇種別テーブル設定 + MOVE '01' TO WRK-LT-CODE(1). + MOVE '02' TO WRK-LT-CODE(2). + MOVE '03' TO WRK-LT-CODE(3). + MOVE '04' TO WRK-LT-CODE(4). + * + *** 運用日付取得 + INITIALIZE D01UBSPAR. + CALL 'SUB01DAT' USING D01UBSPAR. + IF D01FKICOD = ZERO + MOVE D01UBSUDATE TO WRK-U06 + ELSE + INITIALIZE M00MHOPAR + MOVE CNS-MSGSUBEEK TO M00MSGCOD + MOVE 'SUB01DAT' TO M00UMKDATS22-01 + MOVE D01FKICOD TO M00UMKDATS22-02 + PERFORM 4000MSGOUTSOR + PERFORM 9999ABDSOR + END-IF. + * + *** 入出力ファイルOPEN + OPEN INPUT R01INNFIL + OUTPUT W01OUTFIL + W02OUTFIL. + * + *** #R01#を読み込み + PERFORM 1100R01INNSOR. + * + 1000ITTSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(1.1) * + * サブモジュール名:##R01##読込処理 * + * 処理概要 : レコード読込・EOF判定処理 * + ***************************************************************** + 1100R01INNSOR SECTION. + * + READ R01INNFIL + AT END + MOVE '1' TO WRK-R01EOF + NOT AT END + ADD 1 TO CUN-R01INN + END-READ. + * + 1100R01INNSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(2.0) * + * サブモジュール名: 主処理 * + * 処理概要 : CSV分解・休暇種別検索・ステータス振分 * + ***************************************************************** + 2000MAJSOR SECTION. + * + *** CSV分解 + PERFORM 2010CSVSOR. + * + *** 休暇種別テーブル検索 + PERFORM 2020LEAVSERSOR. + * + *** エラー判定(フィールド数/休暇種別) + IF WRK-COMMA-CNT NOT = 8 + MOVE 'F' TO WRK-ERR-TYPE + PERFORM 2050ERRORSOR + ELSE IF WRK-LT-FOUND NOT = '1' + MOVE 'L' TO WRK-ERR-TYPE + PERFORM 2050ERRORSOR + ELSE + *** ステータス判定(IF/ELSE連鎖) + IF WRK-STATUS-ACTIVE + PERFORM 2030VALIDATESOR + ELSE IF WRK-STATUS-CANCEL + PERFORM 2040CANCELSOR + ELSE + MOVE 'S' TO WRK-ERR-TYPE + PERFORM 2050ERRORSOR + END-IF + END-IF. + * + *** 次のレコード読込 + PERFORM 1100R01INNSOR. + * + 2000MAJSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(2.1) * + * サブモジュール名: CSV分解処理 * + * 処理概要 : UNSTRINGでCSVを8項目に分解する * + ***************************************************************** + 2010CSVSOR SECTION. + * + MOVE ZERO TO WRK-COMMA-CNT. + INITIALIZE WRK-CSV-APPL-ID + WRK-CSV-EMP-ID + WRK-CSV-START-DATE + WRK-CSV-START-TIME + WRK-CSV-END-DATE + WRK-CSV-END-TIME + WRK-CSV-LEAVE-TYPE + WRK-CSV-STATUS. + UNSTRING R01INNREC + DELIMITED BY ',' + INTO WRK-CSV-APPL-ID + WRK-CSV-EMP-ID + WRK-CSV-START-DATE + WRK-CSV-START-TIME + WRK-CSV-END-DATE + WRK-CSV-END-TIME + WRK-CSV-LEAVE-TYPE + WRK-CSV-STATUS + TALLYING IN WRK-COMMA-CNT + END-UNSTRING. + * + 2010CSVSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(2.2) * + * サブモジュール名: 休暇種別テーブル検索処理 * + * 処理概要 : SEARCH(非ALL)で休暇種別の妥当性を検証 * + ***************************************************************** + 2020LEAVSERSOR SECTION. + * + MOVE '0' TO WRK-LT-FOUND. + SET WRK-LT-IDX TO 1. + SEARCH WRK-LT-ENTRY + VARYING WRK-LT-IDX + AT END + CONTINUE + WHEN WRK-LT-CODE(WRK-LT-IDX) + = WRK-CSV-LEAVE-TYPE + MOVE '1' TO WRK-LT-FOUND + END-SEARCH. + * + 2020LEAVSERSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(2.3) * + * サブモジュール名: 有効申請処理 * + * 処理概要 : SUB04CHKで日付/時刻チェックしW01出力 * + ***************************************************************** + 2030VALIDATESOR SECTION. + * + *** W01レコード初期化 + INITIALIZE W01OUTREC. + * + *** SUB04CHKで社員番号チェック + INITIALIZE C01CHKPAR. + MOVE WRK-CSV-EMP-ID TO C01CHKDAT. + MOVE 'EMPID' TO C01CHKTYP. + CALL 'SUB04CHK' USING C01CHKPAR. + IF C01CHKRRC NOT = ZERO + MOVE '01' TO W02ERR-CATEGORY + STRING 'EMP-ID ERROR EMP=' + WRK-CSV-EMP-ID + DELIMITED BY SIZE + INTO W02ERR-DETAIL + WRITE W02OUTREC + ADD 1 TO CUN-W02OUT + GO TO 2030VALIDATESOR-EXT + END-IF. + * + *** SUB04CHKで開始日付チェック + INITIALIZE C01CHKPAR. + MOVE WRK-CSV-START-DATE TO C01CHKDAT. + MOVE 'DATE' TO C01CHKTYP. + CALL 'SUB04CHK' USING C01CHKPAR. + IF C01CHKRRC NOT = ZERO + MOVE '01' TO W02ERR-CATEGORY + STRING 'START-DATE ERROR EMP=' + WRK-CSV-EMP-ID + ' DATE=' + WRK-CSV-START-DATE + DELIMITED BY SIZE + INTO W02ERR-DETAIL + WRITE W02OUTREC + ADD 1 TO CUN-W02OUT + GO TO 2030VALIDATESOR-EXT + END-IF. + * + *** SUB04CHKで開始時刻チェック + INITIALIZE C01CHKPAR. + MOVE WRK-CSV-START-TIME TO C01CHKDAT. + MOVE 'TIME' TO C01CHKTYP. + CALL 'SUB04CHK' USING C01CHKPAR. + IF C01CHKRRC NOT = ZERO + MOVE '01' TO W02ERR-CATEGORY + STRING 'START-TIME ERROR EMP=' + WRK-CSV-EMP-ID + ' TIME=' + WRK-CSV-START-TIME + DELIMITED BY SIZE + INTO W02ERR-DETAIL + WRITE W02OUTREC + ADD 1 TO CUN-W02OUT + GO TO 2030VALIDATESOR-EXT + END-IF. + * + *** SUB04CHKで終了日付チェック + INITIALIZE C01CHKPAR. + MOVE WRK-CSV-END-DATE TO C01CHKDAT. + MOVE 'DATE' TO C01CHKTYP. + CALL 'SUB04CHK' USING C01CHKPAR. + IF C01CHKRRC NOT = ZERO + MOVE '01' TO W02ERR-CATEGORY + STRING 'END-DATE ERROR EMP=' + WRK-CSV-EMP-ID + ' DATE=' + WRK-CSV-END-DATE + DELIMITED BY SIZE + INTO W02ERR-DETAIL + WRITE W02OUTREC + ADD 1 TO CUN-W02OUT + GO TO 2030VALIDATESOR-EXT + END-IF. + * + *** SUB04CHKで終了時刻チェック + INITIALIZE C01CHKPAR. + MOVE WRK-CSV-END-TIME TO C01CHKDAT. + MOVE 'TIME' TO C01CHKTYP. + CALL 'SUB04CHK' USING C01CHKPAR. + IF C01CHKRRC NOT = ZERO + MOVE '01' TO W02ERR-CATEGORY + STRING 'END-TIME ERROR EMP=' + WRK-CSV-EMP-ID + ' TIME=' + WRK-CSV-END-TIME + DELIMITED BY SIZE + INTO W02ERR-DETAIL + WRITE W02OUTREC + ADD 1 TO CUN-W02OUT + GO TO 2030VALIDATESOR-EXT + END-IF. + * + *** 複合条件デモ(AND+OR+3段ネスト) + IF W01START-DATE NOT = ZERO + AND W01END-DATE NOT = ZERO + AND W01START-TIME NOT = ZERO + IF W01START-DATE > W01END-DATE + OR (W01START-DATE = W01END-DATE + AND W01START-TIME >= W01END-TIME) + MOVE 10 TO WRK-DEMO-TYPE + ELSE + MOVE 20 TO WRK-DEMO-TYPE + END-IF + END-IF. + * + *** W01出力(新規/変更: APPL-ID=CSV値, STATUS='1') + MOVE WRK-CSV-APPL-ID TO W01APPL-ID. + MOVE WRK-CSV-EMP-ID TO W01EMP-ID. + MOVE WRK-CSV-LEAVE-TYPE TO W01LEAVE-TYPE. + MOVE WRK-CSV-START-DATE TO W01START-DATE. + MOVE WRK-CSV-START-TIME TO W01START-TIME. + MOVE WRK-CSV-END-DATE TO W01END-DATE. + MOVE WRK-CSV-END-TIME TO W01END-TIME. + MOVE WRK-CSV-STATUS TO W01STATUS. + WRITE W01OUTREC. + ADD 1 TO CUN-W01OUT. + * + 2030VALIDATESOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(2.4) * + * サブモジュール名: 取消申請処理 * + * 処理概要 : 取消レコードをW01出力(検証は行わない) * + ***************************************************************** + 2040CANCELSOR SECTION. + * + *** W01レコード初期化 + INITIALIZE W01OUTREC. + * + *** W01出力(取消: APPL-ID=CSV値, STATUS='9') + MOVE WRK-CSV-APPL-ID TO W01APPL-ID. + MOVE WRK-CSV-EMP-ID TO W01EMP-ID. + MOVE WRK-CSV-LEAVE-TYPE TO W01LEAVE-TYPE. + MOVE WRK-CSV-START-DATE TO W01START-DATE. + MOVE WRK-CSV-START-TIME TO W01START-TIME. + MOVE WRK-CSV-END-DATE TO W01END-DATE. + MOVE WRK-CSV-END-TIME TO W01END-TIME. + MOVE WRK-CSV-STATUS TO W01STATUS. + WRITE W01OUTREC. + ADD 1 TO CUN-W01OUT. + * + 2040CANCELSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(2.5) * + * サブモジュール名: エラー処理 * + * 処理概要 : エラーレコードをW02出力 * + ***************************************************************** + 2050ERRORSOR SECTION. + * + *** W02レコード初期化 + INITIALIZE W02OUTREC. + MOVE '01' TO W02ERR-CATEGORY. + * + *** エラー種別判定 + EVALUATE WRK-ERR-TYPE + WHEN 'F' + MOVE 1 TO WRK-DEMO-TYPE + MOVE WRK-COMMA-CNT TO WRK-DEMO-VALUE + STRING 'FIELD COUNT ERROR CNT=' + WRK-DEMO-ALPHA + DELIMITED BY SIZE + INTO W02ERR-DETAIL + WHEN 'L' + MOVE 2 TO WRK-DEMO-TYPE + MOVE 0 TO WRK-DEMO-VALUE + STRING 'INVALID LEAVE TYPE=' + WRK-CSV-LEAVE-TYPE + ' EMP=' + WRK-CSV-EMP-ID + ' ERR=' + WRK-DEMO-ALPHA + DELIMITED BY SIZE + INTO W02ERR-DETAIL + WHEN 'S' + MOVE 3 TO WRK-DEMO-TYPE + MOVE 0 TO WRK-DEMO-VALUE + STRING 'INVALID STATUS=' + WRK-CSV-STATUS + ' EMP=' + WRK-CSV-EMP-ID + ' ERR=' + WRK-DEMO-ALPHA + DELIMITED BY SIZE + INTO W02ERR-DETAIL + WHEN OTHER + MOVE 9 TO WRK-DEMO-TYPE + MOVE 0 TO WRK-DEMO-VALUE + STRING 'UNKNOWN ERROR EMP=' + WRK-CSV-EMP-ID + ' ERR=' + WRK-DEMO-ALPHA + DELIMITED BY SIZE + INTO W02ERR-DETAIL + END-EVALUATE. + * + WRITE W02OUTREC. + ADD 1 TO CUN-W02OUT. + * + 2050ERRORSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(3.0) * + * サブモジュール名: 終了処理 * + * 処理概要 : ファイルクローズ・件数と終了メッセージ出力 * + ***************************************************************** + 3000STPSOR SECTION. + * + *** 入出力ファイルCLOSE + CLOSE R01INNFIL + W01OUTFIL + W02OUTFIL. + * + *** 入出力ファイル件数出力 + INITIALIZE M00MHOPAR. + MOVE CNS-MSGIINKES TO M00MSGCOD. + MOVE 'KIN01R01' TO M00UMKDATS22-01. + MOVE CUN-R01INN TO M00UMKDATS22-02. + PERFORM 4000MSGOUTSOR. + * + INITIALIZE M00MHOPAR. + MOVE CNS-MSGOUTKES TO M00MSGCOD. + MOVE 'KIN01W01' TO M00UMKDATS22-01. + MOVE CUN-W01OUT TO M00UMKDATS22-02. + PERFORM 4000MSGOUTSOR. + * + INITIALIZE M00MHOPAR. + MOVE CNS-MSGOUTKES TO M00MSGCOD. + MOVE 'KIN01W02' TO M00UMKDATS22-01. + MOVE CUN-W02OUT TO M00UMKDATS22-02. + PERFORM 4000MSGOUTSOR. + * + *** 終了メッセージ出力 + INITIALIZE M00MHOPAR. + MOVE CNS-MSGFIN TO M00MSGCOD. + PERFORM 4000MSGOUTSOR. + * + 3000STPSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(4.0) * + * サブモジュール名: メッセージ編集出力処理 * + * 処理概要 : メッセージ編集出力サブPGM呼出 * + ***************************************************************** + 4000MSGOUTSOR SECTION. + * + MOVE CNS-KN0002 TO M00UMKDATS22-03(1:1). + MOVE CNS-KN0002 TO M00UMKDATS22-04(1:1). + MOVE CNS-PRGIDX TO M00UMKDATS22-05. + CALL 'SUB02MSG' USING M00MHOPAR. + * + 4000MSGOUTSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(9.9) * + * サブモジュール名: ABEND処理 * + * 処理概要 : ABENDサブPGM呼出 * + ***************************************************************** + 9999ABDSOR SECTION. + * + MOVE CNS-ABD999 TO E01ABDCOD. + CALL 'SUB03END' USING E01ABDPAR. + * + 9999ABDSOR-EXT. + EXIT. diff --git a/src/KIN02UPD.cbl b/src/KIN02UPD.cbl new file mode 100644 index 0000000..7feb5ee --- /dev/null +++ b/src/KIN02UPD.cbl @@ -0,0 +1,439 @@ + IDENTIFICATION DIVISION. + PROGRAM-ID. KIN02UPD. + ***************************************************************** + * システム名 : 勤怠休暇管理システム * + * プログラムID : KIN02UPD * + * プログラム名 : 休暇申請DB更新処理 * + * 作成日 : 2026-06-17 * + * 処理概要 : WORK-LEAVEの各レコードをDB2テーブル * + * LEAVE_RECORDSに反映する。 * + * ステータスに応じて新規登録(INSERT)、 * + * 変更(DELETE+INSERT)、取消(DELETE)を行う。 * + * * + ***************************************************************** + * 更新履歴 * + *---------------------------------------------------------------* + * 更新日付 担当者 更新内容 * + *---------------------------------------------------------------* + * 26-06-17 @@@ 新規作成 * + * * + ***************************************************************** + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + SOURCE-COMPUTER. IBM-ZSERIES. + OBJECT-COMPUTER. IBM-ZSERIES. + * + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT R01INNFIL ASSIGN TO KIN01W01. + SELECT W01OUTFIL ASSIGN TO KIN02W01. + * + DATA DIVISION. + FILE SECTION. + * + ***************************************************************** + * R01 (WORK-LEAVE) 80B FB * + ***************************************************************** + FD R01INNFIL + LABEL RECORD IS STANDARD + BLOCK CONTAINS 0 + RECORDING MODE IS F. + 01 R01INNREC. + COPY KIN01REC REPLACING ==(A)== BY ==R01==. + * + * + ***************************************************************** + * W01 (ERROR-LOG) 200B VB * + ***************************************************************** + FD W01OUTFIL + LABEL RECORD IS STANDARD + BLOCK CONTAINS 0 + RECORDING MODE IS V. + 01 W01OUTREC. + COPY KIN05REC REPLACING ==(A)== BY ==W01==. + * + WORKING-STORAGE SECTION. + * + ***************************************************************** + * SQLCA * + ***************************************************************** + EXEC SQL INCLUDE SQLCA END-EXEC. + * + ***************************************************************** + * コンスタント領域 * + ***************************************************************** + 01 CNSARA. + 03 CNS-PRGIDX PIC X(008) VALUE 'KIN02UPD'. + 03 CNS-MSGSTR PIC 9(003) VALUE 001. + 03 CNS-MSGFIN PIC 9(003) VALUE 002. + 03 CNS-MSGSUBEEK PIC 9(003) VALUE 005. + 03 CNS-MSGIINKES PIC 9(003) VALUE 006. + 03 CNS-MSGOUTKES PIC 9(003) VALUE 007. + 03 CNS-MSGKEYINF PIC 9(003) VALUE 033. + 03 CNS-ABD999 PIC 9(003) VALUE 999. + 03 CNS-KN0002 PIC 9(001) VALUE 2. + * + ***************************************************************** + * カウンタ領域 * + ***************************************************************** + 01 CUNARA. + 03 CUN-R01INN PIC S9(009) COMP-3 + VALUE ZERO. + 03 CUN-DBXINS PIC S9(009) COMP-3 + VALUE ZERO. + 03 CUN-DBXDEL PIC S9(009) COMP-3 + VALUE ZERO. + 03 CUN-DBXUPD PIC S9(009) COMP-3 + VALUE ZERO. + 03 CUN-W01OUT PIC S9(009) COMP-3 + VALUE ZERO. + * + ***************************************************************** + * 作業領域 * + ***************************************************************** + 01 WRKARA. + *** EOF判定 + 03 WRK-R01EOF PIC X(001). + 88 WRK-R01-EOF VALUE '1'. + *** SQL用ホスト変数 + 03 WS-APPL-ID PIC 9(009). + 03 WS-EMP-ID PIC X(008). + 03 WS-LEAVE-TYPE PIC X(002). + 03 WS-START-DATE PIC X(008). + 03 WS-START-TIME PIC X(004). + 03 WS-END-DATE PIC X(008). + 03 WS-END-TIME PIC X(004). + 03 WS-STATUS PIC X(001). + *** SQLCODE表示用 + 03 WRK-SQLCODE-DISP PIC +9(009). + *** エラーログ編集領域 + 03 WRK-ERR-CATEGORY PIC 9(002). + 03 WRK-ERR-DETAIL PIC X(198). + * + ***************************************************************** + * サブプログラム連絡領域 * + ***************************************************************** + *** メッセージ編集出力SR用 + COPY ZANMSGAC. + *** ABEND処理SR用 + COPY ZANENDAC. + * + PROCEDURE DIVISION. + ***************************************************************** + * サブモジュールNO: (0.0) * + * サブモジュール名: 制御処理 * + * 処理概要 : メインコントロール処理 * + ***************************************************************** + 0000MAJCOLSOR SECTION. + * + *** 初期処理 + PERFORM 1000ITTSOR. + * + *** メイン処理 + PERFORM 2000MAJSOR + UNTIL WRK-R01-EOF. + * + *** 終了処理 + PERFORM 3000STPSOR. + * + 0000MAJCOLSOR-EXT. + GOBACK. + ***************************************************************** + * サブモジュールNO: (1.0) * + * サブモジュール名: 初期処理 * + * 処理概要 : 開始メッセージ出力・各種初期化処理 * + ***************************************************************** + 1000ITTSOR SECTION. + * + *** 開始メッセージ出力 + INITIALIZE M00MHOPAR. + MOVE CNS-MSGSTR TO M00MSGCOD. + PERFORM 4000MSGOUTSOR. + * + *** コンパイル日時出力 + INITIALIZE M00MHOPAR. + MOVE CNS-MSGKEYINF TO M00MSGCOD. + MOVE FUNCTION WHEN-COMPILED TO M00UMKDATS22-01. + MOVE 'COMPILED' TO M00UMKDATS22-02. + PERFORM 4000MSGOUTSOR. + * + *** ワークエリア初期化 + INITIALIZE WRKARA. + * + *** DB接続 + EXEC SQL CONNECT TO 'data/kin.db' END-EXEC. + * + *** R01ファイルOPEN + OPEN INPUT R01INNFIL. + *** W01ファイルOPEN + OPEN OUTPUT W01OUTFIL. + * + *** R01を初回読込 + PERFORM 1100R01INNSOR. + * + 1000ITTSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(1.1) * + * サブモジュール名:R01読込処理 * + * 処理概要 : WORK-LEAVE読込 * + ***************************************************************** + 1100R01INNSOR SECTION. + * + READ R01INNFIL + AT END + MOVE '1' TO WRK-R01EOF + NOT AT END + ADD 1 TO CUN-R01INN + END-READ. + * + 1100R01INNSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(2.0) * + * サブモジュール名:主処理 * + * 処理概要 : R01(WORK-LEAVE)→DB更新処理 * + ***************************************************************** + 2000MAJSOR SECTION. + * + *** レコード処理 + PERFORM 2100PROCSOR. + * + *** 次レコード読込 + PERFORM 1100R01INNSOR. + * + 2000MAJSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(2.1) * + * サブモジュール名:レコード判定処理 * + * 処理概要 : ステータス判定→各DB更新処理分岐 * + ***************************************************************** + 2100PROCSOR SECTION. + * + MOVE R01APPL-ID TO WS-APPL-ID. + MOVE R01EMP-ID TO WS-EMP-ID. + MOVE R01LEAVE-TYPE TO WS-LEAVE-TYPE. + MOVE R01START-DATE TO WS-START-DATE. + MOVE R01START-TIME TO WS-START-TIME. + MOVE R01END-DATE TO WS-END-DATE. + MOVE R01END-TIME TO WS-END-TIME. + MOVE R01STATUS TO WS-STATUS. + * + EVALUATE TRUE + WHEN WS-STATUS = '1' + AND WS-APPL-ID = 0 + PERFORM 2110INSERTSOR + WHEN WS-STATUS = '1' + AND WS-APPL-ID > 0 + PERFORM 2120UPDATESOR + WHEN WS-STATUS = '9' + PERFORM 2130DELETESOR + WHEN OTHER + CONTINUE + END-EVALUATE. + * + 2100PROCSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(2.1.1) * + * サブモジュール名:INSERT処理(新規登録) * + * 処理概要 : LEAVE_RECORDSに新規レコード追加 * + ***************************************************************** + 2110INSERTSOR SECTION. + * + EXEC SQL + INSERT INTO LEAVE_RECORDS + (EMP_ID, LEAVE_TYPE, + START_DATE, START_TIME, + END_DATE, END_TIME, + STATUS) + VALUES + (:WS-EMP-ID, :WS-LEAVE-TYPE, + :WS-START-DATE, :WS-START-TIME, + :WS-END-DATE, :WS-END-TIME, + :WS-STATUS) + END-EXEC. + * + IF SQLCODE NOT = 0 + PERFORM 9100DBERRSOR + END-IF. + * + ADD 1 TO CUN-DBXINS. + * + 2110INSERTSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(2.1.2) * + * サブモジュール名:UPDATE処理(変更) * + * 処理概要 : DELETE(旧レコード)→INSERT(新レコード) * + ***************************************************************** + 2120UPDATESOR SECTION. + * + EXEC SQL + DELETE FROM LEAVE_RECORDS + WHERE APPLICATION_ID = :WS-APPL-ID + END-EXEC. + * + IF SQLCODE NOT = 0 + PERFORM 9100DBERRSOR + END-IF. + * + EXEC SQL + INSERT INTO LEAVE_RECORDS + (EMP_ID, LEAVE_TYPE, + START_DATE, START_TIME, + END_DATE, END_TIME, + STATUS) + VALUES + (:WS-EMP-ID, :WS-LEAVE-TYPE, + :WS-START-DATE, :WS-START-TIME, + :WS-END-DATE, :WS-END-TIME, + :WS-STATUS) + END-EXEC. + * + IF SQLCODE NOT = 0 + PERFORM 9100DBERRSOR + END-IF. + * + ADD 1 TO CUN-DBXUPD. + * + 2120UPDATESOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(2.1.3) * + * サブモジュール名:DELETE処理(取消) * + * 処理概要 : APPL-ID一致レコードをDELETE * + ***************************************************************** + 2130DELETESOR SECTION. + * + EXEC SQL + DELETE FROM LEAVE_RECORDS + WHERE APPLICATION_ID = :WS-APPL-ID + END-EXEC. + * + IF SQLCODE NOT = 0 + PERFORM 9100DBERRSOR + END-IF. + * + ADD 1 TO CUN-DBXDEL. + * + 2130DELETESOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(3.0) * + * サブモジュール名:終了処理 * + * 処理概要 : COMMIT・ファイルクローズ・件数出力 * + ***************************************************************** + 3000STPSOR SECTION. + * + *** COMMIT + EXEC SQL + COMMIT WORK + END-EXEC. + * + *** 入出力ファイルCLOSE + CLOSE R01INNFIL + W01OUTFIL. + * + *** 件数メッセージ出力 + INITIALIZE M00MHOPAR. + MOVE CNS-MSGIINKES TO M00MSGCOD. + MOVE 'KIN01W01' TO M00UMKDATS22-01. + MOVE CUN-R01INN TO M00UMKDATS22-02. + PERFORM 4000MSGOUTSOR. + * + INITIALIZE M00MHOPAR. + MOVE CNS-MSGIINKES TO M00MSGCOD. + MOVE 'INS' TO M00UMKDATS22-01. + MOVE CUN-DBXINS TO M00UMKDATS22-02. + PERFORM 4000MSGOUTSOR. + * + INITIALIZE M00MHOPAR. + MOVE CNS-MSGIINKES TO M00MSGCOD. + MOVE 'UPD' TO M00UMKDATS22-01. + MOVE CUN-DBXUPD TO M00UMKDATS22-02. + PERFORM 4000MSGOUTSOR. + * + INITIALIZE M00MHOPAR. + MOVE CNS-MSGOUTKES TO M00MSGCOD. + MOVE 'DEL' TO M00UMKDATS22-01. + MOVE CUN-DBXDEL TO M00UMKDATS22-02. + PERFORM 4000MSGOUTSOR. + * + INITIALIZE M00MHOPAR. + MOVE CNS-MSGOUTKES TO M00MSGCOD. + MOVE 'KIN02W01' TO M00UMKDATS22-01. + MOVE CUN-W01OUT TO M00UMKDATS22-02. + PERFORM 4000MSGOUTSOR. + * + *** 終了メッセージ出力 + INITIALIZE M00MHOPAR. + MOVE CNS-MSGFIN TO M00MSGCOD. + PERFORM 4000MSGOUTSOR. + * + 3000STPSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(4.0) * + * サブモジュール名:メッセージ編集出力処理 * + * 処理概要 : メッセージ編集出力サブPGM呼出 * + ***************************************************************** + 4000MSGOUTSOR SECTION. + * + MOVE CNS-KN0002 TO M00UMKDATS22-03(1:1). + MOVE CNS-KN0002 TO M00UMKDATS22-04(1:1). + MOVE CNS-PRGIDX TO M00UMKDATS22-05. + CALL 'SUB02MSG' USING M00MHOPAR. + * + 4000MSGOUTSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(9.1) * + * サブモジュール名:DBエラー処理 * + * 処理概要 : SQLエラー→ROLLBACK+メッセージ出力+ABEND * + ***************************************************************** + 9100DBERRSOR SECTION. + * + *** ROLLBACK + EXEC SQL + ROLLBACK WORK + END-EXEC. + * + *** エラーログ出力 + INITIALIZE W01OUTREC. + MOVE '01' TO W01ERR-CATEGORY. + MOVE SQLCODE TO WRK-SQLCODE-DISP. + STRING 'KIN02UPD SQLCODE=' + WRK-SQLCODE-DISP DELIMITED BY SIZE + ' APPL-ID=' + WS-APPL-ID DELIMITED BY SIZE + INTO W01ERR-DETAIL + END-STRING. + WRITE W01OUTREC. + ADD 1 TO CUN-W01OUT. + * + *** エラーメッセージ出力 + INITIALIZE M00MHOPAR. + MOVE CNS-MSGSUBEEK TO M00MSGCOD. + MOVE 'KIN02UPD SQL ERROR' TO M00UMKDATS22-01. + MOVE WRK-SQLCODE-DISP TO M00UMKDATS22-02. + MOVE WS-APPL-ID TO M00UMKDATS22-03. + PERFORM 4000MSGOUTSOR. + * + PERFORM 9999ABDSOR. + * + 9100DBERRSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(9.9) * + * サブモジュール名:ABEND処理 * + * 処理概要 : ABENDサブPGM呼出 * + ***************************************************************** + 9999ABDSOR SECTION. + * + MOVE CNS-ABD999 TO E01ABDCOD. + CALL 'SUB03END' USING E01ABDPAR. + * + 9999ABDSOR-EXT. + EXIT. diff --git a/src/KIN03EXP.cbl b/src/KIN03EXP.cbl new file mode 100644 index 0000000..8c92299 --- /dev/null +++ b/src/KIN03EXP.cbl @@ -0,0 +1,511 @@ + IDENTIFICATION DIVISION. + PROGRAM-ID. KIN03EXP. + ***************************************************************** + * システム名 : 勤怠休暇管理システム * + * プログラムID : KIN03EXP * + * プログラム名 : 休暇日別展開処理 * + * 作成日 : 2026-06-17 * + * 処理概要 : LEAVE_RECORDS(DB2)より有効申請を読込み、 * + * 開始日〜終了日の期間を日別に展開し、 * + * 休日・週末を除外してLEAVE-DAILY-fileを出力 * + * する。社員番号キーブレイクで小計出力を行う。* + ***************************************************************** + * 更新履歴 * + *---------------------------------------------------------------* + * 更新日付 担当者 更新内容 * + *---------------------------------------------------------------* + * 26-06-17 @@@ 新規作成 * + * * + ***************************************************************** + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + SOURCE-COMPUTER. IBM-ZSERIES. + OBJECT-COMPUTER. IBM-ZSERIES. + * + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT W01OUTFIL ASSIGN TO "KIN02W01.DAT". + * + DATA DIVISION. + FILE SECTION. + * + ***************************************************************** + * W01 (LEAVE-DAILY) 80B FB * + ***************************************************************** + FD W01OUTFIL + LABEL RECORD IS STANDARD + BLOCK CONTAINS 0 + RECORDING MODE IS F. + 01 W01OUTREC. + COPY KIN02REC REPLACING ==(A)== BY ==W01==. + * + WORKING-STORAGE SECTION. + * + ***************************************************************** + * SQLCA * + ***************************************************************** + EXEC SQL INCLUDE SQLCA END-EXEC. + * + ***************************************************************** + * コンスタント領域 * + ***************************************************************** + 01 CNSARA. + 03 CNS-PRGIDX PIC X(008) VALUE 'KIN03EXP'. + 03 CNS-MSGSTR PIC 9(003) VALUE 001. + 03 CNS-MSGFIN PIC 9(003) VALUE 002. + 03 CNS-MSGSUBEEK PIC 9(003) VALUE 005. + 03 CNS-MSGIINKES PIC 9(003) VALUE 006. + 03 CNS-MSGOUTKES PIC 9(003) VALUE 007. + 03 CNS-MSGKEYINF PIC 9(003) VALUE 033. + 03 CNS-KN0002 PIC 9(001) VALUE 2. + 03 CNS-ABD999 PIC 9(003) VALUE 999. + * + ***************************************************************** + * カウンタ領域 * + ***************************************************************** + 01 CUNARA. + 03 CUN-R01INN PIC S9(009) COMP-3 + VALUE ZERO. + 03 CUN-W01OUT PIC S9(009) COMP-3 + VALUE ZERO. + * + ***************************************************************** + * DBホスト変数(DISPLAY形式:bridgeテキストI/F対応) * + ***************************************************************** + 01 SQL-HOST-VARS. + 03 SQL-APPL-ID PIC X(009). + 03 SQL-EMP-ID PIC X(008). + 03 SQL-LEAVE-TYPE PIC X(002). + 03 SQL-START-DATE PIC X(008). + 03 SQL-START-TIME PIC X(004). + 03 SQL-END-DATE PIC X(008). + 03 SQL-END-TIME PIC X(004). + 03 SQL-HD-DATE PIC X(008). + * + ***************************************************************** + * 作業領域 * + ***************************************************************** + 01 WRKARA. + *** EOF判定 + 03 WRK-R01EOF PIC X(001). + 88 WRK-R01-EOF VALUE '1'. + *** キーブレイク用 + 03 WRK-BFR-EMP-ID PIC X(008). + *** 社員別小計カウンタ + 03 CUN-EMP-SUB PIC S9(009) COMP-3 + VALUE ZERO. + *** 日付展開用 + 03 WRK-DATE-CURRENT PIC 9(008). + 03 WRK-DATE-ALPHA REDEFINES WRK-DATE-CURRENT + PIC X(008). + 03 WRK-DATE-NUM REDEFINES WRK-DATE-CURRENT. + 05 WRK-DATE-YEAR PIC 9(004). + 05 WRK-DATE-MONTH PIC 9(002). + 05 WRK-DATE-DAY PIC 9(002). + 03 WRK-DATE-END PIC 9(008). + *** 曜日判定用 + 03 WRK-DAY-OF-WEEK PIC 9(001). + *** 休日テーブル件数(ODO前に定義) + 03 WRK-HD-COUNT PIC 9(004) COMP + VALUE ZERO. + *** 休日テーブル存在フラグ + 03 WRK-HD-FOUND PIC X(001). + *** 休日テーブル(ODOは末尾に配置) + 03 WRK-HOLIDAY-TABLE. + 05 WRK-HD-ENTRY OCCURS 1 TO 366 TIMES + DEPENDING ON WRK-HD-COUNT + ASCENDING KEY IS WRK-HD-DATE + INDEXED BY WRK-HD-IDX. + 07 WRK-HD-DATE PIC 9(008). + * + ***************************************************************** + * サブプログラム連絡領域 * + ***************************************************************** + *** 運用日付取得 + COPY ZANDATAC. + *** メッセージ編集出力SR用 + COPY ZANMSGAC. + *** ABEND処理SR用 + COPY ZANENDAC. + * + PROCEDURE DIVISION. + ***************************************************************** + * サブモジュールNO: (0.0) * + * サブモジュール名: 制御処理 * + * 処理概要 : メインコントロール処理 * + ***************************************************************** + 0000MAJCOLSOR SECTION. + * + *** 初期処理 + PERFORM 1000ITTSOR. + * + *** メイン処理 + PERFORM 2000MAJSOR + UNTIL WRK-R01EOF = '1'. + * + *** 終了処理 + PERFORM 3000STPSOR. + * + 0000MAJCOLSOR-EXT. + GOBACK. + ***************************************************************** + * サブモジュールNO: (1.0) * + * サブモジュール名: 初期処理 * + * 処理概要 : 開始メッセージ出力・各種初期化処理 * + ***************************************************************** + 1000ITTSOR SECTION. + * + *** 開始メッセージ出力 + INITIALIZE M00MHOPAR. + MOVE CNS-MSGSTR TO M00MSGCOD. + PERFORM 4000MSGOUTSOR. + * + *** コンパイル日時出力 + INITIALIZE M00MHOPAR. + MOVE CNS-MSGKEYINF TO M00MSGCOD. + MOVE FUNCTION WHEN-COMPILED TO M00UMKDATS22-01. + MOVE 'COMPILED' TO M00UMKDATS22-02. + PERFORM 4000MSGOUTSOR. + * + *** ワークエリア初期化 + INITIALIZE WRKARA. + * + *** DB接続 + EXEC SQL CONNECT TO 'data/kin.db' END-EXEC. + * + *** 運用日付取得 + INITIALIZE D01UBSPAR. + CALL 'SUB01DAT' USING D01UBSPAR. + IF D01FKICOD = ZERO + MOVE D01UBSUDATE TO WRK-DATE-CURRENT + ELSE + INITIALIZE M00MHOPAR + MOVE CNS-MSGSUBEEK TO M00MSGCOD + MOVE 'SUB01DAT' TO M00UMKDATS22-01 + MOVE D01FKICOD TO M00UMKDATS22-02 + PERFORM 4000MSGOUTSOR + PERFORM 9999ABDSOR + END-IF. + * + *** 休日カレンダーテーブル読込 + PERFORM 1200HDINNSOR. + * + *** 出力ファイルOPEN + OPEN OUTPUT W01OUTFIL. + * + *** C1カーソル初回FETCH(SELECT INTO) + PERFORM 1100C1INITSOR. + * + 1000ITTSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(1.1) * + * サブモジュール名:C1初回FETCH処理 * + * 処理概要 : LEAVE_RECORDSをSELECT INTO(初回のみ) * + ***************************************************************** + 1100C1INITSOR SECTION. + * + MOVE SPACES TO SQL-APPL-ID. + EXEC SQL + SELECT APPLICATION_ID, EMP_ID, LEAVE_TYPE, + START_DATE, START_TIME, + END_DATE, END_TIME + FROM LEAVE_RECORDS + WHERE STATUS = '1' + ORDER BY EMP_ID, START_DATE + INTO :SQL-APPL-ID, :SQL-EMP-ID, :SQL-LEAVE-TYPE, + :SQL-START-DATE, :SQL-START-TIME, + :SQL-END-DATE, :SQL-END-TIME + END-EXEC. + * + IF SQLCODE = 0 + ADD 1 TO CUN-R01INN + ELSE + MOVE '1' TO WRK-R01EOF + END-IF. + * + 1100C1INITSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(1.2) * + * サブモジュール名:C1次回FETCH処理 * + * 処理概要 : br_fetch_nextで次行を読込(2回目以降) * + ***************************************************************** + 1100C1FETCHSOR SECTION. + * + CALL 'br_fetch_next' USING SQLCODE. + * + IF SQLCODE = 0 + MOVE SPACES TO SQL-APPL-ID + MOVE 0 TO WS-COL-IDX + MOVE 256 TO WS-COL-LEN + CALL 'br_get_col' USING + WS-COL-IDX, SQL-APPL-ID, WS-COL-LEN + MOVE 1 TO WS-COL-IDX + MOVE 256 TO WS-COL-LEN + CALL 'br_get_col' USING + WS-COL-IDX, SQL-EMP-ID, WS-COL-LEN + MOVE 2 TO WS-COL-IDX + MOVE 256 TO WS-COL-LEN + CALL 'br_get_col' USING + WS-COL-IDX, SQL-LEAVE-TYPE, WS-COL-LEN + MOVE 3 TO WS-COL-IDX + MOVE 256 TO WS-COL-LEN + CALL 'br_get_col' USING + WS-COL-IDX, SQL-START-DATE, WS-COL-LEN + MOVE 4 TO WS-COL-IDX + MOVE 256 TO WS-COL-LEN + CALL 'br_get_col' USING + WS-COL-IDX, SQL-START-TIME, WS-COL-LEN + MOVE 5 TO WS-COL-IDX + MOVE 256 TO WS-COL-LEN + CALL 'br_get_col' USING + WS-COL-IDX, SQL-END-DATE, WS-COL-LEN + MOVE 6 TO WS-COL-IDX + MOVE 256 TO WS-COL-LEN + CALL 'br_get_col' USING + WS-COL-IDX, SQL-END-TIME, WS-COL-LEN + ADD 1 TO CUN-R01INN + ELSE + MOVE '1' TO WRK-R01EOF + END-IF. + * + 1100C1FETCHSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(1.3) * + * サブモジュール名: 休日カレンダー読込処理 * + * 処理概要 : HOLIDAY_CALENDARをWORKING-STORAGEに格納 * + ***************************************************************** + 1200HDINNSOR SECTION. + * + *** C2初回FETCH(SELECT INTO) + EXEC SQL + SELECT HOLIDAY_DATE + FROM HOLIDAY_CALENDAR + ORDER BY HOLIDAY_DATE + INTO :SQL-HD-DATE + END-EXEC. + * + *** 休日テーブルに全件読込 + PERFORM UNTIL SQLCODE NOT = 0 + ADD 1 TO WRK-HD-COUNT + MOVE SQL-HD-DATE TO WRK-HD-DATE(WRK-HD-COUNT) + CALL 'br_fetch_next' USING SQLCODE + IF SQLCODE = 0 + MOVE 0 TO WS-COL-IDX + MOVE 256 TO WS-COL-LEN + CALL 'br_get_col' USING + WS-COL-IDX, SQL-HD-DATE, WS-COL-LEN + END-IF + END-PERFORM. + * + 1200HDINNSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO: (2.0) * + * サブモジュール名: 主処理 * + * 処理概要 : キーブレイク(社員番号)毎の処理を行う * + ***************************************************************** + 2000MAJSOR SECTION. + * + *** 社員番号キー保存 + MOVE SQL-EMP-ID TO WRK-BFR-EMP-ID. + * + *** 1社員分処理(キーブレイク範囲) + PERFORM 2100-PROCESS-EMP + THRU 2100-PROCESS-EMP-EXIT. + * + 2000MAJSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO: (2.1) * + * サブモジュール名: 社員別処理 * + * 処理概要 : 1社員の全申請を処理(PERFORM THRU対象) * + ***************************************************************** + 2100-PROCESS-EMP SECTION. + * + MOVE ZERO TO CUN-EMP-SUB. + * + PERFORM UNTIL WRK-R01EOF = '1' + OR SQL-EMP-ID NOT = WRK-BFR-EMP-ID + PERFORM 2200-EXPAND-DATE + THRU 2200-EXPAND-DATE-EXIT + PERFORM 1100C1FETCHSOR + END-PERFORM. + * + *** 社員別小計出力(キーブレイク) + INITIALIZE M00MHOPAR. + MOVE CNS-MSGKEYINF TO M00MSGCOD. + MOVE WRK-BFR-EMP-ID TO M00UMKDATS22-01. + MOVE CUN-EMP-SUB TO M00UMKDATS22-02. + MOVE 'EMP SUB' TO M00UMKDATS22-03. + PERFORM 4000MSGOUTSOR. + * + 2100-PROCESS-EMP-EXIT. + EXIT. + ***************************************************************** + * サブモジュールNO: (2.2) * + * サブモジュール名: 日付展開処理 * + * 処理概要 : 開始日〜終了日をループ(PERFORM THRU対象) * + * 休日/週末を除外してLEAVE-DAILYを出力 * + ***************************************************************** + 2200-EXPAND-DATE SECTION. + * + MOVE SQL-START-DATE TO WRK-DATE-CURRENT. + MOVE SQL-END-DATE TO WRK-DATE-END. + * + PERFORM UNTIL WRK-DATE-CURRENT > WRK-DATE-END + COMPUTE WRK-DAY-OF-WEEK = + FUNCTION MOD( + FUNCTION INTEGER-OF-DATE(WRK-DATE-CURRENT), 7) + IF WRK-DAY-OF-WEEK = 0 + OR WRK-DAY-OF-WEEK = 6 + IF WRK-HD-COUNT > 0 + AND WRK-DATE-CURRENT NOT = ZERO + CONTINUE + ELSE + CONTINUE + END-IF + ELSE + *** 休日テーブル検索 + MOVE '0' TO WRK-HD-FOUND + IF WRK-HD-COUNT > 0 + SET WRK-HD-IDX TO 1 + SEARCH ALL WRK-HD-ENTRY + AT END + CONTINUE + WHEN WRK-HD-DATE(WRK-HD-IDX) + = WRK-DATE-CURRENT + MOVE '1' TO WRK-HD-FOUND + END-SEARCH + END-IF + IF WRK-HD-FOUND = '0' + INITIALIZE W01OUTREC + MOVE FUNCTION NUMVAL(SQL-APPL-ID) + TO W01APPL-ID + MOVE WRK-BFR-EMP-ID TO W01EMP-ID + MOVE SQL-LEAVE-TYPE TO W01LEAVE-TYPE + MOVE SQL-START-TIME TO W01START-TIME + MOVE SQL-END-TIME TO W01END-TIME + MOVE WRK-DATE-ALPHA + TO W01DATE + WRITE W01OUTREC + ADD 1 TO CUN-W01OUT + ADD 1 TO CUN-EMP-SUB + END-IF + END-IF + *** 日付加算 + PERFORM 2300-DATE-ADD-1 + END-PERFORM. + * + 2200-EXPAND-DATE-EXIT. + EXIT. + ***************************************************************** + * サブモジュールNO: (2.3) * + * サブモジュール名: 日付加算処理 * + * 処理概要 : 日付を1日進める(月/年跨ぎ対応) * + ***************************************************************** + 2300-DATE-ADD-1 SECTION. + * + ADD 1 TO WRK-DATE-DAY. + * + EVALUATE WRK-DATE-MONTH + WHEN 1 WHEN 3 WHEN 5 WHEN 7 + WHEN 8 WHEN 10 WHEN 12 + IF WRK-DATE-DAY > 31 + MOVE 1 TO WRK-DATE-DAY + ADD 1 TO WRK-DATE-MONTH + IF WRK-DATE-MONTH > 12 + MOVE 1 TO WRK-DATE-MONTH + ADD 1 TO WRK-DATE-YEAR + END-IF + END-IF + WHEN 4 WHEN 6 WHEN 9 WHEN 11 + IF WRK-DATE-DAY > 30 + MOVE 1 TO WRK-DATE-DAY + ADD 1 TO WRK-DATE-MONTH + END-IF + WHEN 2 + IF (FUNCTION MOD(WRK-DATE-YEAR, 400) = 0) + OR (FUNCTION MOD(WRK-DATE-YEAR, 4) = 0 + AND FUNCTION MOD(WRK-DATE-YEAR, 100) + NOT = 0) + IF WRK-DATE-DAY > 29 + MOVE 1 TO WRK-DATE-DAY + ADD 1 TO WRK-DATE-MONTH + END-IF + ELSE + IF WRK-DATE-DAY > 28 + MOVE 1 TO WRK-DATE-DAY + ADD 1 TO WRK-DATE-MONTH + END-IF + END-IF + END-EVALUATE. + * + 2300-DATE-ADD-1-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO: (3.0) * + * サブモジュール名: 終了処理 * + * 処理概要 : ファイルクローズ・件数出力 * + ***************************************************************** + 3000STPSOR SECTION. + * + *** 出力ファイルCLOSE + CLOSE W01OUTFIL. + * + *** 入力件数出力 + INITIALIZE M00MHOPAR. + MOVE CNS-MSGIINKES TO M00MSGCOD. + MOVE 'LEAVE_RECORDS' TO M00UMKDATS22-01. + MOVE CUN-R01INN TO M00UMKDATS22-02. + PERFORM 4000MSGOUTSOR. + * + *** 出力件数出力 + INITIALIZE M00MHOPAR. + MOVE CNS-MSGOUTKES TO M00MSGCOD. + MOVE 'KIN02W01' TO M00UMKDATS22-01. + MOVE CUN-W01OUT TO M00UMKDATS22-02. + PERFORM 4000MSGOUTSOR. + * + *** 休日テーブル件数出力 + INITIALIZE M00MHOPAR. + MOVE CNS-MSGKEYINF TO M00MSGCOD. + MOVE 'HOLIDAYS LOADED' TO M00UMKDATS22-01. + MOVE WRK-HD-COUNT TO M00UMKDATS22-02. + PERFORM 4000MSGOUTSOR. + * + *** 終了メッセージ出力 + INITIALIZE M00MHOPAR. + MOVE CNS-MSGFIN TO M00MSGCOD. + PERFORM 4000MSGOUTSOR. + * + 3000STPSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO: (4.0) * + * サブモジュール名: メッセージ編集出力処理 * + * 処理概要 : メッセージ編集出力サブPGM呼出 * + ***************************************************************** + 4000MSGOUTSOR SECTION. + * + MOVE CNS-KN0002 TO M00UMKDATS22-03(1:1). + MOVE CNS-KN0002 TO M00UMKDATS22-04(1:1). + MOVE CNS-PRGIDX TO M00UMKDATS22-05. + CALL 'SUB02MSG' USING M00MHOPAR. + * + 4000MSGOUTSOR-EXT. + EXIT. + ***************************************************************** + * サブモジュールNO:(9.9) * + * サブモジュール名: ABEND処理 * + * 処理概要 : ABENDサブPGM呼出 * + ***************************************************************** + 9999ABDSOR SECTION. + * + MOVE CNS-ABD999 TO E01ABDCOD. + CALL 'SUB03END' USING E01ABDPAR. + * + 9999ABDSOR-EXT. + EXIT. diff --git a/src/ZAN01CHK.cbl b/src/ZAN01CHK.cbl index 91b1b4c..3c93663 100644 --- a/src/ZAN01CHK.cbl +++ b/src/ZAN01CHK.cbl @@ -295,6 +295,22 @@ INITIALIZE W01OUTREC W03OUTREC. * + *** SUB04CHKで社員番号チェック + INITIALIZE C01CHKPAR. + MOVE WRK-CSV-EMP-ID TO C01CHKDAT. + MOVE 'EMPID' TO C01CHKTYP. + CALL 'SUB04CHK' USING C01CHKPAR. + IF C01CHKRRC NOT = ZERO + MOVE '01' TO W03ERR-CATEGORY + STRING 'EMP-ID ERROR:' + WRK-CSV-EMP-ID + DELIMITED BY SIZE + INTO W03ERR-DETAIL + WRITE W03OUTREC + ADD 1 TO CUN-W03OUT + GO TO 2020VALIDATESOR-EXT + END-IF. + * *** SUB04CHKで日付チェック INITIALIZE C01CHKPAR. MOVE WRK-CSV-APPL-DATE TO C01CHKDAT. diff --git a/sub/SUB04CHK.cbl b/sub/SUB04CHK.cbl index f3b1826..2fbe4b3 100644 --- a/sub/SUB04CHK.cbl +++ b/sub/SUB04CHK.cbl @@ -25,10 +25,12 @@ ***************************************************************** WORKING-STORAGE SECTION. ***************************************************************** - 01 WRKARA. - 03 WRK-RETURN-CODE PIC 9(004). - 03 WRK-SIGN PIC S9(004). - 03 WRK-NN PIC 9(004). + 01 WRKARA. + 03 WRK-RETURN-CODE PIC 9(004). + 03 WRK-SIGN PIC S9(004). + 03 WRK-NN PIC 9(004). + 03 WRK-DIGIT PIC 9(004). + 03 WRK-ALPHA PIC 9(004). * ***************************************************************** * リンケージエリア * @@ -130,11 +132,21 @@ ***************************************************************** 3000CHKNUM SECTION. * - *** 非数字文字が含まれていないかチェック + *** 空チェック(全スペース→正常=オプショナル) INSPECT C01CHKDAT TALLYING WRK-NN FOR - CHARACTERS BEFORE INITIAL SPACE. - IF WRK-NN > 0 THEN + LEADING SPACES. + IF WRK-NN = LENGTH OF C01CHKDAT + MOVE ZERO TO WRK-RETURN-CODE + GO TO 3000CHKNUM-EXT + END-IF. + *** 数字(0-9)とスペースのみをカウント + INSPECT C01CHKDAT + TALLYING WRK-NN + FOR ALL "0" "1" "2" "3" "4" + "5" "6" "7" "8" "9" + SPACE. + IF WRK-NN NOT = LENGTH OF C01CHKDAT MOVE 0003 TO WRK-RETURN-CODE GO TO 3000CHKNUM-EXT END-IF. @@ -155,11 +167,42 @@ MOVE 0004 TO WRK-RETURN-CODE GO TO 4000CHKEMP-EXT END-IF. - *** 英数字チェック + *** 空チェック(全8桁がスペース→必須エラー) + IF C01CHKDAT(1:8) = SPACES + MOVE 0004 TO WRK-RETURN-CODE + GO TO 4000CHKEMP-EXT + END-IF. + *** 数字(0-9)カウント + MOVE ZERO TO WRK-DIGIT. INSPECT C01CHKDAT(1:8) - TALLYING WRK-NN FOR - CHARACTERS BEFORE INITIAL SPACE. - IF WRK-NN > 0 THEN + TALLYING WRK-DIGIT + FOR ALL "0" "1" "2" "3" "4" + "5" "6" "7" "8" "9". + *** 英字(A-Z a-z)カウント + MOVE ZERO TO WRK-ALPHA. + INSPECT C01CHKDAT(1:8) + TALLYING WRK-ALPHA + FOR ALL "A" "B" "C" "D" "E" + "F" "G" "H" "I" "J" + "K" "L" "M" "N" "O" + "P" "Q" "R" "S" "T" + "U" "V" "W" "X" "Y" + "Z" + "a" "b" "c" "d" "e" + "f" "g" "h" "i" "j" + "k" "l" "m" "n" "o" + "p" "q" "r" "s" "t" + "u" "v" "w" "x" "y" + "z". + *** スペースカウント + MOVE ZERO TO WRK-NN. + INSPECT C01CHKDAT(1:8) + TALLYING WRK-NN + FOR ALL SPACE. + *** 英数字以外(特殊文字)がないかチェック + ADD WRK-DIGIT TO WRK-ALPHA. + ADD WRK-NN TO WRK-ALPHA. + IF WRK-ALPHA NOT = 8 MOVE 0004 TO WRK-RETURN-CODE GO TO 4000CHKEMP-EXT END-IF. diff --git a/使用資源一覧/KIN01INP_使用資源一覧.md b/使用資源一覧/KIN01INP_使用資源一覧.md new file mode 100644 index 0000000..bb60650 --- /dev/null +++ b/使用資源一覧/KIN01INP_使用資源一覧.md @@ -0,0 +1,51 @@ +# KIN01INP 使用資源一覧 + +## プログラム概要 +- **プログラムID**: KIN01INP +- **プログラム名**: 休暇申請CSV取込・検証処理 +- **処理概要**: CSV形式の休暇申請ファイルを読み込み、休暇種別テーブル検索と項目チェックを行い、ステータスによってWORK-LEAVEまたはERROR-LOGへ振り分ける。 + +## 使用ファイル + +| DD名 | ファイル識別子 | 編成 | レコード形式 | レコード長 | COPY句 | +|------|---------------|------|-------------|-----------|--------| +| KIN01R01 | CSV-INPUT | 順編成 | F (固定長) | 80B | なし(自前定義) | +| KIN01W01 | WORK-LEAVE | 順編成 | F (固定長) | 80B | KIN01REC | +| KIN01W02 | ERROR-LOG | 順編成 | V (可変長) | 200B | KIN05REC | + +## 使用COPY句 + +| COPY句 | 用途 | 使用箇所 | +|--------|------|---------| +| KIN01REC | レコード定義(W01出力ファイル) | FILE SECTION | +| KIN05REC | エラーログレコード定義(W02出力ファイル) | FILE SECTION | +| ZANDATAC | 運用日付サブPGM連絡領域 | WORKING-STORAGE | +| ZANMSGAC | メッセージ編集サブPGM連絡領域 | WORKING-STORAGE | +| ZANENDAC | ABENDサブPGM連絡領域 | WORKING-STORAGE | +| ZANCHKAC | 項目チェックサブPGM連絡領域 | WORKING-STORAGE | + +## 使用サブプログラム + +| サブPGM | 役割 | CALL箇所 | +|---------|------|---------| +| SUB01DAT | 運用日付取得 | 1000ITTSOR | +| SUB02MSG | メッセージ編集出力 | 4000MSGOUTSOR | +| SUB03END | ABEND処理 | 9999ABDSOR | +| SUB04CHK | 日付/時刻/社員番号妥当性チェック | 2030VALIDATESOR | + +## 使用DB2テーブル + +なし(DB操作なし) + +## 処理フロー +1. 初期処理(開始メッセージ→休暇種別テーブル設定→運用日付取得→OPEN→初回読込) +2. CSV分解(UNSTRINGで8項目に分解) +3. 休暇種別テーブル検索(SEARCH) +4. エラー前提判定 + - フィールド数≠8 → ERROR-LOG出力(種別:F) + - 休暇種別未発見 → ERROR-LOG出力(種別:L) +5. ステータス判定 + - ステータス'1'(有効)→ 項目チェック(SUB04CHK: 開始日付/時刻、終了日付/時刻)→ WORK-LEAVE出力(APPL-ID=0) + - ステータス'9'(取消)→ WORK-LEAVE出力(APPL-ID保持、チェックなし) + - その他(エラー)→ ERROR-LOG出力(種別:S) +6. 終了処理(CLOSE→件数出力→終了メッセージ) diff --git a/使用資源一覧/KIN02UPD_使用資源一覧.md b/使用資源一覧/KIN02UPD_使用資源一覧.md new file mode 100644 index 0000000..7b20202 --- /dev/null +++ b/使用資源一覧/KIN02UPD_使用資源一覧.md @@ -0,0 +1,59 @@ +# KIN02UPD 使用資源一覧 + +## プログラム概要 +- **プログラムID**: KIN02UPD +- **プログラム名**: 休暇申請DB更新処理 +- **処理概要**: WORK-LEAVEファイルの各レコードをDB2テーブルLEAVE_RECORDSに反映する。ステータスに応じて新規登録(INSERT)、変更(DELETE+INSERT)、取消(DELETE)を行う。 + +## 使用ファイル + +| DD名 | ファイル識別子 | 編成 | レコード形式 | レコード長 | COPY句 | +|------|---------------|------|-------------|-----------|--------| +| KIN01W01 | WORK-LEAVE | 順編成 | F (固定長) | 80B | KIN01REC | +| KIN02W01 | ERROR-LOG | 順編成 | V (可変長) | 200B | KIN05REC | + +## 使用COPY句 + +| COPY句 | 用途 | 使用箇所 | +|--------|------|---------| +| KIN01REC | レコード定義(R01入力ファイル) | FILE SECTION | +| KIN05REC | エラーログレコード定義(W01出力) | FILE SECTION | +| ZANMSGAC | メッセージ編集サブPGM連絡領域 | WORKING-STORAGE | +| ZANENDAC | ABENDサブPGM連絡領域 | WORKING-STORAGE | +| SQLCA | SQL通信領域 | WORKING-STORAGE | + +## 使用サブプログラム + +| サブPGM | 役割 | CALL箇所 | +|---------|------|---------| +| SUB02MSG | メッセージ編集出力 | 4000MSGOUTSOR | +| SUB03END | ABEND処理 | 9999ABDSOR | + +## 使用DB2テーブル + +| テーブル名 | 操作 | 備考 | +|-----------|------|------| +| LEAVE_RECORDS | INSERT, DELETE | APPLICATION_ID=0→INSERT, >0→DELETE+INSERT, STATUS='9'→DELETE | + +## EXEC SQL一覧 + +| SQL種別 | 処理 | 実行条件 | 使用箇所 | +|---------|------|---------|---------| +| CONNECT | TO 'data/kin.db' | 常時 | 1000ITTSOR | +| INSERT | LEAVE_RECORDSへ追加 | STATUS='1' AND APPL-ID=0 | 2110INSERTSOR | +| DELETE | APPLICATION_ID一致削除+INSERT | STATUS='1' AND APPL-ID>0 | 2120UPDATESOR | +| INSERT | LEAVE_RECORDSへ追加(変更後) | STATUS='1' AND APPL-ID>0 | 2120UPDATESOR | +| DELETE | APPLICATION_ID一致削除 | STATUS='9' | 2130DELETESOR | +| COMMIT | WORK | 常時 | 3000STPSOR | +| ROLLBACK | WORK | SQLエラー時 | 9100DBERRSOR | + +## 処理フロー +1. 初期処理(開始メッセージ→DB接続→OPEN(R01/W01)→初回読込) +2. ホスト変数設定(R01→WS-*) +3. ロジック分岐(EVALUATE) + - STATUS='1' AND APPL-ID=0 → INSERT + - STATUS='1' AND APPL-ID>0 → DELETE + INSERT + - STATUS='9' → DELETE + - その他 → スキップ +4. SQLエラー時 → ROLLBACK + ERROR-LOG出力(W01) + エラーメッセージ + ABEND +5. 終了処理(COMMIT→CLOSE(R01/W01)→件数出力→終了メッセージ) diff --git a/使用資源一覧/KIN03EXP_使用資源一覧.md b/使用資源一覧/KIN03EXP_使用資源一覧.md new file mode 100644 index 0000000..675d953 --- /dev/null +++ b/使用資源一覧/KIN03EXP_使用資源一覧.md @@ -0,0 +1,61 @@ +# KIN03EXP 使用資源一覧 + +## プログラム概要 +- **プログラムID**: KIN03EXP +- **プログラム名**: 休暇日別展開処理 +- **処理概要**: LEAVE_RECORDS(DB2)より有効申請(STATUS='1')を読込み、開始日〜終了日の期間を日別に展開し、休日・週末を除外してLEAVE-DAILYファイルを出力する。社員番号キーブレイクで小計出力を行う。 + +## 使用ファイル + +| DD名 | ファイル識別子 | 編成 | レコード形式 | レコード長 | COPY句 | +|------|---------------|------|-------------|-----------|--------| +| KIN02W01.DAT | LEAVE-DAILY | 順編成 | F (固定長) | 80B | KIN02REC | + +## 使用COPY句 + +| COPY句 | 用途 | 使用箇所 | +|--------|------|---------| +| KIN02REC | レコード定義(W01出力ファイル) | FILE SECTION | +| ZANDATAC | 運用日付サブPGM連絡領域 | WORKING-STORAGE | +| ZANMSGAC | メッセージ編集サブPGM連絡領域 | WORKING-STORAGE | +| ZANENDAC | ABENDサブPGM連絡領域 | WORKING-STORAGE | +| SQLCA | SQL通信領域 | WORKING-STORAGE | + +## 使用サブプログラム + +| サブPGM | 役割 | CALL箇所 | +|---------|------|---------| +| SUB01DAT | 運用日付取得 | 1000ITTSOR | +| SUB02MSG | メッセージ編集出力 | 4000MSGOUTSOR | +| SUB03END | ABEND処理 | 9999ABDSOR | +| br_fetch_next | SQLカーソル次行FETCH(bridge) | 1100C1FETCHSOR, 1200HDINNSOR | +| br_get_col | SQLカラム値取得(bridge) | 1100C1FETCHSOR, 1200HDINNSOR | + +## 使用DB2テーブル + +| テーブル名 | 操作 | 備考 | +|-----------|------|------| +| LEAVE_RECORDS | SELECT | STATUS='1'、ORDER BY EMP_ID, START_DATE | +| HOLIDAY_CALENDAR | SELECT | 休日マスタ、ORDER BY HOLIDAY_DATE | + +## EXEC SQL一覧 + +| SQL種別 | 処理 | 実行条件 | 使用箇所 | +|---------|------|---------|---------| +| CONNECT | TO 'data/kin.db' | 常時 | 1000ITTSOR | +| SELECT | HOLIDAY_DATE FROM HOLIDAY_CALENDAR | 常時(初回のみ) | 1200HDINNSOR | +| SELECT | LEAVE_RECORDS(全件) | 常時(初回のみ) | 1100C1INITSOR | + +## 処理フロー +1. 初期処理(開始メッセージ→DB接続→運用日付取得) +2. 休日カレンダー全件読込(WORKING-STORAGEに格納) +3. 出力ファイルOPEN +4. DB初回FETCH(LEAVE_RECORDS:STATUS='1'、ORDER BY EMP_ID, START_DATE) +5. 社員番号キーブレイクループ + - 社員別に期間内を日別展開 + - 週末判定(MOD(INTEGER-OF-DATE,7)=0/6)→除外 + - 休日判定(SEARCH ALL on WRK-HOLIDAY-TABLE)→除外 + - 非週末・非休日 → LEAVE-DAILY出力 + - 日付加算(月跨ぎ/閏年対応) + - キーブレイク時:社員別小計メッセージ出力 +6. 終了処理(CLOSE→件数出力→終了メッセージ) diff --git a/使用資源一覧/ZAN01CHK_使用資源一覧.md b/使用資源一覧/ZAN01CHK_使用資源一覧.md index c7f5e45..38c9983 100644 --- a/使用資源一覧/ZAN01CHK_使用資源一覧.md +++ b/使用資源一覧/ZAN01CHK_使用資源一覧.md @@ -32,7 +32,7 @@ | SUB01DAT | 運用日付取得 | 1000ITTSOR | | SUB02MSG | メッセージ編集出力 | 4000MSGOUTSOR | | SUB03END | ABEND処理 | 9999ABDSOR | -| SUB04CHK | 日付妥当性チェック | 2020VALIDATESOR | +| SUB04CHK | 日付/社員番号妥当性チェック | 2020VALIDATESOR | ## 使用DB2テーブル diff --git a/詳細設計書/詳細設計書_KIN01INP.md b/詳細設計書/詳細設計書_KIN01INP.md new file mode 100644 index 0000000..2d5b054 --- /dev/null +++ b/詳細設計書/詳細設計書_KIN01INP.md @@ -0,0 +1,153 @@ +# 詳細設計書 + +## 基本情報 + +| # | 項目 | 内容 | +|---|------|------| +| 1 | システム名 | 勤怠休暇管理システム | +| 2 | プログラムID | KIN01INP | +| 3 | プログラム名 | 休暇申請CSV取込・検証処理 | +| 4 | PGMタイプ | メイン | +| 5 | PGMパターン | 振り分け | +| 6 | 機能概要 | CSV形式の休暇申請ファイルを読み込み、休暇種別テーブル検索と項目チェックを行い、ステータスによってWORK-LEAVEまたはERROR-LOGへ振り分ける。 | +| 7 | | ステータス'1':有効申請としてWORK-LEAVEに出力(項目チェック実施) | +| 8 | | ステータス'9':取消申請としてWORK-LEAVEに出力(項目チェックなし、APPL-ID保持) | +| 9 | | その他・フィールド数異常・休暇種別異常:ERROR-LOGに出力 | + +※PGMタイプ:メイン、サブ +※PGMパターン:マッチング(1:1、1:N、N:1、M:N)、レイアウト編集のみ(GETPUT)、振り分け(IF文、EVALUATE文)、キーブレイク(集計、集約、集計・集約の以外)、DB更新 + +### 前提条件 + +| NO | 対象ファイル | 条件 | +|----|-------------|------| +| 1 | KIN01R01(CSV) | ソート不要。CSV形式(カンマ区切り、8項目) | + +### 使用ファイル一覧 + +| NO | 使用ファイル/DB名 | 識別子 | DD名 | I/O | COPY群 | 形式 | ブロック | レコード長 | 媒体 | 備考 | +|----|------------------|--------|------|-----|--------|------|---------|-----------|------|------| +| 1 | CSV-INPUT | R01 | KIN01R01 | I | 自前(80B) | F | | 80 | PS | CSV形式 | +| 2 | WORK-LEAVE | W01 | KIN01W01 | O | KIN01REC | FB | | 80 | PS | | +| 3 | ERROR-LOG | W02 | KIN01W02 | O | KIN05REC | VB | | 200 | PS | | + +### キー項目一覧 + +| NO | ファイル名 | ソート条件(キー項目) | キー条件(マッチング/キーブレイク) | +|----|-----------|---------------------|-------------------------------------------| +| 1 | CSV-INPUT | なし | なし | + +### 使用モジュール一覧 + +| NO | 機能 | プログラムID | 使用COPY名 | +|----|------|-------------|-----------| +| 1 | 運用日付取得SUB | SUB01DAT | ZANDATAC | +| 2 | メッセージ編集出力SUB | SUB02MSG | ZANMSGAC | +| 3 | ABEND処理SUB | SUB03END | ZANENDAC | +| 4 | 項目チェックSUB | SUB04CHK | ZANCHKAC | + +--- + +## 処理詳細 + +``` +1.初期処理(1000ITTSOR) + 1-1.開始メッセージ出力 + 【メッセージ編集】 + メッセージ番号:1(開始メッセージ) + 1-2.コンパイル日時出力 + 【メッセージ編集】 + メッセージ番号:33(コンパイル日時) + PARM1:コンパイル日時 + PARM2:'COMPILED' + 1-3.ワークエリアの初期化 + 1-4.休暇種別テーブル設定(WRK-LEAVE-TYPE-TABLE) + WRK-LT-CODE(1)='01' (年休/年假) + WRK-LT-CODE(2)='02' (事假) + WRK-LT-CODE(3)='03' (因公特批假) + WRK-LT-CODE(4)='04' (病欠) + 1-5.運用日付取得SUB(SUB01DAT)により運用日を取得する。 + 復帰コード≠ZEROの場合、メッセージを出力し、ABEND処理SUBを呼び出し異常終了する。 + 【メッセージ編集】 + メッセージ番号:5(サブエラー) + PARM1:'SUB01DAT' + PARM2:復帰コード + 【ABEND処理SUB】 + ABENDコード:999 + 1-6.使用ファイルのオープン(R01:入力、W01/W02:出力) + 1-7.R01を読み込む。(1100R01INNSOR)(1回目) + +2.主処理(2000MAJSOR)(R01を全て読み終えるまで下記を繰り返す) + 2-1.CSVの分解(2010CSVSOR) + UNSTRINGでカンマ区切りのCSVを8項目に分解する。 + (APPL-ID, EMP-ID, START-DATE, START-TIME, END-DATE, END-TIME, LEAVE-TYPE, STATUS) + 2-2.休暇種別テーブル検索(2020LEAVSERSOR) + SEARCH(非ALL)でWRK-LEAVE-TYPE-TABLEを検索し、休暇種別の妥当性を検証する。 + 2-3.エラー判定 + 2-3-1.フィールド数≠8の場合 + ERROR-LOGに出力する。(2050ERRORSOR) + エラー種別:'F'(FIELD COUNT ERROR) + 2-3-2.休暇種別がテーブルに存在しない場合 + ERROR-LOGに出力する。(2050ERRORSOR) + エラー種別:'L'(INVALID LEAVE TYPE) + 2-3-3.ステータス'1'(有効)の場合 + 項目チェックを実施し、エラーがあればERROR-LOGに出力、なければWORK-LEAVEに出力する。(2030VALIDATESOR) + 2-3-3-1.SUB04CHKで社員番号チェック(EMPID): WRK-CSV-EMP-IDをC01CHKDATに設定し、CALL 'SUB04CHK' EMPIDタイプで社員番号フォーマットの妥当性を検証する。エラーの場合はW02ERR-CATEGORY='01'でエラーログに出力し本レコードをスキップ。 + 2-3-3-2.開始日付チェック(SUB04CHK)。エラー→W02出力 + 2-3-3-3.開始時刻チェック(SUB04CHK)。エラー→W02出力 + 2-3-3-4.終了日付チェック(SUB04CHK)。エラー→W02出力 + 2-3-3-5.終了時刻チェック(SUB04CHK)。エラー→W02出力 + 2-3-3-6.複合条件チェック(AND+OR+3段ネスト) + 開始日>0 AND 終了日>0 AND 開始時刻>0 の場合: + - 開始日>終了日 → WRK-DEMO-TYPE=10 + - 開始日=終了日 AND 開始時刻>=終了時刻 → WRK-DEMO-TYPE=10 + - 上記以外 → WRK-DEMO-TYPE=20 + 2-3-3-7.すべて通過→W01出力(APPL-ID=0, STATUS='1') + 2-3-4.ステータス'9'(取消)の場合 + WORK-LEAVEにそのまま出力する。(2040CANCELSOR) + APPL-ID=CSV値、STATUS='9'(項目チェックなし) + 2-3-5.その他のステータスの場合 + ERROR-LOGに出力する。(2050ERRORSOR) + エラー種別:'S'(INVALID STATUS) + 2-4.R01を読み込む。(1100R01INNSOR)(2件目以降) + +3.終了処理(3000STPSOR) + 3-1.入出力ファイルのクローズ + 3-2.入出力件数出力メッセージ出力 + 【入力メッセージ編集】 + メッセージ番号:6(入力件数メッセージ) + PARM1:'KIN01R01' + PARM2:当該入力ファイルの件数 + 【出力メッセージ編集】 + メッセージ番号:7(出力件数メッセージ) + PARM1:'KIN01W01'、'KIN01W02' + PARM2:当該出力ファイルの件数 + 3-3.終了メッセージ出力 + 【メッセージ編集】 + メッセージ番号:2(終了メッセージ) +``` + +--- + +## 出力レコード定義 + +### 出力ファイル1(W01/WORK-LEAVE) KIN01REC 80B FB + +| No | 項目名 | 設定元 | 備考 | +|----|--------|--------|------| +| 1 | APPL-ID | WRK-CSV-APPL-ID | 有効時=0、取消時=CSV値 | +| 2 | EMP-ID | WRK-CSV-EMP-ID | | +| 3 | LEAVE-TYPE | WRK-CSV-LEAVE-TYPE | 01/02/03/04 | +| 4 | START-DATE | WRK-CSV-START-DATE | YYYYMMDD | +| 5 | START-TIME | WRK-CSV-START-TIME | HHMM | +| 6 | END-DATE | WRK-CSV-END-DATE | YYYYMMDD | +| 7 | END-TIME | WRK-CSV-END-TIME | HHMM | +| 8 | STATUS | WRK-CSV-STATUS | '1'(有効)または'9'(取消) | +| 9 | FILLER | SPACE | 36B | + +### 出力ファイル2(W02/ERROR-LOG) KIN05REC 200B VB + +| No | 項目名 | 設定元 | 備考 | +|----|--------|--------|------| +| 1 | ERR-CATEGORY | '01'固定 | | +| 2 | ERR-DETAIL | STRING編集 | エラー内容(198B) | diff --git a/詳細設計書/詳細設計書_KIN02UPD.md b/詳細設計書/詳細設計書_KIN02UPD.md new file mode 100644 index 0000000..c447fb8 --- /dev/null +++ b/詳細設計書/詳細設計書_KIN02UPD.md @@ -0,0 +1,155 @@ +# 詳細設計書 + +## 基本情報 + +| # | 項目 | 内容 | +|---|------|------| +| 1 | システム名 | 勤怠休暇管理システム | +| 2 | プログラムID | KIN02UPD | +| 3 | プログラム名 | 休暇申請DB更新処理 | +| 4 | PGMタイプ | メイン | +| 5 | PGMパターン | DB更新 | +| 6 | 機能概要 | WORK-LEAVEファイルの各レコードをDB2テーブルLEAVE_RECORDSに反映する。 | +| 7 | | ステータスによって新規登録(INSERT)、変更(DELETE+INSERT)、取消(DELETE)を行う。 | + +※PGMタイプ:メイン、サブ +※PGMパターン:マッチング(1:1、1:N、N:1、M:N)、レイアウト編集のみ(GETPUT)、振り分け(IF文、EVALUATE文)、キーブレイク(集計、集約、集計・集約の以外)、DB更新 + +### 前提条件 + +| NO | 対象ファイル | 条件 | +|----|-------------|------| +| 1 | KIN01W01 | KIN01INPの出力順に従う。ソート不要。 | + +### 使用ファイル一覧 + +| NO | 使用ファイル/DB名 | 識別子 | DD名 | I/O | COPY群 | 形式 | ブロック | レコード長 | 媒体 | 備考 | +|----|------------------|--------|------|-----|--------|------|---------|-----------|------|------| +| 1 | WORK-LEAVE | R01 | KIN01W01 | I | KIN01REC | FB | | 80 | PS | | +| 2 | ERROR-LOG | W01 | KIN02W01 | O | KIN05REC | VB | | 200 | PS | DBエラー時出力 | +| 3 | LEAVE_RECORDS | DB | — | I/U/D | — | — | — | — | DB | SQLite | + +### キー項目一覧 + +| NO | ファイル名 | ソート条件(キー項目) | キー条件(マッチング/キーブレイク) | +|----|-----------|---------------------|-------------------------------------------| +| 1 | WORK-LEAVE | なし | なし | + +### 使用モジュール一覧 + +| NO | 機能 | プログラムID | 使用COPY名 | +|----|------|-------------|-----------| +| 1 | メッセージ編集出力SUB | SUB02MSG | ZANMSGAC | +| 2 | ABEND処理SUB | SUB03END | ZANENDAC | + +--- + +## 処理詳細 + +``` +1.初期処理(1000ITTSOR) + 1-1.開始メッセージ出力 + 【メッセージ編集】 + メッセージ番号:1(開始メッセージ) + 1-2.コンパイル日時出力 + 【メッセージ編集】 + メッセージ番号:33(コンパイル日時) + PARM1:コンパイル日時 + PARM2:'COMPILED' + 1-3.ワークエリアの初期化 + 1-4.DB接続 + EXEC SQL CONNECT TO 'data/kin.db' + 1-5.R01ファイルOPEN(入力)+ W01ファイルOPEN(出力) + 1-6.R01を初回読込(1100R01INNSOR) + +2.主処理(2000MAJSOR)(R01を全て読み終えるまで下記を繰り返す) + 2-1.レコード処理(2100PROCSOR) + 2-1-1.R01各項目をホスト変数(WS-*)にMOVEする。 + 2-1-2.ロジック分岐判定(EVALUATE) + 2-1-2-1.STATUS='1' AND APPL-ID=0(新規)の場合 + INSERT処理(2110INSERTSOR) + 【SQL】 + INSERT INTO LEAVE_RECORDS + (EMP_ID, LEAVE_TYPE, START_DATE, START_TIME, + END_DATE, END_TIME, STATUS) + VALUES + (:WS-EMP-ID, :WS-LEAVE-TYPE, + :WS-START-DATE, :WS-START-TIME, + :WS-END-DATE, :WS-END-TIME, + :WS-STATUS) + SQLCODE≠0の場合、DBエラー処理(9100DBERRSOR)を実行する。 + CUN-DBXINSを+1する。 + 2-1-2-2.STATUS='1' AND APPL-ID>0(変更)の場合 + UPDATE処理(2120UPDATESOR) + 【SQL】 + DELETE FROM LEAVE_RECORDS + WHERE APPLICATION_ID = :WS-APPL-ID + INSERT INTO LEAVE_RECORDS + (EMP_ID, LEAVE_TYPE, START_DATE, START_TIME, + END_DATE, END_TIME, STATUS) + VALUES + (:WS-EMP-ID, :WS-LEAVE-TYPE, + :WS-START-DATE, :WS-START-TIME, + :WS-END-DATE, :WS-END-TIME, + :WS-STATUS) + 各SQLでSQLCODE≠0の場合、DBエラー処理(9100DBERRSOR)を実行する。 + CUN-DBXUPDを+1する。 + 2-1-2-3.STATUS='9'(取消)の場合 + DELETE処理(2130DELETESOR) + 【SQL】 + DELETE FROM LEAVE_RECORDS + WHERE APPLICATION_ID = :WS-APPL-ID + SQLCODE≠0の場合、DBエラー処理(9100DBERRSOR)を実行する。 + CUN-DBXDELを+1する。 + 2-1-2-4.その他 + 何も処理しない(CONTINUE) + 2-2.次レコード読込(1100R01INNSOR)(2件目以降) + +3.終了処理(3000STPSOR) + 3-1.COMMIT + EXEC SQL COMMIT WORK + 3-2.入出力ファイルのクローズ + 3-3.件数メッセージ出力 + 【メッセージ編集】 + メッセージ番号:6(入力件数) + PARM1:'KIN01W01' + PARM2:入力件数 + PARM1:'INS'、'UPD'、'DEL' + PARM2:各処理件数 + 3-4.終了メッセージ出力 + 【メッセージ編集】 + メッセージ番号:2(終了メッセージ) + +4.DBエラー処理(9100DBERRSOR) + 4-1.ROLLBACK + EXEC SQL ROLLBACK WORK + 4-2.ERROR-LOG出力(W01OUTFIL) + 【MOVE → INITIALIZE & WRITE】 + MOVE SQLCODE TO WRK-SQLCODE-DISP + W01ERR-CATEGORY = '01'(固定) + W01ERR-DETAIL = 'KIN02UPD SQLCODE=' + WRK-SQLCODE-DISP + ' APPL-ID=' + WS-APPL-ID + CUN-W01OUTを+1する。 + 4-3.エラーメッセージ出力 + 【メッセージ編集】 + メッセージ番号:5(サブエラー) + PARM1:'KIN02UPD SQL ERROR' + PARM2:SQLCODE + PARM3:WS-APPL-ID + 4-4.ABEND処理SUB呼出(9999ABDSOR) + ABENDコード:999 +``` + +--- + +## 出力レコード定義 + +### 出力ファイル1(W01/ERROR-LOG) + +| No | 項目名 | 設定元 | 備考 | +|----|--------|--------|------| +| 1 | ERR-CATEGORY | 01で固定 | DBエラー | + | 2 | ERR-DETAIL | STRINGで編集 | KIN02UPD SQLCODE= + WRK-SQLCODE-DISP + APPL-ID= + WS-APPL-ID | + +### DB更新結果 + +LEAVE_RECORDSテーブルに直接反映される。 diff --git a/詳細設計書/詳細設計書_KIN03EXP.md b/詳細設計書/詳細設計書_KIN03EXP.md new file mode 100644 index 0000000..853b1a3 --- /dev/null +++ b/詳細設計書/詳細設計書_KIN03EXP.md @@ -0,0 +1,170 @@ +# 詳細設計書 + +## 基本情報 + +| # | 項目 | 内容 | +|---|------|------| +| 1 | システム名 | 勤怠休暇管理システム | +| 2 | プログラムID | KIN03EXP | +| 3 | プログラム名 | 休暇日別展開処理 | +| 4 | PGMタイプ | メイン | +| 5 | PGMパターン | キーブレイク(集計) | +| 6 | 機能概要 | LEAVE_RECORDS(DB2)より有効申請(STATUS='1')を読込み、開始日〜終了日の期間を日別に展開し、休日・週末を除外してLEAVE-DAILYファイルを出力する。 | +| 7 | | 社員番号(EMP_ID)キーブレイクで小計出力を行う。 | + +※PGMタイプ:メイン、サブ +※PGMパターン:マッチング(1:1、1:N、N:1、M:N)、レイアウト編集のみ(GETPUT)、振り分け(IF文、EVALUATE文)、キーブレイク(集計、集約、集計・集約の以外)、DB更新 + +### 前提条件 + +| NO | 対象ファイル | 条件 | +|----|-------------|------| +| 1 | DB(LEAVE_RECORDS) | EMP_ID, START_DATE順にソート済(ORDER BYで取得) | + +### 使用ファイル一覧 + +| NO | 使用ファイル/DB名 | 識別子 | DD名 | I/O | COPY群 | 形式 | ブロック | レコード長 | 媒体 | 備考 | +|----|------------------|--------|------|-----|--------|------|---------|-----------|------|------| +| 1 | LEAVE-DAILY | W01 | KIN02W01.DAT | O | KIN02REC | FB | | 80 | PS | 日別展開後レコード | +| 2 | LEAVE_RECORDS | DB | — | I | — | — | — | — | DB | SQLite | +| 3 | HOLIDAY_CALENDAR | DB | — | I | — | — | — | — | DB | SQLite | + +### キー項目一覧 + +| NO | ファイル名 | ソート条件(キー項目) | キー条件(マッチング/キーブレイク) | +|----|-----------|---------------------|-------------------------------------------| +| 1 | DB(LEAVE_RECORDS) | EMP-ID, START_DATE(昇順) | キーブレイク: EMP-ID | + +### 使用モジュール一覧 + +| NO | 機能 | プログラムID | 使用COPY名 | +|----|------|-------------|-----------| +| 1 | 運用日付取得SUB | SUB01DAT | ZANDATAC | +| 2 | メッセージ編集出力SUB | SUB02MSG | ZANMSGAC | +| 3 | ABEND処理SUB | SUB03END | ZANENDAC | + +--- + +## 処理詳細 + +``` +1.初期処理(1000ITTSOR) + 1-1.開始メッセージ出力 + 【メッセージ編集】 + メッセージ番号:1(開始メッセージ) + 1-2.コンパイル日時出力 + 【メッセージ編集】 + メッセージ番号:33(コンパイル日時) + PARM1:コンパイル日時 + PARM2:'COMPILED' + 1-3.ワークエリアの初期化 + 1-4.DB接続 + EXEC SQL CONNECT TO 'data/kin.db' + 1-5.運用日付取得SUB(SUB01DAT)により運用日を取得する。 + 復帰コード≠ZEROの場合、メッセージを出力し、ABEND処理SUBを呼び出し異常終了する。 + 【メッセージ編集】 + メッセージ番号:5(サブエラー) + PARM1:'SUB01DAT' + PARM2:復帰コード + 【ABEND処理SUB】 + ABENDコード:999 + 1-6.休日カレンダーテーブル読込(1200HDINNSOR) + 【SQL】 + SELECT HOLIDAY_DATE FROM HOLIDAY_CALENDAR ORDER BY HOLIDAY_DATE + FETCHループでWORKING-STORAGEのWRK-HOLIDAY-TABLEに全件格納する。 + WRK-HD-COUNTに件数を保持。最大366件(ODO定義)。 + 1-7.出力ファイルOPEN(W01) + 1-8.C1カーソル初回FETCH(1100C1INITSOR) + 【SQL】 + SELECT APPLICATION_ID, EMP_ID, LEAVE_TYPE, + START_DATE, START_TIME, END_DATE, END_TIME + FROM LEAVE_RECORDS + WHERE STATUS = '1' + ORDER BY EMP_ID, START_DATE + INTO :SQL-APPL-ID, :SQL-EMP-ID, :SQL-LEAVE-TYPE, + :SQL-START-DATE, :SQL-START-TIME, + :SQL-END-DATE, :SQL-END-TIME + SQLCODE=0の場合、入力件数+1 + SQLCODE≠0の場合、WRK-R01EOF='1'(EOF) + +2.主処理(2000MAJSOR)(R01を全て読み終えるまで下記を繰り返す) + 2-1.社員番号キー保存 + SQL-EMP-ID → WRK-BFR-EMP-ID + 2-2.1社員分処理(2100-PROCESS-EMP)(PERFORM THRU) + 2-2-1.CUN-EMP-SUB初期化(ZERO) + 2-2-2.EOFまたはキー変化(SQL-EMP-ID≠WRK-BFR-EMP-ID)まで繰り返し + 2-2-2-1.日付展開処理(2200-EXPAND-DATE)(PERFORM THRU) + 2-2-2-1-1.開始日(SQL-START-DATE)→WRK-DATE-CURRENT + 終了日(SQL-END-DATE)→WRK-DATE-END + 2-2-2-1-2.WRK-DATE-CURRENT > WRK-DATE-END までループ + 2-2-2-1-2-1.曜日判定 + COMPUTE WRK-DAY-OF-WEEK = FUNCTION MOD( + FUNCTION INTEGER-OF-DATE(WRK-DATE-CURRENT), 7) + 0=日曜日、6=土曜日 → 週末としてスキップ + 2-2-2-1-2-2.非週末の場合、休日テーブル検索 + SEARCH ALL WRK-HD-ENTRY(昇順KEY=WRK-HD-DATE) + WRK-HD-DATE(WRK-HD-IDX) = WRK-DATE-CURRENT → 休日としてスキップ + 2-2-2-1-2-3.非週末かつ非休日の場合、W01出力 + W01レコード初期化 + APPL-ID = SQL-APPL-ID + EMP-ID = WRK-BFR-EMP-ID + LEAVE-TYPE = SQL-LEAVE-TYPE + START-TIME = SQL-START-TIME + END-TIME = SQL-END-TIME + DATE = WRK-DATE-ALPHA(現在日付) + WRITE W01OUTREC + CUN-W01OUT +1 + CUN-EMP-SUB +1 + 2-2-2-1-2-4.日付加算(2300-DATE-ADD-1) + WRK-DATE-DAY + 1 + 各月の最終日判定: + - 1/3/5/7/8/10/12月:31日超で月+1、13月→年+1 + - 4/6/9/11月:30日超で月+1 + - 2月:閏年判定(MOD年400=0 または MOD年4=0 AND MOD年100≠0) + 閏年→29日超、平年→28日超で月+1 + 2-2-3.次レコードFETCH(1100C1FETCHSOR) + CALL 'br_fetch_next' USING SQLCODE + SQLCODE=0の場合、br_get_colで各カラムを取得 + SQLCODE≠0の場合、WRK-R01EOF='1' + 2-2-4.社員別小計出力(キーブレイク) + 【メッセージ編集】 + メッセージ番号:33(情報メッセージ) + PARM1:WRK-BFR-EMP-ID + PARM2:CUN-EMP-SUB + PARM3:'EMP SUB' + +3.終了処理(3000STPSOR) + 3-1.出力ファイルのクローズ + 3-2.件数メッセージ出力 + 【メッセージ編集】 + メッセージ番号:6(入力件数) + PARM1:'LEAVE_RECORDS' + PARM2:入力件数 + 【メッセージ編集】 + メッセージ番号:7(出力件数) + PARM1:'KIN02W01' + PARM2:出力件数 + 【メッセージ編集】 + メッセージ番号:33(情報) + PARM1:'HOLIDAYS LOADED' + PARM2:休日テーブル件数 + 3-3.終了メッセージ出力 + 【メッセージ編集】 + メッセージ番号:2(終了メッセージ) +``` + +--- + +## 出力レコード定義 + +### 出力ファイル1(W01/LEAVE-DAILY) KIN02REC 80B FB + +| No | 項目名 | 設定元 | 備考 | +|----|--------|--------|------| +| 1 | EMP-ID | WRK-BFR-EMP-ID | キーブレイク単位 | +| 2 | DATE | WRK-DATE-ALPHA | 展開された日付(YYYYMMDD) | +| 3 | LEAVE-TYPE | SQL-LEAVE-TYPE | 01/02/03/04 | +| 4 | START-TIME | SQL-START-TIME | 元申請の開始時刻(HHMM) | +| 5 | END-TIME | SQL-END-TIME | 元申請の終了時刻(HHMM) | +| 6 | APPL-ID | SQL-APPL-ID | APPLICATION_ID | +| 7 | FILLER | SPACE | 45B |