Skip to content

Routing Overdue

Kode report: routing_01. Membuka modul routing dengan show=report&print=due; routing_handler_print.php meng-include routing_handler_print_dueroute.php, 614 baris, memakai $pdo. Satu baris per penerima sebuah routing (ts_map_routing_to), dengan dokumen routing-nya, aksi yang diminta dari orang itu, due date dan berapa hari tersisa. Walau namanya begitu, report ini tidak terbatas pada baris overdue: filter default-nya Route Status = open, dan kolom Days Remaining adalah tempat "overdue" tampil sebagai angka negatif.

Cara halaman ini diverifikasi

Ditelusuri di master pada 2026-09-06 dan dibandingkan dengan big five dan KTP. Screenshot dari inact-ktp.eris.place, project SNS, Template A dengan Record Grouping.

Form filter

Routing Overdue, form filter
Routing Overdue, form filter · click to enlarge

view=custom merender routing_print_due_custom.htm:

KontrolFieldEfek
Projectprojectdaftarnya dari getProjectPersonByResource(): semua project aktif untuk admin, project milik user untuk yang lain
Show All Datacondition[]=show_allmembuang semua kondisi di bawah; pilihan template tetap berlaku
Show Only Latest Revisiononly_latest_revmenyimpan, per nomor dokumen, routing dengan rout_id tertinggi yang file utamanya dokumen itu. Ini "routing terakhir", bukan "revisi terakhir"
Conditionsfield[], operator[], what[]baris default: Route Status equals open. Field berupa nama kolom mentah (r.rout_status, rout_doc_number, rt.rout_indicate, rout_due_date, ...); add search field menambah baris, semua digabung AND
Template A / B / Ccondition[]=A dst.set kolom, dari json/table_header.json
Record Groupingorder[]kalau ada, nilai berulang dikosongkan sehingga baris terbaca sebagai grup
Presetpreset, nameset kondisi tersimpan; disimpan oleh act=save_preset di routing_handler_post.php, namanya dicetak di judul

Kondisi tanggal (rout_due_date, rout_date, rt.rout_resp_date, rt.rout_initials) dikonversi dari format tanggal INACT; nilai tanggal kosong berubah menjadi ISNULL(field), sintaks MySQL yang gagal di PostgreSQL dan SQL Server. Field originator memaksa operator menjadi =.

Query-nya

Satu SELECT atas ts_map_routing_to rt, di-join ke ts_routing r, author (ts_org_person), perusahaan originator, resource dan person penerima, ts_routing_action_indicated, dan subquery atas ts_map_routing_file yang mengembalikan file pertama tiap routing (rout_type tidak diperiksa; map_id terendah menang, biasanya dokumen utama). Difilter r.rout_project_code = <project>, daftar revisi terakhir dan kondisi.

Kolom hitungan per baris adalah Days Remaining. Ia membandingkan dua tanggal saja:

  • due date penerima, ts_map_routing_to.rout_due_date, kolom Due Date di baris yang sama (tiap penerima punya due date sendiri; routing-nya sendiri tidak punya due date), dan
  • hari ini, jam server database saat report dijalankan. Bukan tanggal sign-off, bukan tanggal terima.
Days Remaining = rout_due_date − hari ini        (dalam hari bulat)

Jadi +3 berarti due date tiga hari lagi, 0 berarti jatuh tempo hari ini, dan -222 berarti due date sudah lewat 222 hari. Angkanya hanya dicetak selama Action Taken baris itu masih Open; begitu penerima sudah sign-off, selnya kosong, apa pun tanggalnya.

Di screenshot Template B report dijalankan pada 07/Sep/2026. Baris dengan Due Date 28/Jan/2026 menampilkan -222: 28 Januari sampai 7 September adalah 222 hari, dan barisnya masih Open, jadi reviewer terlambat 222 hari. Baris dengan Due Date 15/Aug/2024 tidak menampilkan apa-apa karena sudah sign-off.

Per driver:

