# Transkrip Konteks & Riwayat Percakapan Refactoring Everest ERP
**Tanggal**: 05 September 2026  
**Sesi**: Audit Transaksi Penjualan, Validasi Stok Kasir, Takeaway Shipping, dan Selektor Retur Penjualan (9822)  
**Dokumentasi untuk Melanjutkan Pekerjaan**: Simpan berkas ini sebagai referensi status dan backlog teknis untuk sesi berikutnya.

---

## DAFTAR ISI
1. [Ringkasan Eksekutif Sesi](#1-ringkasan-eksekutif-sesi)
2. [Topik 1: Validasi Stok Minus & Proteksi Tombol/Tik Kasir](#2-topik-1-validasi-stok-minus--proteksi-tomboltik-kasir)
3. [Topik 2: Bypass Validasi Detail Pengiriman untuk Metode Takeaway](#3-topik-2-bypass-validasi-detail-pengiriman-untuk-metode-takeaway)
4. [Topik 3: Audit Kritis Selektor Retur Penjualan (9822)](#4-topik-3-audit-kritis-selektor-retur-penjualan-9822)
5. [Daftar Berkas yang Telah Dimodifikasi & Terverifikasi](#5-daftar-berkas-yang-telah-dimodifikasi--terverifikasi)
6. [Backlog & Rencana Aksi untuk Sesi Berikutnya](#6-backlog--rencana-aksi-untuk-sesi-berikutnya)

---

## 1. Ringkasan Eksekutif Sesi

Pada sesi ini, kolaborasi difokuskan pada tiga area modul `penjualan`:
1. **Menutup celah bypass stok minus pada transaksi kasir/tunai**: Menyinkronkan status stok minus dengan status elemen checkbox `#tic_lanjut` dan menambahkan proteksi backend berbasis Mandatory Rule #4.
2. **Penyempurnaan aturan UX Takeaway**: Menghapus kewajiban pengisian detail ekspedisi/alamat untuk transaksi berjenis ambil sendiri (*Takeaway* / opsi 2).
3. **Audit mendalam terhadap Selektor Retur Penjualan (`9822`)**: Menemukan akar penyebab nilai `SKU = 0`, `PRODUCT CODE = 0`, dan `UOM = n/a` di keranjang belanja, serta menemukan *bug* parser SQL `<>` pada service query terpadu (`ComItemQueryService.php`).

---

## 2. Topik 1: Validasi Stok Minus & Proteksi Tombol/Tik Kasir

### A. Latar Belakang & Masalah
* **Gejala**: Ketika item dalam keranjang belanja mengalami stok kurang/minus pada transaksi tunai (seperti penjualan reguler `5822` atau POS `5823`), tombol utama penyimpanan dinonaktifkan (`disabled`). Namun, elemen checkbox **"Tic untuk menyimpan/melanjutkan proses"** (`#tic_lanjut`) masih dapat dicentang oleh kasir. Setelah dicentang, tombol submit aktif kembali dan memungkinkan transaksi stok minus tetap tersimpan (*bypass*).
* **Akar Masalah**:
  * Pada `application/modules/penjualan/controllers/_shoppingCart.php`, fungsi `customerInfo()` yang dipanggil secara AJAX merender ulang bagian footer form dan secara asinkron menghapus atribut `disabled` dari `#tic_lanjut` tanpa memeriksa variabel global `hasStockMinus`.
  * Tidak adanya *early validation* di level domain service sebelum transaksi penjualan dibuat.

### B. Tindakan & Solusi yang Telah Diterapkan
1. **Frontend Synchronization (`_shoppingCart.php`, `transaksi.html`, `transaksi_pos.html`)**:
   * Menambahkan pengecekan `window.hasStockMinus` atau `top.hasStockMinus` pada script perenderan `customerInfo()`.
   * Jika terdeteksi ada item dengan stok minus, checkbox `#tic_lanjut` dipaksa tetap `disabled = true` dan `checked = false`.
2. **Backend Domain Guard (`ComSalesOrderValidationService.php`)**:
   * Mengintegrasikan `ComStockEngine` untuk mengevaluasi `shoppingCartStokKurang` sebelum transaksi disimpan.
   * Transaksi akan ditolak tegas di backend jika kuantitas melebihi saldo fisik riil dikurangi booking locker (Mandatory Rule #4 Anti-Overselling).

---

## 3. Topik 2: Bypass Validasi Detail Pengiriman untuk Metode Takeaway

### A. Latar Belakang & Masalah
* **Gejala**: Ketika kasir memilih metode pengiriman **Takeaway** (Ambil Sendiri / Bawa Sendiri), sistem tetap memunculkan popup validasi yang memblokir proses: *"Detail Pengiriman wajib dipilih!"*.
* **Akar Masalah**:
  * Di dalam `application/modules/penjualan/config/coTransaksiUi.php` pada konfigurasi transaksi `5822` (baris ~2422) dan `5823` (baris ~11054), array pilihan `shippingMethod` untuk indeks `2` (Takeaway) mengikutsertakan field `deliveryDetails` di dalam daftar sub-elemen wajib.

### B. Tindakan & Solusi yang Telah Diterapkan
* Menghapus referensi `deliveryDetails` dari sub-elemen opsi `2` (Takeaway) pada `coTransaksiUi.php` untuk transaksi `5822` dan `5823`.
* Transaksi berstatus Takeaway kini dapat diproses tanpa mewajibkan kasir memilih kurir atau detail pengiriman.

---

## 4. Topik 3: Audit Kritis Selektor Retur Penjualan (9822)

### A. Konteks Tangkapan Layar Pengguna
* **URL**: `demo.mayagrahakencana.com/everest_4sep/penjualan/Create/index/9822?gr=cGVuanVhbGFu`
* **Pelanggan**: `VIVI ELECTRINDO`
* **Tahapan Transaksi**: Step 1: `RETURN REQUEST` (target `9822r`)
* **Daftar Dokumen di Selektor Kiri**:
  * Menampilkan riwayat nota `5822SPD.1.17.1` bertanggal `2024-01-10 09:17:34` hingga `5822SPD.1.17.9` bertanggal `2024-02-06 09:55:03`.
* **Tabel Keranjang Belanja**:
  * Produk: `PANASONIC CS/CU-YN12WKJ 1 outdoor 1 indoor`
  * Qty: 5 unit | Harga Satuan: Rp 4.144.144,14 | Grand Total: Rp 22.750.000,25
  * **Anomali Nilai**: Kolom **SKU = 0**, **PRODUCT CODE = 0**, dan **UOM = n/a**.

### B. Temuan Teknis & Logika Kode (Root Causes)

#### 1. Bug Pemetaan Data di `_processSelectNotaItem.php` (Baris 380)
```php
foreach ($fieldSrcs as $key2 => $src2) {
    if (is_array($src2) && sizeof($src2) > 0) {
        // ...
    } else {
        $tmp[$key2] = makeValue($src2, $tmp, $tmp, $row->$src2); // <-- BUG DI SINI
    }
}
```
* **Penyebab**: `$row` adalah objek data dari `MdlNotaItem` (`transaksi` JOIN `transaksi_data`), yang **tidak memiliki** kolom `kode`, `barcode`, maupun `satuan`.
* Data atribut produk sebenarnya tersimpan di objek `$rows` (dari model `MdlProduk` yang dimuat pada baris 201–206: `$tmpBD = $bd->lookupByID($id)->result(); $rows = $tmpBD[0];`).
* Karena kode memanggil `$row->$src2` dan bukan `$rows->$src2`, nilai properti bernilai `null`, sehingga `makeValue()` fallback ke nilai bawaan `0`.
* **Dampak**: Kolom **SKU** dan **PRODUCT CODE** pada tampilan keranjang belanja menjadi `0` bulat, dan **UOM** menjadi `n/a`.

#### 2. Bug Cacat Parser Operator SQL `<>` di `ComItemQueryService.php` (Baris 153–171)
* Konfigurasi `selectorFilters` pada transaksi `9822` di `coTransaksiUi.php`:
  ```php
  "selectorFilters" => array(
      "returned=.0",
      "jenis=.5822spd",
      "customers_id=pihakID",
      "trash_4<>.1", // Proteksi agar nota yang direject tidak muncul
      "cabang_id=placeID",
  ),
  ```
* Pada fungsi `parseAndApplyFilters()` di `ComItemQueryService.php`:
  ```php
  if (strpos($filterExpr, '>=') !== false) {
      $operator = '>=';
      $parts = explode('>=', $filterExpr, 2);
  } elseif (strpos($filterExpr, '<=') !== false) {
      $operator = '<=';
      $parts = explode('<=', $filterExpr, 2);
  } elseif (strpos($filterExpr, '!=') !== false) {
      $operator = '!=';
      $parts = explode('!=', $filterExpr, 2);
  } elseif (strpos($filterExpr, '>') !== false) {
      $operator = '>';
      $parts = explode('>', $filterExpr, 2);
  } elseif (strpos($filterExpr, '<') !== false) {
      $operator = '<';
      $parts = explode('<', $filterExpr, 2);
  } elseif (strpos($filterExpr, '=') !== false) {
      $operator = '=';
      $parts = explode('=', $filterExpr, 2);
  }
  ```
* **Penyebab**: Parser tidak memiliki kondisi untuk operator `<>`. Karena ekspresi `"trash_4<>.1"` mengandung tanda `<`, kode mencocokkannya sebagai operator `<`, memotong string pada `<` sehingga menghasilkan:
  * `$column = 'trash_4'`
  * `$operator = '<'`
  * `$valExpr = '>.1'` $\rightarrow$ query SQL: `trash_4 < '>.1'`.
* **Dampak**: Filter SQL menjadi tidak valid/rusak dan proteksi anti-reject nota berisiko tidak berfungsi.

#### 3. Disonansi UI Label Selektor
* Form input selektor kiri menggunakan placeholder dan label `item` (dari konfigurasi `"selectorLabel" => "item"`). Padahal pengguna sebenarnya memilih **Nomor Dokumen Surat Pengantar/Shipment (`5822SPD`)**. Ini membingungkan pengguna operasional yang mengira mereka sedang mencari nama produk langsung.

### C. Analisis Kepatuhan Pajak & Hukum Korporasi
1. **Risiko Perpajakan (PMK No. 65/PMK.03/2010 jo. PER-03/PJ/2022 & UU HPP)**:
   * Nota asal yang dimuat bertanggal **Januari 2024** (> 2,5 tahun lalu). Faktur Pajak terkait sudah dilaporkan pada SPT Masa PPN 2024 dan SPT Tahunan Badan 2024 yang sudah ditutup.
   * Meretur transaksi lintas tahun yang sangat lampau tanpa validasi tanggal potong (*cut-off date*) berisiko tinggi memicu pemeriksaan pajak (SP2DK) serta penolakan sinkronisasi faktur retur di Coretax DJP.
2. **Risiko Akuntansi Persediaan (PSAK 14 / IAS 2)**:
   * Mengakui retur 5 unit AC Panasonic ke persediaan dengan nilai historis penuh (Rp 22,75 juta) tanpa evaluasi kondisi fisik dan cadangan penurunan nilai (*allowance for inventory write-down*) berisiko menyebabkan aset persediaan disajikan terlalu tinggi (*overstated assets*).
3. **Risiko Operasional Fisik Unit AC Split**:
   * Karena SKU bernilai `0` dan serial number tidak terkunci, unit AC split ("1 outdoor, 1 indoor") berisiko diterima secara tidak lengkap atau tertukar seri fisiknya di gudang.

---

## 5. Daftar Berkas yang Telah Dimodifikasi & Terverifikasi

Seluruh berkas berikut telah divalidasi dengan PHP Linter (`php -l`) tanpa kesalahan sintaks:
1. `w:\everest_refaktor\application\modules\penjualan\controllers\_shoppingCart.php`
   * Penanganan state `#tic_lanjut` agar tidak aktif saat terdeteksi stok minus.
2. `w:\everest_refaktor\application\modules\penjualan\views\template\transaksi.html`
   * Proteksi event handler pada checkbox konfirmasi kasir.
3. `w:\everest_refaktor\application\modules\penjualan\views\template\transaksi_pos.html`
   * Penyesuaian sinkronisasi event serupa untuk modul POS kasir.
4. `w:\everest_refaktor\application\modules\penjualan\config\coTransaksiUi.php`
   * Penghapusan elemen `deliveryDetails` pada opsi pengiriman `2` (Takeaway) untuk transaksi `5822` dan `5823`.

---

## 6. Backlog & Rencana Aksi untuk Sesi Berikutnya

Ketika melanjutkan pekerjaan di sesi berikutnya, berikut adalah urutan langkah yang siap dieksekusi:

### A. Perbaikan Pemetaan Data `_processSelectNotaItem.php`
* **Target File**: `w:\everest_refaktor\application\modules\penjualan\controllers\_processSelectNotaItem.php`
* **Rencana Perubahan**:
  Pada baris 379–382, ubah logika pemetaan atribut produk agar mengambil nilai dari `$rows` (`MdlProduk`) jika kolom tersebut ada di detail produk:
  ```php
  // Periksa apakah atribut tersedia di $rows (detail produk), jika tidak gunakan $row (nota transaksi)
  $valSource = isset($rows->$src2) ? $rows->$src2 : (isset($row->$src2) ? $row->$src2 : 0);
  $tmp[$key2] = makeValue($src2, $tmp, $tmp, $valSource);
  ```
* **Hasil yang Diharapkan**: Kolom SKU, Product Code, dan Satuan (UOM) pada keranjang retur penjualan akan terisi nilai riil produk (bukan `0` atau `n/a`).

### B. Perbaikan Parser Operator SQL di `ComItemQueryService.php`
* **Target File**: `w:\everest_refaktor\application\models\Coms\ComItemQueryService.php`
* **Rencana Perubahan**:
  Pada fungsi `parseAndApplyFilters()` (baris ~153), tambahkan deteksi operator `<>` di urutan teratas sebelum pemeriksaan operator `<` dan `>`:
  ```php
  if (strpos($filterExpr, '<>') !== false) {
      $operator = '<>';
      $parts = explode('<>', $filterExpr, 2);
  } elseif (strpos($filterExpr, '!=') !== false) {
      $operator = '!=';
      $parts = explode('!=', $filterExpr, 2);
  } // ... operator lainnya
  ```
* **Hasil yang Diharapkan**: Ekspresi filter `"trash_4<>.1"` akan menghasilkan klausa SQL `trash_4 <> '1'` yang benar.

### C. Penyesuaian UI & Kebijakan Batas Waktu Selektor Retur (`coTransaksiUi.php`)
* **Target File**: `w:\everest_refaktor\application\modules\penjualan\config\coTransaksiUi.php`
* **Rencana Perubahan**:
  * Ubah `"selectorLabel" => "item"` menjadi `"delivery note"` atau `"nota pengiriman"` pada konfigurasi `9822`.
  * Evaluasi bersama tim bisnis terkait penambahan filter batas umur nota (misal: nota maksimal 30–90 hari terakhir) pada `selectorFilters` untuk mencegah penarikan faktur lampau tahun 2024 tanpa otorisasi manajerial.

---
*Dokumen ini dibuat secara otomatis pada 05 September 2026 sebagai rangkuman kerja lengkap.*
