<mxfile host="app.diagrams.net" modified="2026-04-22T09:15:00.000Z" agent="Codex" version="25.0.2">
  <diagram id="attendance-spl-payroll-engine" name="Attendance-SPL-Payroll Engine">
    <mxGraphModel dx="1788" dy="980" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="2400" pageHeight="1800" math="0" shadow="0">
      <root>
        <mxCell id="0" />
        <mxCell id="1" parent="0" />

        <mxCell id="title" value="Attendance Review V2 -> SPL -> Payroll Engine" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=24;fontStyle=1;fontColor=#0f172a;" vertex="1" parent="1">
          <mxGeometry x="40" y="20" width="650" height="30" as="geometry" />
        </mxCell>
        <mxCell id="subtitle" value="Detailed operational flow: ingest log, detect attendance, approve review, generate SPL candidate, bayar lewat payroll / separate payout." style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=12;fontColor=#475569;" vertex="1" parent="1">
          <mxGeometry x="40" y="52" width="1100" height="20" as="geometry" />
        </mxCell>

        <mxCell id="lane1" value="A. Source &amp; Ingestion" style="swimlane;html=1;rounded=1;fillColor=#f8fafc;strokeColor=#cbd5e1;fontSize=16;fontStyle=1;startSize=32;" vertex="1" parent="1">
          <mxGeometry x="40" y="100" width="2280" height="170" as="geometry" />
        </mxCell>
        <mxCell id="lane2" value="B. Planning &amp; Detection Engine" style="swimlane;html=1;rounded=1;fillColor=#f0fdf4;strokeColor=#bbf7d0;fontSize=16;fontStyle=1;startSize=32;" vertex="1" parent="1">
          <mxGeometry x="40" y="290" width="2280" height="210" as="geometry" />
        </mxCell>
        <mxCell id="lane3" value="C. Review &amp; Approval Decision" style="swimlane;html=1;rounded=1;fillColor=#eff6ff;strokeColor=#bfdbfe;fontSize=16;fontStyle=1;startSize=32;" vertex="1" parent="1">
          <mxGeometry x="40" y="520" width="2280" height="230" as="geometry" />
        </mxCell>
        <mxCell id="lane4" value="D. SPL Candidate &amp; Overtime Path" style="swimlane;html=1;rounded=1;fillColor=#fffbeb;strokeColor=#fde68a;fontSize=16;fontStyle=1;startSize=32;" vertex="1" parent="1">
          <mxGeometry x="40" y="770" width="2280" height="230" as="geometry" />
        </mxCell>
        <mxCell id="lane5" value="E. Payroll, Separate Payout &amp; Output" style="swimlane;html=1;rounded=1;fillColor=#faf5ff;strokeColor=#d8b4fe;fontSize=16;fontStyle=1;startSize=32;" vertex="1" parent="1">
          <mxGeometry x="40" y="1020" width="2280" height="250" as="geometry" />
        </mxCell>

        <mxCell id="n1" value="Mesin / Device Log&#xa;importMachineLog()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#64748b;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="90" y="150" width="200" height="60" as="geometry" />
        </mxCell>
        <mxCell id="n2" value="API Publik / Server lain&#xa;syncPublicApiLog()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#64748b;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="340" y="150" width="210" height="60" as="geometry" />
        </mxCell>
        <mxCell id="n3" value="Manual Log / Repair Mapping&#xa;storeLog() / repairLogMapping()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#64748b;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="610" y="150" width="240" height="60" as="geometry" />
        </mxCell>
        <mxCell id="n4" value="Raw Attendance Logs&#xa;terkumpul di modul Attendance Review" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e2e8f0;strokeColor=#475569;fontSize=13;fontStyle=1;" vertex="1" parent="1">
          <mxGeometry x="930" y="145" width="250" height="70" as="geometry" />
        </mxCell>
        <mxCell id="n5" value="Queue / Health Control&#xa;queueHealth() / queueProcessOnce()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#64748b;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="1260" y="150" width="230" height="60" as="geometry" />
        </mxCell>

        <mxCell id="n6" value="Referensi Planning&#xa;- Master Karyawan&#xa;- Shift Schedule&#xa;- Profil Bulan assignment&#xa;- Kalender&#xa;- Pembulatan / Perkalian" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#16a34a;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="90" y="350" width="280" height="105" as="geometry" />
        </mxCell>
        <mxCell id="n7" value="runDetection()&#xa;buat job deteksi attendance" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dcfce7;strokeColor=#15803d;fontSize=13;fontStyle=1;" vertex="1" parent="1">
          <mxGeometry x="450" y="365" width="220" height="60" as="geometry" />
        </mxCell>
        <mxCell id="n8" value="Detection Job Runtime&#xa;- mapping punch&#xa;- cocokkan shift&#xa;- telat / pulang / jam kerja&#xa;- holiday / weekend / auto OT mode" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#16a34a;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="750" y="340" width="300" height="110" as="geometry" />
        </mxCell>
        <mxCell id="n9" value="rebuildPlanning()&#xa;rebuild fallback schedule jika rule berubah" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#16a34a;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="1120" y="365" width="250" height="60" as="geometry" />
        </mxCell>
        <mxCell id="n10" value="Attendance Daily Review&#xa;reviewData() / calculationData()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dcfce7;strokeColor=#15803d;fontSize=13;fontStyle=1;" vertex="1" parent="1">
          <mxGeometry x="1450" y="355" width="250" height="80" as="geometry" />
        </mxCell>

        <mxCell id="n11" value="Operator Review V2&#xa;lihat review, calculation detail, history" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#2563eb;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="90" y="595" width="240" height="70" as="geometry" />
        </mxCell>
        <mxCell id="n12" value="Manual Adjustment&#xa;manualUpdateReviewTime()&#xa;approveOfflineLogs() / rejectOfflineLogs()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#2563eb;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="390" y="585" width="290" height="90" as="geometry" />
        </mxCell>
        <mxCell id="n13" value="Approve / Unapprove Review&#xa;approveReview() / approveReviewsByDate()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dbeafe;strokeColor=#1d4ed8;fontSize=13;fontStyle=1;" vertex="1" parent="1">
          <mxGeometry x="760" y="595" width="270" height="70" as="geometry" />
        </mxCell>
        <mxCell id="n14" value="Decision:&#xa;Apakah hasil review cukup langsung ke payroll?" style="rhombus;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#2563eb;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="1110" y="575" width="200" height="110" as="geometry" />
        </mxCell>
        <mxCell id="n15" value="Langsung masuk komponen payroll attendance&#xa;(jam kerja, hadir, telat, dll)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#2563eb;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="1390" y="595" width="280" height="70" as="geometry" />
        </mxCell>
        <mxCell id="n16" value="Need overtime / special handling&#xa;lanjut ke jalur SPL / separate payout" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dbeafe;strokeColor=#1d4ed8;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="1750" y="595" width="280" height="70" as="geometry" />
        </mxCell>

        <mxCell id="n17" value="SPL Candidate Sources&#xa;- reviewCandidateData()&#xa;- bulkCreateAutomaticSpl()&#xa;- bulkCreateAutoOtHolidayWeekendSpl()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d97706;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="90" y="835" width="320" height="90" as="geometry" />
        </mxCell>
        <mxCell id="n18" value="reviewCandidateGenerate()&#xa;buat draft SPL massal per hasil review" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fef3c7;strokeColor=#b45309;fontSize=13;fontStyle=1;" vertex="1" parent="1">
          <mxGeometry x="490" y="845" width="260" height="70" as="geometry" />
        </mxCell>
        <mxCell id="n19" value="SPL Draft / Import Manual&#xa;store() / bulkUpdate() / importCommit()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d97706;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="830" y="845" width="270" height="70" as="geometry" />
        </mxCell>
        <mxCell id="n20" value="Submit &amp; Approval SPL&#xa;submit() / bulkSubmit() / approve() / bulkApprove()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fef3c7;strokeColor=#b45309;fontSize=13;fontStyle=1;" vertex="1" parent="1">
          <mxGeometry x="1180" y="835" width="290" height="90" as="geometry" />
        </mxCell>
        <mxCell id="n21" value="Decision:&#xa;Dibayar lewat payroll atau separate payout?" style="rhombus;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d97706;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="1545" y="825" width="220" height="110" as="geometry" />
        </mxCell>
        <mxCell id="n22" value="Separate Payout Queue&#xa;separatePayoutData() / markPaidSeparate()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d97706;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="1845" y="845" width="280" height="70" as="geometry" />
        </mxCell>

        <mxCell id="n23" value="Penggajian.data()&#xa;bangun dataset payroll per assignment / cycle" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f3e8ff;strokeColor=#7e22ce;fontSize=13;fontStyle=1;" vertex="1" parent="1">
          <mxGeometry x="90" y="1095" width="290" height="80" as="geometry" />
        </mxCell>
        <mxCell id="n24" value="Payroll Engine Input&#xa;- attendance approved&#xa;- SPL approved&#xa;- profile bulan&#xa;- komponen pendapatan / potongan&#xa;- BPJS / tax / overrides" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#9333ea;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="450" y="1085" width="320" height="100" as="geometry" />
        </mxCell>
        <mxCell id="n25" value="Cycle &amp; Payment Control&#xa;updateCycle() / updateCycleBulk()&#xa;markPaid() / markPaidBulk()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#9333ea;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="850" y="1095" width="300" height="80" as="geometry" />
        </mxCell>
        <mxCell id="n26" value="Output Payroll&#xa;exportExcel() / exportPdf() / detail() / slipPrint()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f3e8ff;strokeColor=#7e22ce;fontSize=13;fontStyle=1;" vertex="1" parent="1">
          <mxGeometry x="1230" y="1095" width="300" height="80" as="geometry" />
        </mxCell>
        <mxCell id="n27" value="Tax &amp; THR Output&#xa;taxProof() / thrProgressiveReport() / ThrController" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#9333ea;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="1600" y="1095" width="300" height="80" as="geometry" />
        </mxCell>
        <mxCell id="n28" value="Final Consumer&#xa;HR, Payroll, Finance, Management" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ede9fe;strokeColor=#6d28d9;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="1980" y="1105" width="240" height="60" as="geometry" />
        </mxCell>

        <mxCell id="note1" value="Kunci engine: hasil Attendance Review yang belum approved sebaiknya belum dibawa menjadi basis final payroll." style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff7ed;strokeColor=#fb923c;fontColor=#7c2d12;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="1770" y="360" width="430" height="70" as="geometry" />
        </mxCell>
        <mxCell id="note2" value="SPL special dapat keluar dari jalur payroll normal dan dibayar lewat separate payout." style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff7ed;strokeColor=#fb923c;fontColor=#7c2d12;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="1760" y="1135" width="460" height="70" as="geometry" />
        </mxCell>

        <mxCell id="e1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#475569;endArrow=block;endFill=1;" edge="1" parent="1" source="n1" target="n4"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#475569;endArrow=block;endFill=1;" edge="1" parent="1" source="n2" target="n4"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#475569;endArrow=block;endFill=1;" edge="1" parent="1" source="n3" target="n4"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#475569;dashed=1;endArrow=block;endFill=1;" edge="1" parent="1" source="n5" target="n7"><mxGeometry relative="1" as="geometry" /></mxCell>

        <mxCell id="e5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#16a34a;endArrow=block;endFill=1;" edge="1" parent="1" source="n4" target="n7"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#16a34a;endArrow=block;endFill=1;" edge="1" parent="1" source="n6" target="n8"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#16a34a;endArrow=block;endFill=1;" edge="1" parent="1" source="n7" target="n8"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#16a34a;endArrow=block;endFill=1;" edge="1" parent="1" source="n9" target="n8"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#16a34a;endArrow=block;endFill=1;" edge="1" parent="1" source="n8" target="n10"><mxGeometry relative="1" as="geometry" /></mxCell>

        <mxCell id="e10" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#2563eb;endArrow=block;endFill=1;" edge="1" parent="1" source="n10" target="n11"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e11" value="jika perlu koreksi" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#2563eb;endArrow=block;endFill=1;fontSize=11;" edge="1" parent="1" source="n11" target="n12"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e12" value="final approve" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#2563eb;endArrow=block;endFill=1;fontSize=11;" edge="1" parent="1" source="n12" target="n13"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e13" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#2563eb;endArrow=block;endFill=1;" edge="1" parent="1" source="n13" target="n14"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e14" value="Ya" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#2563eb;endArrow=block;endFill=1;fontSize=11;" edge="1" parent="1" source="n14" target="n15"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e15" value="Perlu lembur / special" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#2563eb;endArrow=block;endFill=1;fontSize=11;" edge="1" parent="1" source="n14" target="n16"><mxGeometry relative="1" as="geometry" /></mxCell>

        <mxCell id="e16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#d97706;endArrow=block;endFill=1;" edge="1" parent="1" source="n16" target="n17"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#d97706;endArrow=block;endFill=1;" edge="1" parent="1" source="n17" target="n18"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e18" value="atau input manual/import" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#d97706;endArrow=block;endFill=1;fontSize=11;" edge="1" parent="1" source="n17" target="n19"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#d97706;endArrow=block;endFill=1;" edge="1" parent="1" source="n18" target="n19"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e20" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#d97706;endArrow=block;endFill=1;" edge="1" parent="1" source="n19" target="n20"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#d97706;endArrow=block;endFill=1;" edge="1" parent="1" source="n20" target="n21"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e22" value="Payroll" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#d97706;endArrow=block;endFill=1;fontSize=11;" edge="1" parent="1" source="n21" target="n24"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e23" value="Separate payout" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#d97706;endArrow=block;endFill=1;fontSize=11;" edge="1" parent="1" source="n21" target="n22"><mxGeometry relative="1" as="geometry" /></mxCell>

        <mxCell id="e24" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#9333ea;endArrow=block;endFill=1;" edge="1" parent="1" source="n15" target="n23"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e25" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#9333ea;endArrow=block;endFill=1;" edge="1" parent="1" source="n23" target="n24"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e26" value="SPL approved" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#9333ea;endArrow=block;endFill=1;fontSize=11;" edge="1" parent="1" source="n20" target="n24"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e27" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#9333ea;endArrow=block;endFill=1;" edge="1" parent="1" source="n24" target="n25"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#9333ea;endArrow=block;endFill=1;" edge="1" parent="1" source="n25" target="n26"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#9333ea;endArrow=block;endFill=1;" edge="1" parent="1" source="n24" target="n27"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e30" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#9333ea;endArrow=block;endFill=1;" edge="1" parent="1" source="n22" target="n28"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e31" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#9333ea;endArrow=block;endFill=1;" edge="1" parent="1" source="n26" target="n28"><mxGeometry relative="1" as="geometry" /></mxCell>
        <mxCell id="e32" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#9333ea;endArrow=block;endFill=1;" edge="1" parent="1" source="n27" target="n28"><mxGeometry relative="1" as="geometry" /></mxCell>
      </root>
    </mxGraphModel>
  </diagram>
</mxfile>