DriverEkspresiTanda
MySQLDATEDIFF(rt.rout_due_date, now())due date dikurangi hari ini: positif = hari tersisa, negatif = hari terlambat
PostgreSQLEXTRACT(DAY FROM (rt.rout_due_date - now()))sama
SQL ServerDATEDIFF(DAY, rt.rout_due_date, GETDATE())hari ini dikurangi due date, jadi tandanya terbalik: positif = hari terlambat

Urutan diturunkan dari template: setiap kolom setelah yang pertama, kecuali Routing Sequence, menjadi kunci ORDER BY sesuai urutan template. Di MySQL handler menjalankan SET sql_mode = '' lebih dulu, karena subquery file memakai GROUP BY longgar. Di SQL Server subquery ditulis ulang dengan ROW_NUMBER() dan rout_sequence_no diformat dengan desimal koma. SQL lengkapnya ditulis ke error log PHP di setiap eksekusi (error_log(print_r($sql, true))).

Kolomnya

Tiga template, dari table_header.json. Ini bukan tiga set kolom dari satu daftar: template juga menentukan urutan sort dan pengelompokan, karena setiap kolom setelah yang pertama menjadi kunci ORDER BY sesuai urutan template, dan Record Grouping mengosongkan kolom-kolom depan saat berulang. Jadi baris yang sama terbaca sebagai tiga report berbeda.

Template ATemplate BTemplate C
Pertanyaan yang dijawabBagaimana keadaan tiap routing?Apa yang ada di meja tiap orang?Bagaimana tiap routing bergerak lewat sequence-nya?
Diurutkan dan dikelompokkan perrouting (Route ID, judul, status, dokumen, rev, author), lalu penerima urut sequenceorang (Routing To), lalu action, due daterouting, lalu penerima urut sequence
Dikosongkan saat berulangtujuh kolom routing, dicetak sekali per routingempat kolom orang (Routing To, Action Indicated, Due Date, Days Remaining), dicetak sekali per orang dan actiontujuh kolom routing, seperti A
KolomNo, Route ID, Route Title, Route Status, Doc.No., Rev, Author, Routing To, Action Indicated, Due Date, Action Taken, Response, Days RemainingNo, Routing To, Action Indicated, Due Date, Days Remaining, Action Taken, Response, Route ID, Route Title, Route Status, Doc No, Rev, AuthorA plus Routing Sequence, Receive Date (rout_initials) dan Sign-Off Date (rout_resp_date)
Dipakai untukdaftar overdue mingguan per dokumenmengejar reviewer: satu blok per orang, baris overdue negatif di Days Remainingaudit: kapan tiap sequence mulai, kapan tiap orang sign-off
Template A: satu blok per routing, penerimanya di bawah urut sequence
Template A: satu blok per routing, penerimanya di bawah urut sequence · click to enlarge
Template B: satu blok per orang; kolom routing pindah ke kanan, dan Days Remaining menunjukkan seberapa terlambat tiap item yang masih terbuka
Template B: satu blok per orang; kolom routing pindah ke kanan, dan Days Remaining menunjukkan seberapa terlambat tiap item yang masih terbuka · click to enlarge
Template C: Template A dengan Routing Sequence, Receive Date dan Sign-Off Date, jejak audit tiap routing
Template C: Template A dengan Routing Sequence, Receive Date dan Sign-Off Date, jejak audit tiap routing · click to enlarge
KolomSumber
Routing Toresource_name (person_id), dibangun dengan CONCAT di query; resource_name (No user) kalau resource tidak punya person. Di Jadestone kurungnya berisi nama person, bukan id, lihat perbedaan antar instance
Action Indicatedts_routing_action_indicated.action_desc
Action Takenrout_status_resp dipetakan lewat $_ROUT_STATUS: N Open, 1 re-Route, 2 Route as New, 3 Return, 4 Sign Off, 5 Closed Without Action
Responserout_response, teks bebas atau result code yang dimasukkan saat sign-off
Days Remainingrout_due_date − hari ini untuk baris penerima itu, lihat di atas; hanya dicetak selama Action Taken masih Open (rout_status_resp = 'N'); baris yang sudah sign-off tidak menampilkan apa-apa
Routing Sequencerout_sequence_no, langkah tempat penerima berada; semua penerima di nomor yang sama dikirim bersamaan
Receive Daterout_initials, tanggal mulai yang direncanakan untuk langkah penerima, lihat di bawah. Walau labelnya begitu, ini bukan hari routing sampai di inbox
Due Daterout_due_date, due date milik penerima sendiri, dihitung dari Receive Date
Sign-Off Daterout_resp_date, hari penerima menjawab; kosong selama Open

