Conversation
update three instances across both inpatient and outpatient kasir plugin admin files to use str_repeat for non-breaking space indentation instead of hardcoded HTML sequences, improving maintainability and compatibility
- Add year filter for rekening tahun annual account management page - Rework buku besar general ledger report: add conditional akun column, saldo normal column, opening/closing balance rows, summary statistics, and toggle to show final balances - Fix buku besar print view to pass all required parameters and include summary data - Simplify periode display logic for general ledger print view - Improve cash flow statement calculation and allocation logic - Update balance sheet calculations to use annual opening balances from rekeningtahun table - Add new akun kegiatan dummy data and improved dummy data handling
update the database upgrade script to set manufacture_date and expiration_date columns for mlite_bpjs_emr_device as nullable with default null, and fix SQL syntax by using backticks instead of single quotes for column names
Add print URL generation for health and referral certificates in the backend admin controller, add print action buttons to their respective management tables, fix trailing newlines in template files, and update print styling in the sick certificate view to hide the e-signature button alongside save and print buttons when printing.
…puts Add new menu entry for shift recap report Add new shift recap report page with date range filtering Implement CSV export for shift report data Update existing cashier report to include institution branding header when printing Pass site settings to all report templates for dynamic header content Refactor print JavaScript function to reuse the institution header template
Reviewer's GuideEnhances keuangan reporting (Buku Besar, Cash Flow, Neraca) with year filtering, saldo awal/akhir correctness and summaries, improves dummy data seeding, adds shift recap reporting and printable headers for kasir reports, fixes several schema/upgrade issues, and improves surat listing/printing UX while enabling dev mode explicitly. Sequence diagram for enhanced Buku Besar generation with saldo awal/akhir and summarysequenceDiagram
participant AdminKeuangan as Admin_keuangan
participant DB as Database
participant Template as Template_engine
AdminKeuangan->>AdminKeuangan: getBukuBesar()
AdminKeuangan->>AdminKeuangan: read $_GET[tgl_awal], $_GET[tgl_akhir], $_GET[kd_rek], $_GET[show_saldo_akhir]
AdminKeuangan->>AdminKeuangan: build $sql (detailjurnal + rekening + jurnal)
AdminKeuangan->>DB: db()->pdo()->prepare($sql)
AdminKeuangan->>DB: execute($params)
DB-->>AdminKeuangan: $rows = fetchAll(\PDO::FETCH_ASSOC)
alt kd_rek is set
AdminKeuangan->>DB: db('mlite_rekeningtahun')->where('thn',$tahun)->where('kd_rek',$kd_rek)->oneArray()
DB-->>AdminKeuangan: $saldoAwalRow
AdminKeuangan->>DB: db('mlite_rekening')->where('kd_rek',$kd_rek)->oneArray()
DB-->>AdminKeuangan: $rekeningRow (nm_rek, balance)
AdminKeuangan->>DB: db()->pdo()->prepare($sqlMutasi)
AdminKeuangan->>DB: execute([$kd_rek,$awalTahun,$tgl_awal])
DB-->>AdminKeuangan: $mutasi
AdminKeuangan->>AdminKeuangan: hitung saldo awal + mutasi
AdminKeuangan->>AdminKeuangan: loop $rows, hitung saldo, saldo_normal, saldo_sisi
AdminKeuangan->>AdminKeuangan: optionally append row "Saldo akhir"
AdminKeuangan->>AdminKeuangan: isi summary (total_debet, total_kredit, saldo_akhir_*)
else kd_rek kosong (semua rekening)
AdminKeuangan->>DB: db('mlite_rekeningtahun')->where('thn',$tahun)->toArray()
DB-->>AdminKeuangan: $saldoAwalRows
AdminKeuangan->>DB: db()->pdo()->prepare($sqlMutasiAll)
AdminKeuangan->>DB: execute([$awalTahun,$tgl_awal])
DB-->>AdminKeuangan: mutasi per kd_rek
AdminKeuangan->>AdminKeuangan: kelompokkan $rows by kd_rek
AdminKeuangan->>AdminKeuangan: untuk tiap kd_rek: saldo awal + mutasi, loop transaksi
AdminKeuangan->>AdminKeuangan: optionally append "Saldo akhir" per kd_rek
AdminKeuangan->>AdminKeuangan: akumulasi summary (rekening_count, total_debet, total_kredit, saldo_akhir_d/k, saldo_akhir_net)
end
AdminKeuangan->>DB: db('mlite_rekening')->toArray()
DB-->>AdminKeuangan: $akunrekening
alt action == 'print'
AdminKeuangan->>Template: draw('buku.besar.print.html', bukubesar, kd_rek_filter, show_saldo_akhir, summary)
Template-->>AdminKeuangan: HTML
AdminKeuangan->>AdminKeuangan: echo HTML and exit
else tampilan normal
AdminKeuangan->>Template: draw('buku.besar.html', bukubesar, akunrekening, kd_rek_filter, show_saldo_akhir, tgl_awal, tgl_akhir, summary)
Template-->>AdminKeuangan: HTML
end
Sequence diagram for new kasir rawat jalan shift recap reportingsequenceDiagram
actor Admin as Admin_user
participant KasirRJ as KasirRawatJalan_Admin
participant DB as Database
participant Template as Template_engine
Admin->>KasirRJ: GET anyShiftReport(awal, akhir)
KasirRJ->>KasirRJ: _addHeaderFiles()
KasirRJ->>KasirRJ: tentukan $awal, $akhir (default hari ini)
KasirRJ->>DB: db()->pdo()->prepare(SELECT ... FROM mlite_kasir_shift ...)
KasirRJ->>DB: execute([$awal,$akhir,$awal,$akhir,$awal,$akhir])
DB-->>KasirRJ: $rows = fetchAll(\PDO::FETCH_ASSOC)
KasirRJ->>KasirRJ: $settings = settings('settings')
KasirRJ->>Template: draw('shift.report.html', awal, akhir, rows, settings)
Template-->>KasirRJ: HTML
KasirRJ-->>Admin: halaman Rekap Shift Kasir
Admin->>KasirRJ: GET anyShiftReportExport(awal, akhir)
KasirRJ->>DB: db()->pdo()->prepare(SELECT ... FROM mlite_kasir_shift ...)
KasirRJ->>DB: execute([$awal,$akhir,$awal,$akhir,$awal,$akhir])
DB-->>KasirRJ: cursor rows
KasirRJ->>KasirRJ: header('Content-Type: text/csv')
KasirRJ->>KasirRJ: echo CSV header
KasirRJ->>KasirRJ: loop fetch(\PDO::FETCH_ASSOC) echo baris CSV
KasirRJ-->>Admin: file rekap_shift_kasir.csv untuk diunduh
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- In
Admin::getBukuBesar()(branch withoutkd_rekfilter), you perform a separatemlite_rekeningquery inside the loop for each account; consider preloading all rekening rows into an associative array keyed bykd_rekto avoid N+1 queries and reduce DB load. - In
plugins/surat/Admin.phpforanyRujukan/anySakit/anySehat, rows are passed throughhtmlspecialchars_arrayonce when building$this->assign['list']and then again when building$assignfor the view, which risks double-escaping; it would be cleaner to escape only once at the boundary to the view. - In the DDL for
mlite_bpjs_emr_device(both inupgrade.phpandmlite_db.sql), themanufacture_dateandexpiration_datecolumns are still written with single quotes around the column names; updating these to backticks (like other identifiers) will avoid SQL syntax/compatibility issues across databases.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `Admin::getBukuBesar()` (branch without `kd_rek` filter), you perform a separate `mlite_rekening` query inside the loop for each account; consider preloading all rekening rows into an associative array keyed by `kd_rek` to avoid N+1 queries and reduce DB load.
- In `plugins/surat/Admin.php` for `anyRujukan/anySakit/anySehat`, rows are passed through `htmlspecialchars_array` once when building `$this->assign['list']` and then again when building `$assign` for the view, which risks double-escaping; it would be cleaner to escape only once at the boundary to the view.
- In the DDL for `mlite_bpjs_emr_device` (both in `upgrade.php` and `mlite_db.sql`), the `manufacture_date` and `expiration_date` columns are still written with single quotes around the column names; updating these to backticks (like other identifiers) will avoid SQL syntax/compatibility issues across databases.
## Individual Comments
### Comment 1
<location path="plugins/surat/Admin.php" line_range="82-83" />
<code_context>
$this->assign['addURL'] = url([ADMIN, 'surat', 'rujukanadd']);
$this->assign['phrase'] = $phrase;
- return $this->draw('rujukan.manage.html', ['rujukan' => htmlspecialchars_array($this->assign)]);
+ $assign = htmlspecialchars_array($this->assign);
+ $assign['pagination'] = $this->assign['pagination'];
+ return $this->draw('rujukan.manage.html', ['rujukan' => $assign]);
}
</code_context>
<issue_to_address>
**issue (bug_risk):** Assignment data is being HTML-escaped twice, which can lead to double-encoded output.
`$this->assign` is escaped twice: once per row via `htmlspecialchars_array($row)` before adding to `$this->assign['list']`, and again when you build `$assign = htmlspecialchars_array($this->assign)`. This will double-encode entities (e.g. `&` → `&` → `&amp;`). Please escape only once, either at the final render step or by skipping the second `htmlspecialchars_array` when `$this->assign` is already sanitized.
</issue_to_address>
### Comment 2
<location path="mlite_db.sql" line_range="1654-1655" />
<code_context>
`manufacturer` VARCHAR(255) DEFAULT NULL,
- 'manufacture_date' DATE NOT NULL,
- 'expiration_date' DATE NOT NULL,
+ 'manufacture_date' DATE DEFAULT NULL,
+ 'expiration_date' DATE DEFAULT NULL,
`model` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`id`),
</code_context>
<issue_to_address>
**issue (bug_risk):** Column identifiers are quoted with single quotes, which are string literals in SQL, not identifier delimiters.
`manufacture_date` and `expiration_date` are written with single quotes (`'manufacture_date'` / `'expiration_date'`), which SQL interprets as string literals rather than column identifiers. This can cause syntax errors or unexpected behavior, depending on SQL mode. Please use identifier quoting (e.g., ``` `manufacture_date` ``` / ``` `expiration_date` ```), or leave them unquoted to match the other columns.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| $assign = htmlspecialchars_array($this->assign); | ||
| $assign['pagination'] = $this->assign['pagination']; |
There was a problem hiding this comment.
issue (bug_risk): Assignment data is being HTML-escaped twice, which can lead to double-encoded output.
$this->assign is escaped twice: once per row via htmlspecialchars_array($row) before adding to $this->assign['list'], and again when you build $assign = htmlspecialchars_array($this->assign). This will double-encode entities (e.g. & → & → &amp;). Please escape only once, either at the final render step or by skipping the second htmlspecialchars_array when $this->assign is already sanitized.
| 'manufacture_date' DATE DEFAULT NULL, | ||
| 'expiration_date' DATE DEFAULT NULL, |
There was a problem hiding this comment.
issue (bug_risk): Column identifiers are quoted with single quotes, which are string literals in SQL, not identifier delimiters.
manufacture_date and expiration_date are written with single quotes ('manufacture_date' / 'expiration_date'), which SQL interprets as string literals rather than column identifiers. This can cause syntax errors or unexpected behavior, depending on SQL mode. Please use identifier quoting (e.g., `manufacture_date` / `expiration_date`), or leave them unquoted to match the other columns.
Summary by Sourcery
Enhance financial reporting, cashier, and letter management modules with improved period handling, summaries, printing/exports, and safer schema defaults.
New Features:
Bug Fixes:
Enhancements: