import dto.Zan01Rec; import dto.Zan05Rec; import dto.ZanmsgacPar; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; /** * ============================================================ * 銆怌OBOL鈫扟ava銆慞ROGRAM-ID. ZAN03CHK 鈫?绫?Zan03ChkMain * ============================================================ * 鎵撳埢鏅傞枔鐓у悎: OVT-NODUP(R01) 銇?PUNCH(R02) 銈掋偔銉?绀惧摗+鐢宠珛鏃?銇х獊鍚堛€? * 涓€鑷淬仐鏅傞枔甯亴鍑哄嫟銆滈€€鍕ょ瘎鍥插唴 鈫?OVT-TYPE浠樺姞銇椼仸 OVT-CHECKED(W01)銆? * 绡勫洸澶栥伨銇熴伅涓嶄竴鑷?鈫?ERROR-LOG(W02) 銈儐銈淬儶03銆? * 浼戞棩鍒ゅ畾銇?R03(浼戞棩銉曘偂銈ゃ儷) 銇ц銇嗐€? * 鈥籞AN03 銇?SUB01DAT 鏈娇鐢?FUNCTION CURRENT-DATE)銆傝ō瑷堟浉婧栨嫚銆? */ public class Zan03ChkMain { private static final String PRGIDX = "ZAN03CHK"; private static final int CNS_MSGSTR = 1; private static final int CNS_MSGFIN = 2; private static final int CNS_MSGIINKES = 6; private static final int CNS_MSGOUTKES = 7; private static final int CNS_MSGKEYINF = 33; private static final int CNS_KN0002 = 2; private static final int CNS_ERR_CAT03 = 3; private static final String OVT_W = "W"; private static final String OVT_H = "H"; private static final String HIGH = "zzzzzzzzzzzzzzzz"; // 16脳'z' = HIGH-VALUE private static final String R01_PATH = "data/ZAN03R01.txt"; private static final String R02_PATH = "data/ZAN03R02.txt"; private static final String R03_PATH = "data/ZAN03R03.txt"; private static final String W01_PATH = "data/ZAN03W01.txt"; private static final String W02_PATH = "data/ZAN03W02.txt"; private long cunR01Inn = 0; private long cunR02Inn = 0; private long cunR03Inn = 0; private long cunW01Out = 0; private long cunW02Out = 0; private String wrkR01Eof = "0"; private String wrkR02Eof = "0"; private String wrkR03Eof = "0"; private String r01Line = ""; private String r02Line = ""; private String wrkR01Key = ""; private String wrkR02Key = HIGH; private String wrkOvtTypeSet = OVT_W; private final ZanmsgacPar m00 = new ZanmsgacPar(); private Zan01Rec r01Rec = new Zan01Rec(); // R02 銈ゃ兂銉┿偆銉抽爡鐩? // R02 インライン項目 private String r02EmpId = ""; private String r02Date = ""; private String r02TimeIn = ""; private String r02TimeOut = ""; // 浼戞棩銉嗐兗銉栥儷 private final List holidayTable = new ArrayList<>(); private BufferedReader r01In; private BufferedReader r02In; private BufferedReader r03In; private BufferedWriter w01Out; private BufferedWriter w02Out; private static final class Holiday { final String date; final String flg; Holiday(final String d, final String f) { this.date = d; this.flg = f; } } public static void main(final String[] args) { new Zan03ChkMain().run(); } private void run() { initProc(); while (!"1".equals(wrkR01Eof)) { majProc(); } stpProc(); } private void initProc() { msgOut(CNS_MSGSTR, "", ""); msgCompiled(); wrkR01Eof = "0"; wrkR02Eof = "0"; wrkR03Eof = "0"; try { r01In = FileIo.openReader(R01_PATH); r02In = FileIo.openReader(R02_PATH); r03In = FileIo.openReader(R03_PATH); w01Out = FileIo.openWriter(W01_PATH); w02Out = FileIo.openWriter(W02_PATH); } catch (IOException e) { throw new RuntimeException("FILE OPEN ERROR", e); } // 浼戞棩銉曘偂銈ゃ儷瑾炯 holidayLoad(); readR01(); readR02(); } private void holidayLoad() { try { String line; while ((line = r03In.readLine()) != null) { cunR03Inn++; String date = line.length() >= 8 ? line.substring(0, 8).trim() : ""; String flg = line.length() >= 9 ? line.substring(8, 9) : " "; holidayTable.add(new String[]{date, flg}); } wrkR03Eof = "1"; } catch (IOException e) { throw new RuntimeException("READ R03 ERROR", e); } } private void readR01() { try { String line = r01In.readLine(); if (line == null) { wrkR01Eof = "1"; } else { r01Line = line; r01Rec.fromRecordLine(line); wrkR01Key = pad8(r01Rec.getEmpId()) + pad8(r01Rec.getApplDate()); cunR01Inn++; } } catch (IOException e) { throw new RuntimeException("READ R01 ERROR", e); } } private void readR02() { try { String line = r02In.readLine(); if (line == null) { wrkR02Eof = "1"; wrkR02Key = HIGH; } else { r02Line = line; r02EmpId = line.length() >= 8 ? line.substring(0, 8).trim() : ""; r02Date = line.length() >= 16 ? line.substring(8, 16).trim() : ""; r02TimeIn = line.length() >= 20 ? line.substring(16, 20).trim() : ""; r02TimeOut = line.length() >= 24 ? line.substring(20, 24).trim() : ""; wrkR02Key = pad8(r02EmpId) + pad8(r02Date); cunR02Inn++; } } catch (IOException e) { throw new RuntimeException("READ R02 ERROR", e); } } private void majProc() { int cmp = wrkR01Key.compareTo(wrkR02Key); if (cmp < 0) { noMatchProc(); readR01(); } else if (cmp == 0) { matchProc(); readR01(); } else { readR02(); } } private void noMatchProc() { Zan05Rec rec = new Zan05Rec(); rec.setErrCategory(String.valueOf(CNS_ERR_CAT03)); rec.setErrDetail(r01Rec.getEmpId() + "/" + r01Rec.getApplDate()); try { w02Out.write(rec.toRecordLine()); w02Out.newLine(); cunW02Out++; } catch (IOException e) { throw new RuntimeException("WRITE W02 ERROR", e); } } private void matchProc() { int r01Start = parseInt(r01Rec.getStartTime(), 0); int r01End = parseInt(r01Rec.getEndTime(), 0); int punchIn = parseInt(r02TimeIn, 0); int punchOut = parseInt(r02TimeOut, 0); if (r01Start >= punchIn && r01End <= punchOut) { setOvtProc(); try { w01Out.write(r01Rec.toRecordLine()); w01Out.newLine(); cunW01Out++; } catch (IOException e) { throw new RuntimeException("WRITE W01 ERROR", e); } } else { Zan05Rec rec = new Zan05Rec(); rec.setErrCategory(String.valueOf(CNS_ERR_CAT03)); rec.setErrDetail(r01Rec.getEmpId() + "/" + r01Rec.getApplDate() + "/" + r01Rec.getStartTime() + "-" + r01Rec.getEndTime()); try { w02Out.write(rec.toRecordLine()); w02Out.newLine(); cunW02Out++; } catch (IOException e) { throw new RuntimeException("WRITE W02 ERROR", e); } } } private void setOvtProc() { wrkOvtTypeSet = OVT_W; String date = r01Rec.getApplDate(); for (String[] h : holidayTable) { if (h[0].equals(date)) { // 休日フラグ: COBOL データ慣習は '1'、設計上は 'H' も可。両方受容して運用互換を確保。 if (OVT_H.equals(h[1]) || "1".equals(h[1])) { wrkOvtTypeSet = OVT_H; } break; } } r01Rec.setOvtType(wrkOvtTypeSet); } private void stpProc() { try { if (r01In != null) { r01In.close(); } if (r02In != null) { r02In.close(); } if (r03In != null) { r03In.close(); } if (w01Out != null) { w01Out.close(); } if (w02Out != null) { w02Out.close(); } } catch (IOException e) { throw new RuntimeException("CLOSE ERROR", e); } msgInkCnt("ZAN03R01", cunR01Inn); msgInkCnt("ZAN03R02", cunR02Inn); msgInkCnt("ZAN03R03", cunR03Inn); msgOutCnt("ZAN03W01", cunW01Out); msgOutCnt("ZAN03W02", cunW02Out); msgOut(CNS_MSGFIN, "", ""); } private void msgOut(final int code, final String p1, final String p2) { m00.reset(); m00.setM00MsgCod(code); m00.setM00Umkdats2201(p1); m00.setM00Umkdats2202(p2); m00.setM00Umkdats2203(String.valueOf(CNS_KN0002)); m00.setM00Umkdats2204(String.valueOf(CNS_KN0002)); m00.setM00Umkdats2205(PRGIDX); Sub02MsgSub.execute(m00); } private void msgCompiled() { m00.reset(); m00.setM00MsgCod(CNS_MSGKEYINF); m00.setM00Umkdats2201("2026-06-14"); m00.setM00Umkdats2202("COMPILED"); m00.setM00Umkdats2203(String.valueOf(CNS_KN0002)); m00.setM00Umkdats2204(String.valueOf(CNS_KN0002)); m00.setM00Umkdats2205(PRGIDX); Sub02MsgSub.execute(m00); } private void msgInkCnt(final String dd, final long cnt) { m00.reset(); m00.setM00MsgCod(CNS_MSGIINKES); m00.setM00Umkdats2201(dd); m00.setM00Umkdats2202(String.valueOf(cnt)); m00.setM00Umkdats2203(String.valueOf(CNS_KN0002)); m00.setM00Umkdats2204(String.valueOf(CNS_KN0002)); m00.setM00Umkdats2205(PRGIDX); Sub02MsgSub.execute(m00); } private void msgOutCnt(final String dd, final long cnt) { m00.reset(); m00.setM00MsgCod(CNS_MSGOUTKES); m00.setM00Umkdats2201(dd); m00.setM00Umkdats2202(String.valueOf(cnt)); m00.setM00Umkdats2203(String.valueOf(CNS_KN0002)); m00.setM00Umkdats2204(String.valueOf(CNS_KN0002)); m00.setM00Umkdats2205(PRGIDX); Sub02MsgSub.execute(m00); } private String pad8(final String s) { if (s == null) { return " "; } if (s.length() >= 8) { return s.substring(0, 8); } StringBuilder sb = new StringBuilder(s); while (sb.length() < 8) { sb.append(' '); } return sb.toString(); } private int parseInt(final String s, final int def) { if (s == null) { return def; } String t = s.trim(); if (t.isEmpty()) { return def; } try { return Integer.parseInt(t); } catch (NumberFormatException e) { return def; } } }