Hanya Jadestone: Issued Status setelah Rev

Jadestone, Template A di project AAL-VS: Issued Status berada di antara Rev dan Uploaded By
Jadestone, Template A di project AAL-VS: Issued Status berada di antara Rev dan Uploaded By · click to enlarge

Ditambahkan oleh INA27-299 (Done) ke ketiga template, di keluaran HTML dan ekspor Excel. Nilainya ts_issued_status.issued_desc untuk issued_code file routing, di-join pada project report (LEFT JOIN ts_issued_status i ON i.issued_code = rf.issued_code AND i.project_id = <project>), jadi terbaca Issued for Review, bukan IFR, teks yang sama dengan yang ditampilkan Inbox. Routing yang file-nya tidak punya issued code mencetak kosong.

Rev, Issued Status dan Uploaded By di Template A Jadestone
Rev, Issued Status dan Uploaded By di Template A Jadestone · click to enlarge

Dua perubahan ikutan: Record Grouping di Template A dan C sekarang mengosongkan delapan kolom berulang, bukan tujuh, karena kolom baru ini setingkat dokumen dan harus ikut terlipat dengan routing-nya; dan daftar field filter mendapat Issued Status (rf.issued_code). Master dan fork lain tidak punya kolom ini.

Receive Date dan Due Date, dan kapan berubah

Keduanya kolom date di ts_map_routing_to, satu pasang per penerima, dan keduanya ditulis sekali, saat baris penerima dibuat. Tidak ada yang menulis ulang setelahnya: mengirim sequence berikutnya hanya membalik rout_is_oninbox, dan sign-off hanya menulis rout_resp_date dan rout_status_resp. Tidak ada UPDATE ... SET rout_initials di mana pun di modul routing.

Cara pengisiannya bergantung pada asal barisnya:

Baris dibuat olehReceive Date (rout_initials)Due Date (rout_due_date)
Upload dari Distribution Matrixsequence 1: hari upload, digeser keluar dari akhir pekan oleh get_santos_startdate(). Tiap sequence berikutnya: sehari setelah due date sequence sebelumnyaReceive Date plus Review Time project untuk issued status itu (ts_workingdays), melewati akhir pekan dan ts_holiday, oleh get_santos_duedate() di business_day_santos.inc.php. Baris dengan action yang sama menyalin pasangan dari baris pertama, jadi setiap reviewer di satu langkah berbagi tanggal
Add di Routing Slip (routing_handler_ajax.php)hari initanggal routing plus hari review; kalau routing sudah lewat jatuh tempo, hari ini plus satu hari
Submit Routing dari form (routing_handler_post.php)apa pun yang diketik user di sel Start Date grid Routing Toapa pun yang diketik user di Due Date

Jadi seluruh jadwal sebuah routing disusun di hari pertama, sequence demi sequence, dari review time. Kalau reviewer 1 sign-off terlambat, Receive Date dan Due Date reviewer 2 tidak digeser: reviewer 2 menerima routing di inbox-nya setelah Receive Date yang direncanakan, dan Days Remaining untuk reviewer 2 dihitung terhadap due date yang mungkin sudah dekat atau lewat. Itulah angka yang ditampilkan report ini, dan itu sebabnya reviewer pertama yang terlambat membuat setiap langkah berikutnya tampak overdue.

