207 lines
11 KiB
PHP
207 lines
11 KiB
PHP
<?php
|
|
|
|
/*******************************************************************
|
|
|
|
PHP Class : /Controller/Inv/OpnamebarangController
|
|
Description : Transaksi Penyesuaian Stok Per Barang
|
|
Created By : Siau Pheng ([email protected]).
|
|
Created Date : October 22nd, 2014.
|
|
Last Modified : November 4th, 2026.
|
|
|
|
(c) 3FONIA Software; WWW.3FONIA.COM.
|
|
|
|
*******************************************************************/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Controller\Inv;
|
|
|
|
use App\Utils\Inv;
|
|
use App\Utils\Gel;
|
|
use flight\Engine;
|
|
use flight\database\SimplePdo;
|
|
use flight\Session;
|
|
use Webapp\DB\SQL;
|
|
use Webapp\Web\Form;
|
|
use Webapp\Web\Param;
|
|
use Webapp\Web\Table;
|
|
|
|
class OpnamebarangController {
|
|
|
|
private array $app_gel;
|
|
private int $id_cab;
|
|
private Inv $inv;
|
|
private Gel $gel;
|
|
protected Engine $app;
|
|
protected SimplePdo $db;
|
|
|
|
public function __construct(Engine $app, SimplePdo $db, Session $session) {
|
|
$this->app = $app;
|
|
$this->db = $db;
|
|
$this->app_gel = (array) $session->get('APP_GEL');
|
|
$this->id_cab = $session->get('APP_INV')['CABANGID'];
|
|
$this->inv = new Inv($app);
|
|
$this->gel = new Gel($app);
|
|
}
|
|
|
|
public function brow_produk() {
|
|
$tcari = Param::Get("Cari_Produk");
|
|
$tsql = ''; $asql = [];
|
|
if (!empty($tcari)) {
|
|
$tsql .= " AND Barcode_Nama LIKE ?";
|
|
array_push($asql, '%' . $tcari . '%');
|
|
}
|
|
array_push($asql, $this->id_cab);
|
|
|
|
$obj = new Table($this->app);
|
|
$obj->set_table("(SELECT * FROM inv_produk_join WHERE Aktif=1".$tsql." GROUP BY InvID,SatuanID,VarianID) P LEFT JOIN inv_stok X ON (X.CabID=? AND X.InvID=P.InvID)", "P.*,IF(IFNULL(X.Stok,0)=0,0,ROUND(X.Stok/P.Qty,2)) Sisa_Stok", "", $asql);
|
|
$obj->add_field("InvID", "ID", "hid");
|
|
$obj->add_field("SatuanID", "ID", "hid");
|
|
$obj->add_field("VarianID", "ID", "hid");
|
|
$obj->add_field("Kode_SKU", "SKU", "c");
|
|
$obj->add_field("Kode_Barcode", "Barcode", "c");
|
|
$obj->add_field("Nama_Lengkap", "Nama Barang", "awr");
|
|
$obj->add_field("Satuan_Kemasan", "Satuan", "hid");
|
|
$obj->add_field("Harga_Pokok", "HPP", "hid");
|
|
$obj->add_field("Sisa_Stok", "Stok", "r", "rupiah2");
|
|
$obj->add_field("PPN", "PPN", "hid");
|
|
$obj->set_field_order("Kode_SKU", "A");
|
|
$obj->set_func_select("OpnameBarangJS.produk_select");
|
|
$this->app->json([ $obj->db_table("divBrowProduk") ]);
|
|
}
|
|
|
|
public function auto_produk() {
|
|
$tcari = Param::Get("Auto_Query", "");
|
|
$ajson['autodata'] = [];
|
|
$bcode = 0; $arec = [];
|
|
|
|
// Cari by SKU + Barcode
|
|
// Satuan : Varian : SKU + Barcode : Harga_Pokok : Satuan : PPN : Stok
|
|
if ($bcode === 0) {
|
|
$_row = $this->db->fetchRow("SELECT P.InvID,P.Nama_Lengkap,CONCAT(P.SatuanID,':',P.VarianID,':',P.Kode_SKU,' / ',P.Kode_Barcode,':',CONVERT(P.Harga_Pokok USING UTF8),':',P.Satuan_Kemasan,':',P.PPN,':',CONVERT(FORMAT(IF(IFNULL(X.Stok,0)=0,0,ROUND(X.Stok/P.Qty,2)),2) USING UTF8)) Data2 FROM (SELECT * FROM inv_produk_join WHERE Aktif=1 AND (Kode_SKU=? OR Kode_Barcode=?) GROUP BY InvID,SatuanID,VarianID) P LEFT JOIN inv_stok X ON (X.CabID=? AND X.InvID=P.InvID)", [$tcari, $tcari, $this->id_cab]);
|
|
if ($_row) {
|
|
$bcode = 1;
|
|
$arec = $_row->getData();
|
|
}
|
|
}
|
|
|
|
if ($bcode === 1) {
|
|
$ajson['autodata'][] = ['value'=>$arec['InvID'], 'text'=>$arec['Nama_Lengkap'], 'data'=>$arec['Data2'], 'bc'=>1];
|
|
} else {
|
|
$stat = $this->db->runQuery("SELECT P.InvID,P.Nama_Lengkap,P.Kode_SKU,IF(IFNULL(X.Stok,0)=0,'KOSONG',ROUND(X.Stok/P.Qty,2)) Sisa_Stok,CONCAT(P.SatuanID,':',P.VarianID,':',P.Kode_SKU,' / ',P.Kode_Barcode,':',CONVERT(P.Harga_Pokok USING UTF8),':',P.Satuan_Kemasan,':',P.PPN,':',CONVERT(FORMAT(IF(IFNULL(X.Stok,0)=0,0,ROUND(X.Stok/P.Qty,2)),2) USING UTF8)) Data2 FROM (SELECT * FROM inv_produk_join WHERE Barcode_Nama LIKE ? AND Aktif=1 GROUP BY InvID,SatuanID,VarianID) P LEFT JOIN inv_stok X ON (X.CabID=? AND X.InvID=P.InvID) ORDER BY P.Nama_Produk,P.Qty LIMIT 50", ['%'.$tcari.'%', $this->id_cab]);
|
|
while ($row = $stat->fetch(SimplePdo::FETCH_ASSOC)) {
|
|
$ajson['autodata'][] = ['value'=>$row['InvID'], 'text'=>$row['Nama_Lengkap'], 'html'=>'<span class="text-primary">'.$row['Kode_SKU'].'</span> '.$row['Nama_Lengkap'].' <span class="text-danger">('.(string) $row['Sisa_Stok'].')</span>', 'data'=>$row['Data2'], 'bc'=>0];
|
|
}
|
|
}
|
|
$this->app->json($ajson);
|
|
}
|
|
|
|
public function scan_produk() {
|
|
$tcari = Param::Get("Cari_Produk", "");
|
|
$scandata = [ 'InvID'=>0, 'SatuanID'=>0, 'VarianID'=>0, 'Kode_Barang'=>"KODE_SKU / KODE_BARCODE", 'Nama_Barang'=>"NAMA_BARANG", 'Nama_Satuan'=>"SATUAN", 'PPN'=>0, 'Harga_Beli'=>0, 'Stok_Sistem'=>0 ];
|
|
|
|
// Cari by SKU + Barcode
|
|
// Satuan : Varian : SKU + Barcode : Harga_Pokok : Satuan : PPN : Stok
|
|
$_row = $this->db->fetchRow("SELECT P.InvID,P.SatuanID,P.VarianID,P.Nama_Lengkap Nama_Barang,CONCAT(P.Kode_SKU,' / ',P.Kode_Barcode) Kode_Barang,P.Harga_Pokok Harga_Beli,P.Satuan_Kemasan Nama_Satuan,P.PPN,FORMAT(IFNULL(X.Stok,0),2) Stok_Sistem FROM (SELECT * FROM inv_produk_join WHERE Aktif=1 AND (Kode_SKU=? OR Kode_Barcode=?) GROUP BY InvID,SatuanID,VarianID) P LEFT JOIN inv_stok X ON (X.CabID=? AND X.InvID=P.InvID)", [$tcari, $tcari, $this->id_cab]);
|
|
if ($_row) $scandata = array_merge($scandata, $_row->getData());
|
|
$this->app->json( $scandata );
|
|
}
|
|
|
|
public function proses_simpan() {
|
|
$no_opname = "";
|
|
$id_inv = Param::Int("InvID", 0);
|
|
$id_satuan = Param::Int("SatuanID", 0);
|
|
$qty = Param::Float("Stok_Fisik", 0);
|
|
$hpp = Param::Float("Harga_Beli", 0);
|
|
|
|
$no_opname = $this->db->fetchField("SELECT No_Opname FROM inv_opname WHERE Tgl_Opname=CURDATE() AND CabID=? AND UserID=? ORDER BY No_Opname DESC", [$this->id_cab, $this->app->user()->id()]) ?? '';
|
|
if (empty($no_opname)) {
|
|
$no_opname = $this->inv->Nomor_Baru("O", tgl_dmy(), true);
|
|
$this->db->runQuery("UPDATE inv_opname SET Tgl_Opname=CURDATE(), CabID=?, Catatan=?, UserID=? WHERE No_Opname=?", [$this->id_cab, 'OPNAME USER : '.$this->app->user()->username().' - '.$this->app->user()->nama(), $this->app->user()->id(), $no_opname]);
|
|
}
|
|
|
|
$_qty = $this->db->fetchField("SELECT SUM(Stok) Stok FROM inv_detail WHERE Tgl_Ref<=? AND CabID=? AND InvID=?", [tgl_ymd(), $this->id_cab, $id_inv]) ?? 0;
|
|
$qty -= $_qty;
|
|
|
|
$_stok = (float) $this->db->fetchField("SELECT Qty FROM inv_produk_kemasan WHERE InvID=? AND SatuanID=?", [$id_inv, $id_satuan]) ?? 1;
|
|
$stok = $_stok * $qty;
|
|
|
|
$sql = new SQL($this->app);
|
|
$sql->set_table("inv_detail");
|
|
$sql->add_param("No_Ref", $no_opname);
|
|
$sql->add_param("Tgl_Ref", "CURDATE()", true);
|
|
$sql->add_param("NotaID", 1);
|
|
$sql->add_param("CabID", $this->id_cab);
|
|
$sql->add_param("InvID");
|
|
$sql->add_param("SatuanID");
|
|
$sql->add_param("VarianID");
|
|
$sql->add_param("Qty", $qty);
|
|
$sql->add_param("Stok", $stok);
|
|
$sql->add_param("Harga_Beli", $hpp);
|
|
$sql->add_param("Harga_Jual", "Harga_Beli", true);
|
|
$sql->add_param("PPN");
|
|
$sql->add_param_userid();
|
|
$sql->InsertDB();
|
|
|
|
$tot_opname = $this->db->fetchField("SELECT SUM(Qty*Harga_Beli) Opname FROM inv_detail WHERE No_Ref=?", [$no_opname]) ?? 0;
|
|
if ($tot_opname > 0) {
|
|
$this->db->runQuery("UPDATE inv_opname SET Total_Opname=? WHERE No_Opname=?", [$tot_opname, $no_opname]);
|
|
|
|
// PROSES POSTING GL
|
|
$ajurnal = [
|
|
'Kode_Jurnal' => $no_opname,
|
|
'TipeID' => 12,
|
|
'CabID' => $this->id_cab,
|
|
'Tanggal' => tgl_dmy(),
|
|
'Kode_Ref' => $no_opname,
|
|
'Catatan' => "Opname Stok / Penyesuaian : ".$no_opname." - ".tgl_dmy()
|
|
];
|
|
$_dkD = ($tot_opname > 0) ? "K" : "D";
|
|
$_dkK = ($tot_opname < 0) ? "K" : "D";
|
|
$adetail = [
|
|
[ 'Kode_Rek' => $this->app_gel['HPP'], 'DK' => $_dkD, 'Jumlah' => $tot_opname ],
|
|
[ 'Kode_Rek' => $this->app_gel['STOK'], 'DK' => $_dkK, 'Jumlah' => $tot_opname ]
|
|
];
|
|
$this->gel->Jurnal_Post($ajurnal, $adetail);
|
|
}
|
|
$this->app->json([ 'status' => true ]);
|
|
}
|
|
|
|
public function index() {
|
|
$form = new Form($this->app);
|
|
$tbrg = $form->textauto("_", "Nama_Produk", ['value'=>0, 'text'=>""], true, true, "Scan SKU / Barcode / Ketik Nama Barang");
|
|
$tkode = $form->textbox("_", "Kode_Barang", "KODE_SKU / KODE_BARCODE", false);
|
|
$tnama = $form->textbox("_", "Nama_Barang", "NAMA_BARANG", false);
|
|
$tsat = $form->textbox("_", "Nama_Satuan", "SATUAN", false);
|
|
$tssis = $form->textbox("_", "Stok_Sistem", "0", false, false, "double");
|
|
$tsfis = $form->textbox("_", "Stok_Fisik", "0", true, false, "double");
|
|
$ajson['html'] = '';
|
|
if (isMobile()) {
|
|
$ajson['html'] .= '
|
|
<div class="row mb-1"><div class="col"><div id="qr-reader"></div></div></div>
|
|
<hr class="my-2">
|
|
<div class="row mb-1"><div class="col-sm-3 col-lg-3 col-form-label">Kode SKU / Barcode</div><div class="col"><div class="input-group">'.$tkode.'<button class="btn btn-info shadow-none" type="button" id="butBrow"><i class="bi-search"></i></button></div></div></div>
|
|
';
|
|
} else {
|
|
$ajson['html'] .= '
|
|
<div class="row mb-1"><div class="col-sm-3 col-lg-3 col-form-label">Kunci Pencarian</div><div class="col"><div class="input-group">'.$tbrg.'<button class="btn btn-info shadow-none" type="button" id="butBrow"><i class="bi-search"></i></button></div></div></div>
|
|
<hr class="my-2">
|
|
<div class="row mb-1"><div class="col-sm-3 col-lg-3 col-form-label">Kode SKU / Barcode</div><div class="col">'.$tkode.'</div></div>
|
|
';
|
|
}
|
|
|
|
$ajson['html'] .= '
|
|
<div class="row mb-1"><div class="col-sm-3 col-lg-3 col-form-label">Nama Barang</div><div class="col">'.$tnama.'</div></div>
|
|
<div class="row mb-1"><div class="col-sm-3 col-lg-3 col-form-label">Satuan</div><div class="col">'.$tsat.'</div></div>
|
|
<div class="row mb-1"><div class="col-sm-3 col-lg-3 col-form-label">Stok Sistem</div><div class="col-sm-9 col-lg-5">'.$tssis.'</div></div>
|
|
<div class="row mb-1"><div class="col-sm-3 col-lg-3 col-form-label">Stok Fisik</div><div class="col-sm-9 col-lg-5">'.$tsfis.'</div></div>
|
|
<input type="hidden" id="InvID" value="0" />
|
|
<input type="hidden" id="SatuanID" value="0" />
|
|
<input type="hidden" id="VarianID" value="0" />
|
|
<input type="hidden" id="Harga_Beli" value="0" />
|
|
<input type="hidden" id="PPN" value="0" />';
|
|
$this->app->json($ajson);
|
|
}
|
|
|
|
}
|