Initial commit
This commit is contained in:
@@ -0,0 +1,795 @@
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
class Items extends CI_Controller {
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
if (!$this->session->userdata('logged_in')) {
|
||||
redirect('auth');
|
||||
}
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data = ["active_menu" => "items"];
|
||||
$this->load->view('partials/header', $data);
|
||||
$this->load->view('items/layout');
|
||||
$this->load->view('partials/footer');
|
||||
}
|
||||
|
||||
public function draft_items()
|
||||
{
|
||||
$data = ["active_menu" => "draft_items"];
|
||||
$this->load->view('partials/header', $data);
|
||||
$this->load->view('items/draft_items');
|
||||
$this->load->view('partials/footer');
|
||||
}
|
||||
|
||||
// =========================
|
||||
// GET DATA (FIX)
|
||||
// =========================
|
||||
public function get_data()
|
||||
{
|
||||
$status = $this->input->get('s') ?? 'all';
|
||||
|
||||
$allowed = ['draft','active','all'];
|
||||
if (!in_array($status, $allowed)) {
|
||||
$status = 'all';
|
||||
}
|
||||
|
||||
$this->db->select('
|
||||
items.id,
|
||||
items.nama_barang,
|
||||
items.kode_detail,
|
||||
items.harga_beli,
|
||||
items.harga_jual,
|
||||
items.tanggal_pembelian,
|
||||
items.created_at,
|
||||
items.stok,
|
||||
items.status,
|
||||
items.kode_id,
|
||||
(
|
||||
SELECT GROUP_CONCAT(DISTINCT w.nama SEPARATOR ", ")
|
||||
FROM stock_logs sl
|
||||
LEFT JOIN warehouses w ON sl.warehouse_id = w.id
|
||||
WHERE sl.item_id = items.id
|
||||
) as gudang
|
||||
');
|
||||
|
||||
if ($status !== 'all') {
|
||||
$this->db->where('items.status', $status);
|
||||
}
|
||||
|
||||
// urutan custom
|
||||
$this->db->order_by('(items.stok = 0)', 'ASC', false);
|
||||
$this->db->order_by('items.tanggal_pembelian', 'ASC');
|
||||
|
||||
$this->db->from('items');
|
||||
|
||||
$data = $this->db->get()->result();
|
||||
|
||||
// $this->db->select('
|
||||
// items.id,
|
||||
// items.nama_barang,
|
||||
// items.kode_detail,
|
||||
// items.harga_beli,
|
||||
// items.harga_jual,
|
||||
// items.tanggal_pembelian,
|
||||
// items.created_at,
|
||||
// items.stok,
|
||||
// items.status,
|
||||
// items.kode_id,
|
||||
// (
|
||||
// SELECT GROUP_CONCAT(DISTINCT w.nama SEPARATOR ", ")
|
||||
// FROM stock_logs sl
|
||||
// LEFT JOIN warehouses w ON sl.warehouse_id = w.id
|
||||
// WHERE sl.item_id = items.id
|
||||
// ) as gudang
|
||||
// ');
|
||||
|
||||
// if ($status !== 'all') {
|
||||
// $this->db->where('items.status', $status);
|
||||
// }
|
||||
|
||||
// // 🔥 filter utama per kode_id
|
||||
// $this->db->where("
|
||||
// (items.stok > 0)
|
||||
// OR
|
||||
// (
|
||||
// items.stok = 0
|
||||
// AND items.tanggal_pembelian = (
|
||||
// SELECT MAX(i2.tanggal_pembelian)
|
||||
// FROM items i2
|
||||
// WHERE i2.stok = 0
|
||||
// AND i2.kode_id = items.kode_id
|
||||
// )
|
||||
// )
|
||||
// ", null, false);
|
||||
|
||||
// // urutan
|
||||
// $this->db->order_by('items.stok = 0', 'ASC', false);
|
||||
// $this->db->order_by('items.tanggal_pembelian', 'ASC');
|
||||
|
||||
// $this->db->from('items');
|
||||
|
||||
// $data = $this->db->get()->result();
|
||||
|
||||
$result = [];
|
||||
$no = 1;
|
||||
|
||||
foreach($data as $row){
|
||||
|
||||
$btnDetail = '<button class="btn btn-info btn-sm btn-detail m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Detail</button>';
|
||||
$btnEdit = '<button class="btn btn-secondary btn-sm btn-editItem m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Edit</button>';
|
||||
$btnDelete = '<button class="btn btn-danger btn-sm btn-delete m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Delete</button>';
|
||||
|
||||
if($row->status == 'draft'){
|
||||
$btnPost = '<button class="btn btn-success btn-sm btn-updatePosting m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Posting</button>';
|
||||
$action = $btnDetail . $btnPost . $btnDelete;
|
||||
} else {
|
||||
if($this->session->userdata('role') == 'Admin') {
|
||||
$btnAdjust = '<button class="btn btn-warning btn-sm btn-adjust m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Adjust</button>';
|
||||
} else {
|
||||
$btnAdjust = '';
|
||||
}
|
||||
$action = $btnDetail . $btnEdit . $btnAdjust . $btnDelete;
|
||||
}
|
||||
|
||||
$result[] = [
|
||||
$no++,
|
||||
$row->tanggal_pembelian,
|
||||
$row->kode_detail,
|
||||
$row->nama_barang,
|
||||
$row->gudang ?? '-',
|
||||
$row->stok,
|
||||
number_format($row->harga_beli ?? 0, 2),
|
||||
number_format($row->harga_jual ?? 0, 2),
|
||||
$row->created_at,
|
||||
$action
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode(["data"=>$result]);
|
||||
}
|
||||
|
||||
// =========================
|
||||
// DETAIL
|
||||
// =========================
|
||||
public function detail_simple($id)
|
||||
{
|
||||
echo json_encode(
|
||||
$this->db->get_where('items',['id'=>$id])->row()
|
||||
);
|
||||
}
|
||||
|
||||
// =========================
|
||||
// DETAIL
|
||||
// =========================
|
||||
public function detail($id)
|
||||
{
|
||||
$item = $this->db->get_where('items',['id'=>$id])->row();
|
||||
|
||||
$logs = $this->db
|
||||
->select('stock_logs.*, warehouses.nama as gudang')
|
||||
->join('warehouses','warehouses.id = stock_logs.warehouse_id','left')
|
||||
->where('item_id',$id)
|
||||
->order_by('stock_logs.id','DESC')
|
||||
->get('stock_logs')
|
||||
->result();
|
||||
|
||||
echo json_encode([
|
||||
'item'=>$item,
|
||||
'logs'=>$logs
|
||||
]);
|
||||
}
|
||||
|
||||
public function get_accounts()
|
||||
{
|
||||
$data = $this->db
|
||||
->where_in('kode_akun', [101,102,201])
|
||||
->order_by('kode_akun','ASC')
|
||||
->get('accounts')
|
||||
->result();
|
||||
|
||||
echo json_encode($data);
|
||||
}
|
||||
|
||||
public function get_accounts_biaya()
|
||||
{
|
||||
$data = $this->db
|
||||
->where(['tipe' => 'expense', 'posisi'=> 'debit', 'kategori'=> 'laba_rugi'])
|
||||
->order_by('kode_akun','ASC')
|
||||
->get('accounts')
|
||||
->result();
|
||||
|
||||
echo json_encode($data);
|
||||
}
|
||||
|
||||
// =========================
|
||||
// SAVE (FIX TOTAL)
|
||||
// =========================
|
||||
public function save()
|
||||
{
|
||||
$nama_barang = $this->input->post('nama_barang');
|
||||
$qty = (int)$this->input->post('qty');
|
||||
$harga_beli = (float)$this->input->post('harga_beli');
|
||||
$harga_jual = (float)$this->input->post('harga_jual');
|
||||
$warehouse_id = $this->input->post('warehouse_id');
|
||||
$account_kas = $this->input->post('account_kas');
|
||||
$kode_id = $this->input->post('kode_id');
|
||||
$tanggal_beli = $this->input->post('tanggal_beli');
|
||||
$status = $this->input->post('status');
|
||||
|
||||
// ================= VALIDASI =================
|
||||
if(!$nama_barang || $qty <= 0 || $harga_beli <= 0 || !$warehouse_id || !$account_kas){
|
||||
echo json_encode([
|
||||
'status'=>false,
|
||||
'message'=>'Data tidak lengkap / tidak valid'
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
// ================= VALIDASI HARGA =================
|
||||
if($harga_beli > $harga_jual){
|
||||
echo json_encode([
|
||||
'status'=>false,
|
||||
'message'=>'Harga beli tidak boleh lebih besar dari harga jual'
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
$kode = $this->db->get_where('kode_barang',['id'=>$kode_id])->row();
|
||||
|
||||
$tanggal_kode = date('dmy', strtotime($tanggal_beli));
|
||||
$kode_detail = $kode->kode_barang . '-' . $tanggal_kode;
|
||||
|
||||
$total = $qty * $harga_beli;
|
||||
|
||||
$this->db->trans_start();
|
||||
|
||||
// ================= INSERT ITEM =================
|
||||
$this->db->insert('items',[
|
||||
'stok' =>$qty,
|
||||
'kode_detail' =>$kode_detail,
|
||||
'kode_id' =>$kode_id,
|
||||
'nama_barang' =>$nama_barang,
|
||||
'harga_beli' =>$harga_beli,
|
||||
'harga_jual' =>$harga_jual,
|
||||
'tanggal_pembelian' => $tanggal_beli,
|
||||
'status' => $status
|
||||
]);
|
||||
|
||||
$item_id = $this->db->insert_id();
|
||||
|
||||
// ================= STOCK MASUK =================
|
||||
$this->db->insert('stock_logs',[
|
||||
'item_id'=>$item_id,
|
||||
'warehouse_id'=>$warehouse_id,
|
||||
'qty'=>$qty,
|
||||
'tipe'=>'masuk',
|
||||
'keterangan'=>'Pembelian awal',
|
||||
'created_at'=>date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
// ================= JURNAL =================
|
||||
$no_ref = 'BLI-'.date('Ymd').'-'.$item_id;
|
||||
|
||||
$this->db->insert('journals',[
|
||||
'tanggal'=>$tanggal_beli,
|
||||
'no_ref'=>$no_ref,
|
||||
'ref_type'=> 'new_items',
|
||||
'ref_id'=>$item_id,
|
||||
'keterangan'=>'Pembelian '.$nama_barang,
|
||||
'created_by' => $this->session->userdata('user_id')
|
||||
]);
|
||||
|
||||
$jid = $this->db->insert_id();
|
||||
|
||||
// 🔥 Debit Persediaan
|
||||
$this->db->insert('journal_details',[
|
||||
'journal_id'=>$jid,
|
||||
'account_id'=>21, // persediaan
|
||||
'debit'=>$total,
|
||||
'kredit'=>0
|
||||
]);
|
||||
|
||||
// 🔥 Kredit Kas (DINAMIS)
|
||||
$this->db->insert('journal_details',[
|
||||
'journal_id'=>$jid,
|
||||
'account_id'=>$account_kas,
|
||||
'debit'=>0,
|
||||
'kredit'=>$total
|
||||
]);
|
||||
|
||||
$this->db->trans_complete();
|
||||
|
||||
// ================= CEK TRANSAKSI =================
|
||||
if ($this->db->trans_status() === FALSE){
|
||||
echo json_encode([
|
||||
'status'=>false,
|
||||
'message'=>'Gagal simpan data'
|
||||
]);
|
||||
} else {
|
||||
|
||||
log_activity(
|
||||
'items',
|
||||
'create',
|
||||
'Menambahkan item: ' . $nama_barang,
|
||||
'success'
|
||||
);
|
||||
|
||||
echo json_encode([
|
||||
'status'=>true,
|
||||
'message'=>'Berhasil tambah item'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// =========================
|
||||
// UPDATE (FIX AKUN)
|
||||
// =========================
|
||||
public function update()
|
||||
{
|
||||
$id = $this->input->post('id');
|
||||
$nama_barang = $this->input->post('nama_barang');
|
||||
$harga_baru = (float)$this->input->post('harga_beli');
|
||||
$harga_jual = (float)$this->input->post('harga_jual');
|
||||
|
||||
$item = $this->db->get_where('items',['id'=>$id])->row();
|
||||
|
||||
if(!$item){
|
||||
echo json_encode(['status'=>false,'message'=>'Item tidak ditemukan']);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->db->trans_start();
|
||||
|
||||
$this->db->where('id',$id)->update('items',[
|
||||
'nama_barang'=>$nama_barang,
|
||||
'harga_beli'=>$harga_baru,
|
||||
'harga_jual'=>$harga_jual
|
||||
]);
|
||||
|
||||
if($item->harga_beli != $harga_baru){
|
||||
|
||||
$stok = $this->db->select('SUM(qty * IF(tipe="masuk",1,-1)) as stok')
|
||||
->where('item_id',$id)
|
||||
->get('stock_logs')
|
||||
->row()->stok ?? 0;
|
||||
|
||||
$selisih = ($harga_baru - $item->harga_beli) * $stok;
|
||||
|
||||
if($selisih != 0){
|
||||
|
||||
$this->db->insert('journals',[
|
||||
'tanggal'=>date('Y-m-d'),
|
||||
'no_ref'=>'ADJ-'.date('YmdHis').'-'.$id,
|
||||
'keterangan'=>'Penyesuaian harga '.$item->nama_barang,
|
||||
'created_by' => $this->session->userdata('user_id')
|
||||
]);
|
||||
|
||||
$jid = $this->db->insert_id();
|
||||
|
||||
if($selisih > 0){
|
||||
// 🔥 naik → pendapatan
|
||||
$this->db->insert_batch('journal_details',[
|
||||
[
|
||||
'journal_id'=>$jid,
|
||||
'account_id'=>21,
|
||||
'debit'=>$selisih,
|
||||
'kredit'=>0
|
||||
],
|
||||
[
|
||||
'journal_id'=>$jid,
|
||||
'account_id'=>65, // ✅ BENAR
|
||||
'debit'=>0,
|
||||
'kredit'=>$selisih
|
||||
]
|
||||
]);
|
||||
}else{
|
||||
// 🔥 turun → beban
|
||||
$this->db->insert_batch('journal_details',[
|
||||
[
|
||||
'journal_id'=>$jid,
|
||||
'account_id'=>64, // ✅ BENAR
|
||||
'debit'=>abs($selisih),
|
||||
'kredit'=>0
|
||||
],
|
||||
[
|
||||
'journal_id'=>$jid,
|
||||
'account_id'=>21,
|
||||
'debit'=>0,
|
||||
'kredit'=>abs($selisih)
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->db->trans_complete();
|
||||
|
||||
log_activity(
|
||||
'items',
|
||||
'update',
|
||||
'Update item: ' . $nama_barang,
|
||||
'success'
|
||||
);
|
||||
|
||||
$this->update_item_stok($id);
|
||||
|
||||
echo json_encode(['status'=>true,'message'=>'Berhasil update + adjustment']);
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
// cek item ada
|
||||
$item = $this->db->get_where('items',['id'=>$id])->row();
|
||||
|
||||
if(!$item){
|
||||
echo json_encode(['status'=>false,'message'=>'Item tidak ditemukan']);
|
||||
return;
|
||||
}
|
||||
|
||||
// cek ada transaksi stock
|
||||
$cekStock = $this->db->where('item_id',$id)->count_all_results('stock_logs');
|
||||
|
||||
if($cekStock > 1){
|
||||
echo json_encode([
|
||||
'status'=>false,
|
||||
'message'=>'Tidak bisa dihapus, sudah ada transaksi stok'
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->db->trans_start();
|
||||
|
||||
// hapus item
|
||||
$this->db->delete('stock_logs',['item_id'=>$id]);
|
||||
$this->db->delete('items',['id'=>$id]);
|
||||
|
||||
$j = $this->db->get_where('journals', [
|
||||
'ref_type'=>'new_items',
|
||||
'ref_id'=>$id
|
||||
])->result();
|
||||
|
||||
foreach($j as $row){
|
||||
$this->db->delete('journal_details', ['journal_id'=>$row->id]);
|
||||
$this->db->delete('journals', ['id'=>$row->id]);
|
||||
}
|
||||
|
||||
$this->db->trans_complete();
|
||||
|
||||
if ($this->db->trans_status() === FALSE){
|
||||
echo json_encode(['status'=>false,'message'=>'Gagal hapus']);
|
||||
} else {
|
||||
|
||||
log_activity(
|
||||
'items',
|
||||
'delete',
|
||||
'Hapus item ID: ' . $id,
|
||||
'success'
|
||||
);
|
||||
|
||||
echo json_encode(['status'=>true,'message'=>'Berhasil dihapus']);
|
||||
}
|
||||
}
|
||||
|
||||
public function posting()
|
||||
{
|
||||
$id = $this->input->post('id');
|
||||
|
||||
if(!$id){
|
||||
echo json_encode([
|
||||
'status' => false,
|
||||
'message' => 'ID tidak valid'
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
// cek item ada
|
||||
$item = $this->db->get_where('items', ['id' => $id])->row();
|
||||
|
||||
if(!$item){
|
||||
echo json_encode([
|
||||
'status' => false,
|
||||
'message' => 'Item tidak ditemukan'
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
// cegah double posting
|
||||
if($item->status == 'active'){
|
||||
echo json_encode([
|
||||
'status' => false,
|
||||
'message' => 'Barang sudah diterima sebelumnya'
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->db->trans_start();
|
||||
|
||||
// update status saja
|
||||
$this->db->where('id', $id);
|
||||
$this->db->update('items', [
|
||||
'status' => 'active'
|
||||
]);
|
||||
|
||||
$this->db->trans_complete();
|
||||
|
||||
if ($this->db->trans_status() === FALSE){
|
||||
|
||||
echo json_encode([
|
||||
'status' => false,
|
||||
'message' => 'Gagal memproses data'
|
||||
]);
|
||||
|
||||
} else {
|
||||
|
||||
// log aktivitas
|
||||
log_activity(
|
||||
'items',
|
||||
'posting',
|
||||
'Barang diterima | ID: '.$id.' | Nama: '.$item->nama_barang,
|
||||
'success'
|
||||
);
|
||||
|
||||
echo json_encode([
|
||||
'status' => true,
|
||||
'message' => 'Barang sudah diterima dan stok siap digunakan'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// =========================
|
||||
// KELUAR BARANG (FIX TANPA stok column)
|
||||
// =========================
|
||||
public function keluarkan()
|
||||
{
|
||||
$account_biaya = (int)$this->input->post('account_biaya');
|
||||
$tanggal_keluar = $this->input->post('tanggal_keluar');
|
||||
$warehouse_id_keluar = $this->input->post('warehouse_id_keluar');
|
||||
$barang_id = $this->input->post('barang_id');
|
||||
$qty_keluar = (int)$this->input->post('qty_keluar');
|
||||
$keterangan_keluar = $this->input->post('keterangan_keluar');
|
||||
|
||||
// =========================
|
||||
// VALIDASI
|
||||
// =========================
|
||||
if(!$barang_id || !$warehouse_id_keluar || $qty_keluar <= 0){
|
||||
echo json_encode(['status'=>false,'message'=>'Data tidak valid']);
|
||||
return;
|
||||
}
|
||||
|
||||
// =========================
|
||||
// CEK ITEM
|
||||
// =========================
|
||||
$item = $this->db->get_where('items',['id'=>$barang_id])->row();
|
||||
if(!$item){
|
||||
echo json_encode(['status'=>false,'message'=>'Item tidak ditemukan']);
|
||||
return;
|
||||
}
|
||||
|
||||
// =========================
|
||||
// HITUNG STOK
|
||||
// =========================
|
||||
$stok = $this->db->select('
|
||||
COALESCE(SUM(qty * IF(tipe="masuk",1,-1)),0) as stok
|
||||
')
|
||||
->where('item_id',$barang_id)
|
||||
->where('warehouse_id',$warehouse_id_keluar)
|
||||
->get('stock_logs')
|
||||
->row()->stok;
|
||||
|
||||
if($stok < $qty_keluar){
|
||||
echo json_encode(['status'=>false,'message'=>'Stok tidak cukup']);
|
||||
return;
|
||||
}
|
||||
|
||||
$nilai = $qty_keluar * (float)$item->harga_beli;
|
||||
|
||||
// =========================
|
||||
// TRANSACTION
|
||||
// =========================
|
||||
$this->db->trans_start();
|
||||
|
||||
// log keluar
|
||||
$this->db->insert('stock_logs',[
|
||||
'item_id'=>$barang_id,
|
||||
'warehouse_id'=>$warehouse_id_keluar,
|
||||
'qty'=>$qty_keluar,
|
||||
'tipe'=>'keluar',
|
||||
'keterangan'=>$keterangan_keluar
|
||||
]);
|
||||
|
||||
$stock_log_id = $this->db->insert_id();
|
||||
|
||||
// jurnal
|
||||
$this->db->insert('journals',[
|
||||
'tanggal'=>$tanggal_keluar,
|
||||
'no_ref'=>'GOUT-'.date('YmdHis').'-'.$barang_id,
|
||||
'keterangan'=>'Pengeluaran Barang '.$item->nama_barang . ' ( ' . $keterangan_keluar . ' )',
|
||||
'ref_type' =>'stock_logs',
|
||||
'ref_id' => $stock_log_id,
|
||||
'created_by' => $this->session->userdata('user_id')
|
||||
]);
|
||||
|
||||
$jid = $this->db->insert_id();
|
||||
|
||||
// Debit biaya / HPP
|
||||
$this->db->insert('journal_details',[
|
||||
'journal_id'=>$jid,
|
||||
'account_id'=>$account_biaya,
|
||||
'debit'=>$nilai,
|
||||
'kredit'=>0
|
||||
]);
|
||||
|
||||
// Kredit persediaan
|
||||
$this->db->insert('journal_details',[
|
||||
'journal_id'=>$jid,
|
||||
'account_id'=>21,
|
||||
'debit'=>0,
|
||||
'kredit'=>$nilai
|
||||
]);
|
||||
|
||||
$this->db->trans_complete();
|
||||
|
||||
// =========================
|
||||
// CEK TRANSACTION
|
||||
// =========================
|
||||
if (!$this->db->trans_status()) {
|
||||
echo json_encode(['status'=>false,'message'=>'Gagal proses']);
|
||||
return;
|
||||
}
|
||||
|
||||
log_activity(
|
||||
'items',
|
||||
'stock_out',
|
||||
'Keluar barang: ' . $item->nama_barang . ' qty: ' . $qty_keluar . ' ( ' . $keterangan_keluar . ' )',
|
||||
'success'
|
||||
);
|
||||
|
||||
$this->update_item_stok($barang_id);
|
||||
|
||||
echo json_encode(['status'=>true,'message'=>'Barang berhasil dikeluarkan']);
|
||||
}
|
||||
|
||||
public function list()
|
||||
{
|
||||
echo json_encode(
|
||||
$this->db->get('warehouses')->result()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function adjust()
|
||||
{
|
||||
$item_id = $this->input->post('item_id');
|
||||
$qty = (int)$this->input->post('qty');
|
||||
$warehouse_id = $this->input->post('warehouse_id');
|
||||
$ket = $this->input->post('keterangan');
|
||||
|
||||
if($qty == 0){
|
||||
echo json_encode(['status'=>false,'message'=>'Qty tidak boleh 0']);
|
||||
return;
|
||||
}
|
||||
|
||||
$item = $this->db->get_where('items',['id'=>$item_id])->row();
|
||||
|
||||
$nilai = abs($qty) * $item->harga_beli;
|
||||
|
||||
$this->db->trans_start();
|
||||
|
||||
// 🔥 stock log
|
||||
$this->db->insert('stock_logs',[
|
||||
'item_id'=>$item_id,
|
||||
'warehouse_id'=>$warehouse_id,
|
||||
'qty'=>abs($qty),
|
||||
'tipe'=> $qty > 0 ? 'masuk' : 'keluar',
|
||||
'keterangan'=>'Adjustment: '.$ket
|
||||
]);
|
||||
|
||||
// 🔥 jurnal
|
||||
$this->db->insert('journals',[
|
||||
'tanggal'=>date('Y-m-d'),
|
||||
'no_ref'=>'ADJ-'.date('Ymd').'-'.$item_id,
|
||||
'keterangan'=>'Penyesuaian '.$item->nama_barang,
|
||||
'created_by' => $this->session->userdata('user_id')
|
||||
]);
|
||||
|
||||
$jid = $this->db->insert_id();
|
||||
|
||||
if($qty > 0){
|
||||
// stok naik
|
||||
$this->db->insert_batch('journal_details',[
|
||||
[
|
||||
'journal_id'=>$jid,
|
||||
'account_id'=>21, // persediaan
|
||||
'debit'=>$nilai,
|
||||
'kredit'=>0
|
||||
],
|
||||
[
|
||||
'journal_id'=>$jid,
|
||||
'account_id'=>65, // modal / selisih
|
||||
'debit'=>0,
|
||||
'kredit'=>$nilai
|
||||
]
|
||||
]);
|
||||
}else{
|
||||
// stok turun
|
||||
$this->db->insert_batch('journal_details',[
|
||||
[
|
||||
'journal_id'=>$jid,
|
||||
'account_id'=>64,
|
||||
'debit'=>$nilai,
|
||||
'kredit'=>0
|
||||
],
|
||||
[
|
||||
'journal_id'=>$jid,
|
||||
'account_id'=>21,
|
||||
'debit'=>0,
|
||||
'kredit'=>$nilai
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
$this->db->trans_complete();
|
||||
|
||||
log_activity(
|
||||
'items',
|
||||
'adjust',
|
||||
'Adjustment item ID: ' . $item_id . ' qty: ' . $qty,
|
||||
'success'
|
||||
);
|
||||
|
||||
$this->update_item_stok($item_id);
|
||||
|
||||
echo json_encode(['status'=>true,'message'=>'Adjustment berhasil']);
|
||||
}
|
||||
|
||||
private function update_item_stok($item_id)
|
||||
{
|
||||
$stok = $this->db->query("
|
||||
SELECT COALESCE(SUM(qty * IF(tipe='masuk',1,-1)),0) as stok
|
||||
FROM stock_logs
|
||||
WHERE item_id = ?
|
||||
", [$item_id])->row()->stok;
|
||||
|
||||
$this->db->where('id', $item_id)
|
||||
->update('items', [
|
||||
'stok' => $stok
|
||||
]);
|
||||
}
|
||||
|
||||
public function get_items_by_wh_id($warehouse_id)
|
||||
{
|
||||
$this->db->select('
|
||||
items.id,
|
||||
items.nama_barang,
|
||||
items.harga_jual,
|
||||
items.kode_detail,
|
||||
COALESCE(SUM(
|
||||
stock_logs.qty * IF(stock_logs.tipe="masuk",1,-1)
|
||||
),0) as stok
|
||||
');
|
||||
$this->db->where('status', 'active');
|
||||
$this->db->from('items');
|
||||
|
||||
$this->db->join('stock_logs',
|
||||
'stock_logs.item_id = items.id
|
||||
AND stock_logs.warehouse_id = '.$this->db->escape($warehouse_id),
|
||||
'left');
|
||||
|
||||
$this->db->group_by('items.id');
|
||||
|
||||
// ✅ INI KUNCINYA
|
||||
$this->db->having('stok >', 0);
|
||||
|
||||
|
||||
$data = $this->db->get()->result();
|
||||
|
||||
echo json_encode($data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user