Routing Slip menampilkan dua kolom yang sama sebagai Start Date dan Due Date; report mengganti nama yang pertama menjadi Receive Date. Form filter mendaftarnya dengan nama lamanya, Sequence Start Date.

Action Taken, Response dan Days Remaining; yang terakhir kosong begitu penerima sudah sign-off
Action Taken, Response dan Days Remaining; yang terakhir kosong begitu penerima sudah sign-off · click to enlarge

Record grouping

Dengan order[] ada, baris sudah diurutkan per kolom template, dan handler mengosongkan sel yang berulang sehingga tiap routing (Template A dan C, tujuh kolom pertama) atau tiap orang (Template B, empat kolom pertama) dicetak sekali. Barisnya tidak digabung; perubahan di kolom mana pun yang lebih awal memulai grup baru. Tanpa grouping setiap sel dicetak.

Masalah yang diketahui

  • Days Remaining bertanda terbalik di SQL Server. Report Medco terbaca "terlambat" di mana instance MySQL terbaca "tersisa".
  • Latest Revision sebenarnya routing terakhir: rout_id tertinggi per dokumen, revisi apa pun yang dibawanya.
  • Subquery file mengabaikan rout_type; routing yang file pertamanya lampiran mencetak nomor lampiran di Doc.No.
  • Cabang doc_title di loop baris mencetak tanggal sign-off, tetapi tidak ada template yang punya kunci itu, jadi tidak terjangkau. Jangan menambah kolom Doc Title ke table_header.json tanpa memperbaikinya.
  • Setiap eksekusi mencatat SQL ke error log web server.
  • ISNULL(...) untuk kondisi tanggal kosong adalah sintaks MySQL; di PostgreSQL dan SQL Server query-nya gagal.

Perbedaan antar instance

Diperiksa 2026-09-06 dengan diff handler.

InstancePerbedaan
JOTRE (116 baris)Subquery file dan set kolom yang ditulis ulang; database QA-nya memasang entri tunggal yang sama.
KTP (62 baris)Blok filter lebih lama; kolom keluaran identik.
JadestoneINA27-293 (sudah di-merge ke main 2026-09, Ready for deployment): Routing To terbaca Resource Name (Person Name), bukan Resource Name (person_id), di ketiga template, di keluaran HTML dan di ekspor Excel (excel/export_excel.php), karena person id di Jadestone berupa alamat email yang tidak dikenali orang. Dropdown filter Routing To terbaca Person Name (Resource Name) (routmakeFieldValue() di routing.inc.php); nilai yang dikirim tetap resource id, jadi preset tersimpan tetap jalan. Resource Name (No user) tidak berubah. INA27-299 (Done): kolom Issued Status setelah Rev di ketiga template, lihat di atas. Juga punya Routing Overdue Summary sendiri (INA27-296).
Prima Energy (23 baris)Blok filter lebih lama: tanpa field filter Originator (Company / Person) dan Discipline, docdisc_id tidak dibawa di subquery file, dan query hanya menghitung penerima yang masih di inbox (rt.rout_is_oninbox = 1). Dua panggilan iw_mysql_query masih ada; helper-nya melempar exception, jadi jalur itu fatal kalau tercapai. Diperiksa lewat diff pada 2026-09-08, belum ditelusuri.
Timas (19 baris), Medco (3 baris)Kosmetik. Medco menambah report Comment Summary terpisah (print=commentsummary).
Jadestone setelah INA27-293: Routing To terbaca Resource Name (Person Name), di sini Sr. Document Control (Atar Sukamto)
Jadestone setelah INA27-293: Routing To terbaca Resource Name (Person Name), di sini Sr. Document Control (Atar Sukamto) · click to enlarge
Form filter Jadestone: nilai Routing To terbaca Person Name (Resource Name)
Form filter Jadestone: nilai Routing To terbaca Person Name (Resource Name) · click to enlarge

Terkait