first commit
This commit is contained in:
@@ -0,0 +1,581 @@
|
||||
<?php
|
||||
|
||||
/*******************************************************************
|
||||
|
||||
PHP Class : /Controller/Inv/BeliController
|
||||
Description : Transaksi Pembelian
|
||||
Created By : Siau Pheng ([email protected]).
|
||||
Created Date : May 22th, 2010.
|
||||
Last Modified : September 20th, 2026.
|
||||
|
||||
(c) 3FONIA Software; WWW.3FONIA.COM.
|
||||
|
||||
*******************************************************************/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller\Inv;
|
||||
|
||||
use App\Utils\Inv;
|
||||
use App\Utils\Gel;
|
||||
use App\Utils\Invesa;
|
||||
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 BeliController {
|
||||
|
||||
private array $web_app;
|
||||
private array $app_gel;
|
||||
private int $id_cab;
|
||||
private string $mode;
|
||||
private string $mode_detail;
|
||||
private string $no_beli;
|
||||
private bool $is_pend;
|
||||
private int $id_inv;
|
||||
private int $id_satuan;
|
||||
private int $id_varian;
|
||||
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->web_app = (array) $session->get('WEB_APP');
|
||||
$this->app_gel = (array) $session->get('APP_GEL');
|
||||
$this->id_cab = Param::Int("CabID", $session->get('APP_INV')['CABANGID']);
|
||||
$this->mode = Param::Get("mode", "");
|
||||
$this->mode_detail = Param::Get("mode_detail", "");
|
||||
$this->no_beli = Param::Get("No_Beli", "");
|
||||
$this->is_pend = str_contains($this->no_beli, "BELI") === true;
|
||||
$this->id_inv = Param::Int("InvID", 0);
|
||||
$this->id_satuan = Param::Int("SatuanID", 0);
|
||||
$this->id_varian = Param::Int("VarianID", 0);
|
||||
$this->inv = new Inv($app);
|
||||
$this->gel = new Gel($app);
|
||||
}
|
||||
|
||||
public function table_detail() {
|
||||
if (in_array($this->mode_detail, ["insert","update","delete"])) {
|
||||
$iqty = Param::Float("Qty", 0);
|
||||
|
||||
$sql = new SQL($this->app);
|
||||
$sql->set_table("tmp_inv_detail");
|
||||
$sql->add_param("No_Ref", $this->no_beli);
|
||||
$sql->add_param("InvID");
|
||||
$sql->add_param("SatuanID");
|
||||
$sql->add_param("VarianID");
|
||||
$sql->add_param("Qty", $iqty);
|
||||
$sql->add_param("Harga_Beli");
|
||||
$sql->add_param("Disk_Rupiah");
|
||||
$sql->add_param("Disk_Persen1");
|
||||
$sql->add_param("Disk_Persen2");
|
||||
$sql->add_param("Disk_Persen3");
|
||||
$sql->add_param("Disk_Persen4");
|
||||
$sql->add_param("Disk_Persen5");
|
||||
$sql->add_param("Total_Diskon", "(Harga_Beli-((Harga_Beli-Disk_Rupiah)*((100.0-Disk_Persen1)/100)*((100.0-Disk_Persen2)/100)*((100.0-Disk_Persen3)/100)*((100.0-Disk_Persen4)/100)*((100.0-Disk_Persen5)/100)))*Qty", true);
|
||||
$sql->add_param_unix();
|
||||
$sql->add_param_userid();
|
||||
$sql->add_where("ID");
|
||||
$sql->add_where("No_Ref", $this->no_beli);
|
||||
|
||||
$_id = Param::Get("ID", 0);
|
||||
if ( $this->mode_detail === "insert" ) {
|
||||
$sql->InsertDB();
|
||||
$_id = $sql->LastInsertID("ID");
|
||||
} else if ( $this->mode_detail === "update" ) {
|
||||
$sql->UpdateDB();
|
||||
} else if ( $this->mode_detail === "delete" ) {
|
||||
$sql->DeleteDB();
|
||||
}
|
||||
}
|
||||
|
||||
$tsql = ''; $asql = [$this->no_beli]; $qtabel = "inv_detail";
|
||||
if ($this->is_pend) $qtabel = "tmp_inv_detail";
|
||||
if (in_array($this->mode, ["add","edit"])) {
|
||||
if ($this->mode === "add") { $tsql = " AND Unix=?"; $asql[] = $this->app->user()->unix(); }
|
||||
$qtabel = "tmp_inv_detail";
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("(SELECT * FROM ".$qtabel." WHERE No_Ref=?".$tsql.") D LEFT JOIN vi_inv_produk P ON (D.InvID=P.InvID AND D.SatuanID=P.SatuanID AND D.VarianID=P.VarianID)", "D.*,P.Kode_SKU,P.Nama_Lengkap,(D.Qty*D.Harga_Beli)-D.Total_Diskon Total", "", $asql);
|
||||
$obj->set_footer("SUM((D.Qty*D.Harga_Beli)-D.Total_Diskon) Total,SUM(D.Total_Diskon) Total_Diskon");
|
||||
$obj->add_field("ID", "No", "c");
|
||||
$obj->add_field("InvID", "InvID", "hid");
|
||||
$obj->add_field("SatuanID", "SatuanID", "hid");
|
||||
$obj->add_field("VarianID", "VarianID", "hid");
|
||||
$obj->add_field("Kode_SKU", "SKU", "c");
|
||||
$obj->add_field("Nama_Lengkap", "Nama Barang", "awr");
|
||||
$obj->add_field("Qty", "Qty", "r", "rupiah2");
|
||||
$obj->add_field("Harga_Beli", "Harga @", "r", "rupiah");
|
||||
$obj->add_field("Total_Diskon", "Diskon", "r", "rupiah", "rupiah");
|
||||
$obj->add_field("Total", "Jumlah", "r", "rupiah", "rupiah");
|
||||
$obj->set_field_order("ID", "D");
|
||||
if (in_array($this->mode, ["add","edit"])) {
|
||||
$obj->add_row_btn("clipboard", "Ubah", "BeliJS.detail_ubah");
|
||||
$obj->add_row_btn("trash", "Hapus", "BeliJS.detail_hapus", "Unix", $this->app->user()->unix());
|
||||
$obj->set_func_btn("BeliJS.detail_tambah", '<i class="bi-plus-lg me-1"></i> Barang');
|
||||
$obj->set_func_btn("BeliJS.produk_brow", '<i class="bi-table me-1"></i> Browse');
|
||||
}
|
||||
$obj->set_func_btn("BeliJS.total_show", "Total");
|
||||
$ajson[] = $obj->json_table("divDetailTabel");
|
||||
|
||||
if (in_array($this->mode, ["add","pending-edit"])) {
|
||||
$ajual = $this->db->fetchRow("SELECT SUM((Qty*Harga_Beli)-Total_Diskon) Jumlah,SUM(Total_Diskon) Diskon FROM ".$qtabel." WHERE No_Ref=?".$tsql, $asql) ?? ['Jumlah'=>0, 'Diskon'=>0];
|
||||
$ajson[] = ['type'=>"form", 'id'=>"Real_Beli", 'value'=>$ajual['Jumlah']];
|
||||
$ajson[] = ['type'=>"form", 'id'=>"Real_Diskon", 'value'=>$ajual['Diskon']];
|
||||
}
|
||||
if (in_array($this->mode_detail, ["insert","update"])) {//WARNING: harga jual dibawah limit margin!!
|
||||
$hbeli = (float) $this->db->fetchField("SELECT CEIL(Harga_Beli-(Total_Diskon/Qty)) Pokok FROM tmp_inv_detail WHERE No_Ref=? AND ID=?", [$this->no_beli, $_id]) ?? 0;
|
||||
$_row = $this->db->fetchRow("SELECT P.Nama_Produk,H.*,G.Margin FROM (SELECT * FROM inv_produk_harga WHERE InvID=? AND SatuanID=? AND Harga_Jual>0 ORDER BY Harga_Jual ASC LIMIT 1) H LEFT JOIN (SELECT * FROM inv_produk WHERE InvID=?) P ON (H.InvID=P.InvID) LEFT JOIN inv_produk_grup G ON (P.Grup_InvID=G.Grup_InvID)", [$this->id_inv, $this->id_satuan, $this->id_inv]);
|
||||
if ($_row) {
|
||||
if ((float) $_row['Margin'] > 0) $hbeli += ($hbeli*((float) $_row['Margin']/100));
|
||||
if ($hbeli > (float) $_row['Harga_Jual']) $ajson[] = ['type'=>"msg", 'mode'=>"error", 'wait'=>3000, 'value'=>"Produk \"".$_row['Nama_Produk']."\" Harga Beli telah melewati Margin Harga Jual!"];
|
||||
}
|
||||
}
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function brow_tx() {
|
||||
$tcari = Param::Get("Cari_TX");
|
||||
$tsql = ''; $asql = [];
|
||||
if (!empty($tcari)) {
|
||||
$tsql .= "CONCAT(B.No_Beli,B.No_Faktur,S.Nama_Sup,DATE_FORMAT(B.Tgl_Faktur,'%d-%m-%Y')) LIKE ?";
|
||||
$asql[] = '%' . $tcari . '%';
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("(SELECT *,Total_Beli-Total_Diskon Jumlah FROM inv_beli WHERE Data_Beli=1) B LEFT JOIN para_supplier S ON (B.SupID=S.SupID) LEFT JOIN para_cabang C ON (C.CabID=B.CabID)", "B.*,S.Nama_Sup,C.Kode_Cab", $tsql, $asql);
|
||||
$obj->add_field("No_Beli", "No. Trans", "c");
|
||||
$obj->add_field("Tgl_Beli", "Tgl. Trans", "c", "sqltgl", "", "val-tgl");
|
||||
$obj->add_field("Kode_Cab", "Cabang", "c");
|
||||
$obj->add_field("Nama_Sup", "Nama Supplier", "awr");
|
||||
$obj->add_field("Total_Beli", "Sub. Total", "r", "rupiah2");
|
||||
$obj->add_field("Total_Diskon", "Diskon", "r", "rupiah2");
|
||||
$obj->add_field("Jumlah", "Jumlah", "r", "rupiah2");
|
||||
$obj->set_field_order("Tgl_Beli", "D");
|
||||
$obj->set_func_select("BeliJS.tx_select");
|
||||
$this->app->json([ $obj->db_table("divBrowTX") ]);
|
||||
}
|
||||
|
||||
public function brow_pending() {
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("(SELECT *,Total_Beli-Total_Diskon Jumlah FROM inv_beli_pend WHERE UserID=?) B LEFT JOIN para_supplier S ON (B.SupID=S.SupID) LEFT JOIN para_cabang C ON (C.CabID=B.CabID)", "B.*,S.Nama_Sup,C.Kode_Cab", "", [$this->app->user()->id()]);
|
||||
$obj->add_field("No_Beli", "No. Trans", "c");
|
||||
$obj->add_field("Tgl_Beli", "Tgl. Pending", "c", "sqltgl", "", "val-tgl");
|
||||
$obj->add_field("Kode_Cab", "Cabang", "c");
|
||||
$obj->add_field("Nama_Sup", "Nama Supplier", "awr");
|
||||
$obj->add_field("Total_Beli", "Sub. Total", "r", "rupiah2");
|
||||
$obj->add_field("Total_Diskon", "Diskon", "r", "rupiah2");
|
||||
$obj->add_field("Jumlah", "Jumlah", "r", "rupiah2");
|
||||
$obj->set_field_order("No_Beli", "D");
|
||||
$obj->add_row_btn("save", "Pilih", "BeliJS.pending_select");
|
||||
if ($this->app->user()->is_level(1)) $obj->add_row_btn("trash", "Hapus", "BeliJS.pending_delete", "UserID", $this->app->user()->id());
|
||||
$this->app->json([ $obj->db_table("divBrowPending") ]);
|
||||
}
|
||||
|
||||
public function brow_produk() {
|
||||
$tcari = Param::Get("Cari_Produk");
|
||||
$tsql = ''; $asql = [1];
|
||||
if (!empty($tcari)) {
|
||||
$tsql .= " AND P.Barcode_Nama LIKE ?";
|
||||
$asql[] = '%' . $tcari . '%';
|
||||
}
|
||||
if ((string) Param::Get("Filter_Browse", "") !== "all") {
|
||||
$tsql .= " AND S.SupID=?";
|
||||
array_push($asql, Param::Get("SupID"));
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("vi_inv_produk P LEFT JOIN inv_produk_sup S ON (P.InvID=S.InvID)", "P.*", "P.Aktif=?".$tsql, $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->set_field_order("Kode_SKU", "A");
|
||||
$obj->set_func_select("BeliJS.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
|
||||
$_row = $this->db->fetchRow("SELECT V.InvID,P.Nama_Produk,CONCAT(V.SatuanID,':',V.VarianID,':',S.Nama_Satuan) Data2 FROM (SELECT * FROM inv_produk_varian WHERE Kode_SKU=? OR Kode_Barcode=? LIMIT 1) V LEFT JOIN inv_produk P ON (P.InvID=V.InvID) LEFT JOIN para_satuan S ON (S.SatuanID=V.SatuanID) WHERE P.Aktif=1", [$tcari, $tcari]);
|
||||
if ($_row) {
|
||||
$bcode = 1;
|
||||
$arec = $_row->getData();
|
||||
}
|
||||
|
||||
if ($bcode === 1) {
|
||||
$ajson['autodata'][] = ['value'=>$arec['InvID'], 'text'=>$arec['Nama_Produk'], 'data'=>$arec['Data2'], 'bc'=>1];
|
||||
} else {
|
||||
$stat = $this->db->runQuery("SELECT P.InvID,P.Nama_Produk,V.Kode_SKU,IFNULL(MV.Nama_Varian,'') Nama_Varian,MS.Nama_Satuan,CONCAT(V.SatuanID,':',V.VarianID,':',MS.Nama_Satuan) Data2 FROM (SELECT * FROM inv_produk WHERE Nama_Produk LIKE ? AND Aktif=1) P INNER JOIN inv_produk_varian V ON (V.InvID=P.InvID) LEFT JOIN para_satuan MS ON (MS.SatuanID=V.SatuanID) LEFT JOIN para_varian MV ON (MV.VarianID=V.VarianID) ORDER BY P.Nama_Produk,MS.Nama_Satuan LIMIT 50", ['%'.$tcari.'%']);
|
||||
while ($row = $stat->fetch(SimplePdo::FETCH_ASSOC)) {
|
||||
$ajson['autodata'][] = ['value'=>$row['InvID'], 'text'=>$row['Nama_Produk'], 'html'=>'<span class="text-primary">'.$row['Kode_SKU'].'</span> '.$row['Nama_Produk']." ".$row['Nama_Varian']." ".$row['Nama_Satuan'], 'data'=>$row['Data2'], 'bc'=>0];
|
||||
}
|
||||
}
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function form_master() {
|
||||
$ajson = [ 'error'=>"", 'html'=>"" ];
|
||||
$atabel = [];
|
||||
|
||||
if ($this->mode === "pending-edit") {
|
||||
$this->inv->Pending_Edit($this->no_beli);
|
||||
$atabel = $this->Data_Beli($this->no_beli);
|
||||
$this->mode = "edit";
|
||||
} else if ($this->mode === "pending-save") {
|
||||
$b_baru = false;
|
||||
if (str_ends_with($this->no_beli, "#00")) {
|
||||
$b_baru = true;
|
||||
$no_lama = $this->no_beli;
|
||||
$this->no_beli = $this->Pending_Nomor();
|
||||
$this->inv->Pending_Save($no_lama, $this->no_beli);
|
||||
}
|
||||
$apending = $this->db->fetchRow("SELECT SUM(Qty*Harga_Beli) Beli,SUM(Total_Diskon) Diskon FROM tmp_inv_detail WHERE No_Ref=?", [$this->no_beli]) ?? ['Beli'=>0, 'Diskon'=>0];
|
||||
|
||||
$sql = new SQL($this->app);
|
||||
$sql->set_table("inv_beli_pend");
|
||||
$sql->add_param("No_Beli", $this->no_beli);
|
||||
$sql->add_param_date("Tgl_Beli");
|
||||
$sql->add_param_date("Tgl_Faktur");
|
||||
$sql->add_param("No_Faktur");
|
||||
$sql->add_param("CabID");
|
||||
$sql->add_param("SupID");
|
||||
$sql->add_param("Total_Beli", $apending['Beli']);
|
||||
$sql->add_param("Total_Diskon", $apending['Diskon']);
|
||||
$sql->add_param("Real_Beli");
|
||||
$sql->add_param("Real_Diskon");
|
||||
$sql->add_param("PPN");
|
||||
$sql->add_param_userid();
|
||||
$sql->add_where("No_Beli", $this->no_beli);
|
||||
if ($b_baru) $sql->InsertDB();
|
||||
else $sql->UpdateDB();
|
||||
$atabel = $this->Data_Beli();
|
||||
} else if ($this->mode === "pending-delete") {
|
||||
$this->inv->Pending_Delete($this->no_beli);
|
||||
$this->db->delete("inv_beli_pend", "No_Beli=?", [$this->no_beli]);
|
||||
$atabel = $this->Data_Beli();
|
||||
} else if ($this->mode === "add") {
|
||||
$atabel = $this->Data_Beli("", true);
|
||||
} else if ($this->mode === "edit") {
|
||||
$this->inv->Detail_Copy($this->no_beli, true);
|
||||
$atabel = $this->Data_Beli($this->no_beli);
|
||||
} else if ($this->mode === "save") {
|
||||
$no_lama = $this->no_beli;
|
||||
if ($this->is_pend) {
|
||||
$this->no_beli = $this->inv->Nomor_Baru("B", Param::Get("Tgl_Beli"), true);
|
||||
if (!str_ends_with($no_lama, "#00")) $this->db->delete("inv_beli_pend", "No_Beli=?", [$no_lama]);
|
||||
}
|
||||
$this->inv->Detail_Save($this->no_beli, 3, $this->id_cab, Param::Get("Tgl_Beli"), $this->is_pend, $no_lama, Param::Int("PPN", 0));
|
||||
|
||||
$abeli = $this->db->fetchRow("SELECT SUM(Qty*Harga_Beli) Beli, SUM(Total_Diskon) Diskon FROM inv_detail WHERE No_Ref=?", [$this->no_beli]) ?? ['Beli'=>0, 'Diskon'=>0];
|
||||
|
||||
$sql = new SQL($this->app);
|
||||
$sql->set_table("inv_beli");
|
||||
$sql->add_param_date("Tgl_Beli");
|
||||
$sql->add_param_date("Tgl_Faktur");
|
||||
$sql->add_param("No_Faktur");
|
||||
$sql->add_param("CabID");
|
||||
$sql->add_param("SupID");
|
||||
$sql->add_param("Total_Beli", $abeli['Beli']);
|
||||
$sql->add_param("Total_Diskon", $abeli['Diskon']);
|
||||
$sql->add_param("Real_Beli");
|
||||
$sql->add_param("Real_Diskon");
|
||||
$sql->add_param("PPN");
|
||||
$sql->add_param("Data_Beli", 1);
|
||||
$sql->add_param_stamp();
|
||||
$sql->add_param_userid();
|
||||
$sql->add_where("No_Beli", $this->no_beli);
|
||||
$sql->UpdateDB();
|
||||
|
||||
$this->inv->Produk_Update($this->no_beli, Param::Int("SupID", 0));
|
||||
$this->gel->Update_Lunas_Sup(Param::Int("SupID", 0));
|
||||
|
||||
// PROSES POSTING GL
|
||||
$ainfo = $this->db->fetchRow("SELECT B.*,S.Nama_Sup,B.Real_Beli Tagihan FROM (SELECT * FROM inv_beli WHERE No_Beli=?) B LEFT JOIN para_supplier S ON (S.SupID=B.SupID)", [$this->no_beli]);
|
||||
if (count($ainfo) > 0) {
|
||||
$ajurnal = [
|
||||
'Kode_Jurnal' => $ainfo['No_Beli'],
|
||||
'TipeID' => 5,
|
||||
'CabID' => $ainfo['CabID'],
|
||||
'Tanggal' => tgl_sql2str($ainfo['Tgl_Beli']),
|
||||
'Kode_Ref' => $ainfo['No_Beli'],
|
||||
'Catatan' => "Pembelian : ".$ainfo['No_Beli'].(($ainfo['No_Faktur']=="")?"":" (Faktur : ".$ainfo['No_Faktur'].") ")." / ".$ainfo['Nama_Sup']
|
||||
];
|
||||
$adetail = [
|
||||
[
|
||||
'Kode_Rek' => $this->app_gel['STOK'],
|
||||
'DK' => "D",
|
||||
'Jumlah' => $ainfo['Tagihan']
|
||||
],
|
||||
[
|
||||
'Kode_Rek' => $this->app_gel['HUT_USAHA'],
|
||||
'DK' => "K",
|
||||
'Jumlah' => $ainfo['Tagihan'],
|
||||
'SupID' => $ainfo['SupID']
|
||||
]
|
||||
];
|
||||
$this->gel->Jurnal_Post($ajurnal, $adetail);
|
||||
}
|
||||
$atabel = $this->Data_Beli($this->no_beli);
|
||||
$this->mode = "view";
|
||||
|
||||
} else if ($this->mode === "cancel") {
|
||||
if (str_ends_with($this->no_beli, "#00") || !$this->is_pend) $this->inv->Detail_Cancel($this->no_beli);
|
||||
$atabel = $this->Data_Beli();
|
||||
} else {
|
||||
$atabel = $this->Data_Beli($this->no_beli);
|
||||
}
|
||||
|
||||
$enable = in_array($this->mode, ["add","edit"]) ? true : false;
|
||||
$form = new Form($this->app);
|
||||
$tnota = $form->textbox("_", "No_Beli", $atabel['No_Beli'], !$enable, true, "text", "nomor transaksi");
|
||||
$tfaktur = $form->textbox("_", "No_Faktur", $atabel['No_Faktur'], $enable, true, "text", "nomor faktur");
|
||||
$ttglnota = $form->datebox("_", "Tgl_Beli", $atabel['Tgl_Beli'], $enable, true);
|
||||
$ttglfaktur = $form->datebox("_", "Tgl_Faktur", $atabel['Tgl_Faktur'], $enable, true);
|
||||
$tcab = $form->option_db("_", "CabID", $atabel['CabID'], $enable, false, "para_cabang", ["CabID","Nama_Cab"], "Aktif=1 ORDER BY Nama_Cab", [0," "]);
|
||||
$tsup = $form->option_db("_", "SupID", $atabel['SupID'], $enable, false, "para_supplier", ["SupID","Nama_Sup"], "Aktif=1 ORDER BY Nama_Sup", [0," "]);
|
||||
$tppn = '<button class="btn btn-secondary" type="button" disabled="">'.Invesa::PPN_Array()[$atabel['PPN']].'</button>';
|
||||
if ($enable) {
|
||||
$tppn = $form->option("_", "PPN", $atabel['PPN'], true, false, Invesa::PPN_Array());
|
||||
$tppn = str_replace("option-tags", "", $tppn);
|
||||
}
|
||||
$ajson['html'] = '
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-lg-6">
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="No_Beli">Nomor Transaksi</label>
|
||||
<div class="col"><div class="input-group">'.$tnota.'<button id="butBrow" class="btn btn-info" type="button"><i class="bi-search"></i></button></div></div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="Tgl_Beli">Tanggal Transaksi</label>
|
||||
<div class="col-sm-7 col-lg-5">'.$ttglnota.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="Tgl_Faktur">Tanggal Faktur</label>
|
||||
<div class="col-sm-7 col-lg-5">'.$ttglfaktur.'</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-lg-6">
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="CabID">Nama Cabang</label>
|
||||
<div class="col">'.$tcab.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="SupID">Nama Supplier</label>
|
||||
<div class="col">'.$tsup.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="No_Faktur">Nomor Faktur</label>
|
||||
<div class="col"><div class="input-group">'.$tfaktur.$tppn.'</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1"><div class="col"><hr class="my-1"></div></div>
|
||||
<input type="hidden" id="Total_Beli" value="'.$atabel['Total_Beli'].'" >
|
||||
<input type="hidden" id="Real_Beli" value="'.$atabel['Real_Beli'].'" >
|
||||
<input type="hidden" id="Real_Diskon" value="'.$atabel['Real_Diskon'].'" >
|
||||
<input type="hidden" id="Lunas" value="'.$atabel['Lunas'].'" >
|
||||
<input type="hidden" id="mode" value="'.$this->mode.'" >';
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function form_produk() {
|
||||
$id = (int) Param::Get("ID", 0);
|
||||
$atabel = [ 'ID'=>$id, 'InvID'=>$this->id_inv, 'SatuanID'=>$this->id_satuan, 'VarianID'=>$this->id_varian, 'Nama_Produk'=>"", 'Nama_Satuan'=>"", 'Qty'=>0, 'Harga_Beli'=>0, 'Disk_Rupiah'=>0, 'Disk_Persen1'=>0, 'Disk_Persen2'=>0, 'Disk_Persen3'=>0, 'Disk_Persen4'=>0, 'Disk_Persen5'=>0 ];
|
||||
if ($id > 0) {
|
||||
$_row = $this->db->fetchRow("SELECT * FROM tmp_inv_detail WHERE No_Ref=? AND ID=?", [$this->no_beli, $id]);
|
||||
if ($_row) $atabel = array_merge($atabel, $_row->getData());
|
||||
}
|
||||
if ((int) $atabel['InvID'] > 0 && (int) $atabel['SatuanID'] > 0) {
|
||||
$_row = $this->db->fetchRow("SELECT Nama_Produk,Nama_Satuan FROM vi_inv_produk WHERE InvID=? AND SatuanID=? AND VarianID=?", [$atabel['InvID'], $atabel['SatuanID'], $atabel['VarianID']]);
|
||||
if ($_row) $atabel = array_merge($atabel, $_row->getData());
|
||||
}
|
||||
|
||||
$form = new Form($this->app);
|
||||
$tnama = $form->textauto("_", "Nama_Produk", ['value'=>$atabel['InvID'],'text'=>$atabel['Nama_Produk']], true, true, "ketik nama produk");
|
||||
$tvar = $form->option("_", "VarianID", $atabel['VarianID'], true, false, [$atabel['VarianID']=>"Tanpa Varian"]);
|
||||
$tqty = $form->textbox("_", "Qty", $atabel['Qty'], true, true, "double");
|
||||
$tbeli = $form->textbox("_", "Harga_Beli", $atabel['Harga_Beli'], true, true, "double");
|
||||
$tdisrp = $form->textbox("_", "Disk_Rupiah", $atabel['Disk_Rupiah'], true, true, "double");
|
||||
$tdis1 = $form->textbox("_", "Disk_Persen1", $atabel['Disk_Persen1'], true, true, "double");
|
||||
$tdis2 = $form->textbox("_", "Disk_Persen2", $atabel['Disk_Persen2'], true, true, "double");
|
||||
$tdis3 = $form->textbox("_", "Disk_Persen3", $atabel['Disk_Persen3'], true, true, "double");
|
||||
$tdis4 = $form->textbox("_", "Disk_Persen4", $atabel['Disk_Persen4'], true, true, "double");
|
||||
$tdis5 = $form->textbox("_", "Disk_Persen5", $atabel['Disk_Persen5'], true, true, "double");
|
||||
$ttot_dis = $form->textbox("_", "Total_Diskon", 0, false, false, "double");
|
||||
$ttot = $form->textbox("_", "Jumlah", 0, false, false, "double");
|
||||
$tsat = $form->textbox("_", "Nama_Satuan", $atabel['Nama_Satuan'], false, false, "text");
|
||||
$ajson['html'] = '
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-2 col-form-label" for="Nama_Produk">Nama Barang</label>
|
||||
<div class="col">'.$tnama.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-2 col-form-label" for="VarianID">Nama Varian</label>
|
||||
<div class="col">'.$tvar.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-2 col-form-label" for="Qty">Qty</label>
|
||||
<div class="col-sm-4 col-lg-5"><div class="input-group">'.$tqty.$tsat.'</div></div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-2 col-form-label" for="Harga_Beli">Harga (@)</label>
|
||||
<div class="col-sm-4 col-lg-5">'.$tbeli.'</div>
|
||||
</div>
|
||||
<hr class="my-1">
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-2 col-form-label" for="Disk_Rupiah">Diskon Rupiah</label>
|
||||
<div class="col-sm-4 col-lg-5">'.$tdisrp.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-2 col-form-label">Diskon Persen</label>
|
||||
<div class="col-sm-4 col-lg-3"><div class="input-group"><span class="input-group-text">1</span>'.$tdis1.'<span class="input-group-text">%</span></div></div>
|
||||
<div class="col-sm-4 col-lg-3"><div class="input-group"><span class="input-group-text">3</span>'.$tdis3.'<span class="input-group-text">%</span></div></div>
|
||||
<div class="col-sm-4 col-lg-3"><div class="input-group"><span class="input-group-text">5</span>'.$tdis5.'<span class="input-group-text">%</span></div></div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-2 col-form-label"> </label>
|
||||
<div class="col-sm-4 col-lg-3"><div class="input-group"><span class="input-group-text">2</span>'.$tdis2.'<span class="input-group-text">%</span></div></div>
|
||||
<div class="col-sm-4 col-lg-3"><div class="input-group"><span class="input-group-text">4</span>'.$tdis4.'<span class="input-group-text">%</span></div></div>
|
||||
<div class="col-sm-4 col-lg-3">'.Invesa::Form_Info("Silakan masukkan -10 pada Diskon 5, jika ada PPN.").'</div>
|
||||
</div>
|
||||
<hr class="my-1">
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-2 col-form-label">Diskon</label>
|
||||
<div class="col-sm-4 col-lg-5">'.$ttot_dis.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-2 col-form-label">Total</label>
|
||||
<div class="col-sm-4 col-lg-5">'.$ttot.'</div>
|
||||
</div>
|
||||
<input type="hidden" id="ID" value="'.$atabel['ID'].'" >
|
||||
<input type="hidden" id="InvID" value="'.$atabel['InvID'].'" >
|
||||
<input type="hidden" id="SatuanID" value="'.$atabel['SatuanID'].'" >
|
||||
<input type="hidden" id="mode_detail" value="'.$this->mode_detail.'" >';
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function form_total() {
|
||||
$form = new Form($this->app);
|
||||
$tdisk = $form->textbox("_", "popTotal_Diskon", 0, true, false, "double");
|
||||
$tbeli = $form->textbox("_", "popTotal_Beli", 0, true, false, "double");
|
||||
$ajson['html'] = '
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-6 col-lg-5 col-form-label" for="popTotal_Diskon">Total Diskon (Koreksi +/-)</label>
|
||||
<div class="col">'.$tdisk.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-6 col-lg-5 col-form-label" for="popTotal_Beli">Total Faktur / Hutang</label>
|
||||
<div class="col">'.$tbeli.'</div>
|
||||
</div>
|
||||
';
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function proses_delete() {
|
||||
if ($this->is_pend === false) {
|
||||
$this->db->runQuery("DELETE FROM inv_beli WHERE No_Beli=?", [$this->no_beli]);
|
||||
$this->db->runQuery("DELETE FROM inv_detail WHERE No_Ref=?", [$this->no_beli]);
|
||||
// PROSES POSTING GL
|
||||
$this->db->runQuery("DELETE FROM gel_jurnal WHERE Kode_Jurnal=?", [$this->no_beli]);
|
||||
$this->db->runQuery("DELETE FROM gel_jurnal_detail WHERE Kode_Jurnal=?", [$this->no_beli]);
|
||||
} else {
|
||||
$this->db->runQuery("DELETE FROM inv_beli_pend WHERE No_Beli=?", [$this->no_beli]);
|
||||
$this->db->runQuery("DELETE FROM tmp_inv_detail WHERE No_Ref=?", [$this->no_beli]);
|
||||
}
|
||||
$this->app->json([ 'status' => true ]);
|
||||
}
|
||||
|
||||
public function option_varian() {
|
||||
$aoption = ['type' => "option", 'id' => "VarianID", 'value' => $this->id_varian, 'avalue' => [['value'=>0, 'html'=>"Tanpa Varian"]]];
|
||||
$avarian = $this->db->fetchAll("SELECT * FROM para_varian WHERE VarianID IN (SELECT VarianID FROM inv_produk_varian WHERE InvID=? AND SatuanID=?) ORDER BY Nama_Varian", [$this->id_inv, $this->id_satuan]);
|
||||
foreach ($avarian as $varian) {
|
||||
$aoption['avalue'][] = ['value'=>$varian['VarianID'], 'html'=>$varian['Nama_Varian']];
|
||||
}
|
||||
$this->app->json([ $aoption ]);
|
||||
}
|
||||
|
||||
public function item_detail() {
|
||||
$ajson['data'] = [];
|
||||
$_row = $this->db->fetchRow("SELECT * FROM inv_detail D WHERE Qty>0 AND InvID=? ORDER BY Tgl_Ref DESC", [$this->id_inv]);
|
||||
if ($_row) $ajson['data'] = $_row->getData();
|
||||
|
||||
if ($this->id_satuan !== (int) $ajson['data']['SatuanID']) {
|
||||
$_bagi = (float) $this->db->fetchField("SELECT A.Qty/B.Qty Bagi FROM (SELECT InvID,Qty FROM inv_produk_kemasan WHERE InvID=? AND SatuanID=? LIMIT 1) A LEFT JOIN (SELECT InvID,Qty FROM inv_produk_kemasan WHERE InvID=? AND SatuanID=? LIMIT 1) B ON (A.InvID=B.InvID)", [$this->id_inv, $this->id_satuan, $this->id_inv, $this->id_satuan]) ?? 1;
|
||||
(float) $ajson['data']['Harga_Beli'] /= $_bagi;
|
||||
(float) $ajson['data']['Disk_Rupiah'] /= $_bagi;
|
||||
}
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function index() {
|
||||
$this->app->json(['html' => '
|
||||
<div class="fade-in">
|
||||
<div class="card"><div class="card-body">
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="tx-tab" data-bs-toggle="tab" data-bs-target="#tx" type="button" role="tab" aria-controls="tx" aria-selected="true"><i class="bi-database me-2"></i>Transaksi Pembelian</button>
|
||||
</li>
|
||||
<li class="nav-item ms-auto">
|
||||
<button class="btn btn-primary mb-1 ms-2" id="butTambah" type="button"><i class="bi-plus-lg me-2"></i>Tambah</button>
|
||||
<button class="btn btn-info mb-1 ms-2" id="butUbah" type="button"><i class="bi-clipboard me-2"></i>Ubah</button>
|
||||
<button class="btn btn-warning mb-1 ms-2" id="butHapus" type="button"><i class="bi-trash me-2"></i>Hapus</button>
|
||||
<button class="btn btn-info mb-1 ms-2" id="butPendingBrow" type="button"><i class="bi-cloud me-2"></i>Pending</button>
|
||||
<button class="btn btn-secondary mb-1 ms-2" id="butPrint" type="button"><i class="bi-printer me-2"></i>Cetak</button>
|
||||
<button class="btn btn-danger mb-1 ms-2" id="butBatal" type="button"><i class="bi-x-lg me-2"></i>Batal</button>
|
||||
<button class="btn btn-warning mb-1 ms-2" id="butPendingSimpan" type="button"><i class="bi-cloud-upload me-2"></i>Simpan Pending</button>
|
||||
<button class="btn btn-success mb-1 ms-2" id="butSimpan" type="button"><i class="bi-save me-2"></i>Simpan</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content border border-top-0 p-3">
|
||||
<div class="tab-pane fade active show" id="tx" role="tabpanel" aria-labelledby="tx-tab">
|
||||
<div id="divTXMaster"> </div>
|
||||
<div id="divDetailTabel"> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
</div>'
|
||||
]);
|
||||
}
|
||||
|
||||
private function Data_Beli(string $nomor="", bool $baru=false): array {
|
||||
$aparam = [ 'No_Beli'=>$nomor, 'PPN'=>0, 'Lunas'=>0 ];
|
||||
if (empty($nomor)) {
|
||||
if ($baru) $aparam['No_Beli'] = "BELI".$this->web_app['SERVER_ID'].(string) $this->id_cab.$this->app->user()->id(3)."#00";
|
||||
$aparam['Tgl_Beli'] = tgl_ymd();
|
||||
$aparam['Tgl_Faktur'] = tgl_ymd();
|
||||
$aparam['No_Faktur'] = "";
|
||||
$aparam['SupID'] = 0;
|
||||
$aparam['CabID'] = $this->id_cab;
|
||||
$aparam['Total_Beli'] = 0;
|
||||
$aparam['Real_Beli'] = 0;
|
||||
$aparam['Real_Diskon'] = 0;
|
||||
} else {
|
||||
$tabel_beli = (str_contains($nomor, "BELI") === false) ? "inv_beli" : "inv_beli_pend";
|
||||
$row = $this->db->fetchRow("SELECT * FROM ".$tabel_beli." WHERE No_Beli=?", [$nomor]);
|
||||
if ($row) $aparam = array_merge($aparam, $row->getData());
|
||||
}
|
||||
return $aparam;
|
||||
}
|
||||
|
||||
private function Pending_Nomor(): string {
|
||||
$tno = "BELI".$this->web_app['SERVER_ID'].(string) $this->id_cab.$this->app->user()->id(3)."#";
|
||||
$ino = (int) $this->db->fetchField("SELECT MAX(RIGHT(No_Beli,2)) FROM inv_beli_pend WHERE No_Beli LIKE ?", [$tno.'%']) ?? 0;
|
||||
$tno .= isi_nol(++$ino, 2);
|
||||
return $tno;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,392 @@
|
||||
<?php
|
||||
|
||||
/*******************************************************************
|
||||
|
||||
PHP Class : /Controller/Inv/BelireturController
|
||||
Description : Transaksi Retur Pembelian
|
||||
Created By : Siau Pheng ([email protected]).
|
||||
Created Date : May 22th, 2010.
|
||||
Last Modified : September 21st, 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 BelireturController {
|
||||
|
||||
private array $web_app;
|
||||
private array $app_gel;
|
||||
private int $id_cab;
|
||||
private string $mode;
|
||||
private string $mode_detail;
|
||||
private string $no_beli;
|
||||
private bool $is_baru;
|
||||
private int $id_inv;
|
||||
private int $id_satuan;
|
||||
private int $id_varian;
|
||||
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->web_app = (array) $session->get('WEB_APP');
|
||||
$this->app_gel = (array) $session->get('APP_GEL');
|
||||
$this->id_cab = Param::Int("CabID", $session->get('APP_INV')['CABANGID']);
|
||||
$this->mode = Param::Get("mode", "");
|
||||
$this->mode_detail = Param::Get("mode_detail", "");
|
||||
$this->no_beli = Param::Get("No_Beli", "");
|
||||
$this->is_baru = str_contains($this->no_beli, "BERE") === true;
|
||||
$this->id_inv = Param::Int("InvID", 0);
|
||||
$this->id_satuan = Param::Int("SatuanID", 0);
|
||||
$this->id_varian = Param::Int("VarianID", 0);
|
||||
$this->inv = new Inv($app);
|
||||
$this->gel = new Gel($app);
|
||||
}
|
||||
|
||||
public function table_detail() {
|
||||
if (in_array($this->mode_detail, ["insert","update","delete"])) {
|
||||
$iqty = Param::Float("Qty", 0) * -1;
|
||||
|
||||
$sql = new SQL($this->app);
|
||||
$sql->set_table("tmp_inv_detail");
|
||||
$sql->add_param("No_Ref", $this->no_beli);
|
||||
$sql->add_param("InvID");
|
||||
$sql->add_param("SatuanID");
|
||||
$sql->add_param("VarianID");
|
||||
$sql->add_param("Qty", $iqty);
|
||||
$sql->add_param("Harga_Beli");
|
||||
$sql->add_param("Harga_Jual", "Harga_Beli", true);
|
||||
$sql->add_param_unix();
|
||||
$sql->add_param_userid();
|
||||
$sql->add_where("ID");
|
||||
$sql->add_where("No_Ref", $this->no_beli);
|
||||
|
||||
if ( $this->mode_detail === "insert" ) {
|
||||
$sql->InsertDB();
|
||||
} else if ( $this->mode_detail === "update" ) {
|
||||
$sql->UpdateDB();
|
||||
} else if ( $this->mode_detail === "delete" ) {
|
||||
$sql->DeleteDB();
|
||||
}
|
||||
}
|
||||
|
||||
$tsql = ''; $asql = [$this->no_beli]; $qtabel = "inv_detail";
|
||||
if (in_array($this->mode, ["add","edit"])) {
|
||||
if ($this->mode === "add") { $tsql = " AND Unix=?"; $asql[] = $this->app->user()->unix(); }
|
||||
$qtabel = "tmp_inv_detail";
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("(SELECT *,-Qty Qty2,(-Qty*Harga_Beli) Total FROM ".$qtabel." WHERE No_Ref=?".$tsql.") D LEFT JOIN vi_inv_produk P ON (D.InvID=P.InvID AND D.SatuanID=P.SatuanID AND D.VarianID=P.VarianID)", "D.*,P.Kode_SKU,P.Nama_Lengkap", "", $asql);
|
||||
$obj->set_footer("SUM(D.Total) Total");
|
||||
$obj->add_field("ID", "No", "c");
|
||||
$obj->add_field("InvID", "InvID", "hid");
|
||||
$obj->add_field("SatuanID", "SatuanID", "hid");
|
||||
$obj->add_field("VarianID", "VarianID", "hid");
|
||||
$obj->add_field("Kode_SKU", "SKU", "c");
|
||||
$obj->add_field("Nama_Lengkap", "Nama Barang", "awr");
|
||||
$obj->add_field("Qty2", "Qty", "r", "rupiah2");
|
||||
$obj->add_field("Harga_Beli", "Harga @", "r", "rupiah");
|
||||
$obj->add_field("Total", "Jumlah", "r", "rupiah", "rupiah");
|
||||
$obj->set_field_order("ID", "D");
|
||||
if (in_array($this->mode, ["add","edit"])) {
|
||||
$obj->add_row_btn("clipboard", "Ubah", "BeliReturJS.detail_ubah");
|
||||
$obj->add_row_btn("trash", "Hapus", "BeliReturJS.detail_hapus", "Unix", $this->app->user()->unix());
|
||||
$obj->set_func_btn("BeliReturJS.detail_tambah", '<i class="bi-plus-lg me-1"></i> Produk');
|
||||
$obj->set_func_btn("BeliReturJS.produk_brow", '<i class="bi-table me-1"></i> Browse');
|
||||
}
|
||||
$ajson[] = $obj->json_table("divDetailTabel");
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function brow_tx() {
|
||||
$tcari = Param::Get("Cari_TX");
|
||||
$tsql = ''; $asql = [];
|
||||
if (!empty($tcari)) {
|
||||
$tsql .= "CONCAT(B.No_Beli,B.No_Faktur,S.Nama_Sup,DATE_FORMAT(B.Tgl_Faktur,'%d-%m-%Y')) LIKE ?";
|
||||
$asql[] = '%' . $tcari . '%';
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("(SELECT * FROM inv_beli WHERE Data_Beli=0) B LEFT JOIN para_supplier S ON (B.SupID=S.SupID) LEFT JOIN para_cabang C ON (C.CabID=B.CabID)", "B.*,S.Nama_Sup,C.Kode_Cab", $tsql, $asql);
|
||||
$obj->add_field("No_Beli", "No. Trans", "c");
|
||||
$obj->add_field("Tgl_Beli", "Tgl. Trans", "c", "sqltgl", "", "val-tgl");
|
||||
$obj->add_field("Kode_Cab", "Cabang", "c");
|
||||
$obj->add_field("Nama_Sup", "Nama Supplier", "awr");
|
||||
$obj->add_field("Total_Beli", "Total", "r", "rupiah2");
|
||||
$obj->set_field_order("Tgl_Beli", "D");
|
||||
$obj->set_func_select("BeliReturJS.tx_select");
|
||||
$this->app->json([ $obj->db_table("divBrowTX") ]);
|
||||
}
|
||||
|
||||
public function brow_produk() {
|
||||
$tcari = Param::Get("Cari_Produk");
|
||||
$tsql = ''; $asql = [1];
|
||||
if (!empty($tcari)) {
|
||||
$tsql .= " AND P.Barcode_Nama LIKE ?";
|
||||
$asql[] = '%' . $tcari . '%';
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("vi_inv_produk P", "P.*", "P.Aktif=?".$tsql, $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->set_field_order("Kode_SKU", "A");
|
||||
$obj->set_func_select("BeliReturJS.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
|
||||
$_row = $this->db->fetchRow("SELECT V.InvID,P.Nama_Produk,CONCAT(V.SatuanID,':',V.VarianID,':',S.Nama_Satuan) Data2 FROM (SELECT * FROM inv_produk_varian WHERE Kode_SKU=? OR Kode_Barcode=? LIMIT 1) V LEFT JOIN inv_produk P ON (P.InvID=V.InvID) LEFT JOIN para_satuan S ON (S.SatuanID=V.SatuanID) WHERE P.Aktif=1", [$tcari, $tcari]);
|
||||
if ($_row) {
|
||||
$bcode = 1;
|
||||
$arec = $_row->getData();
|
||||
}
|
||||
|
||||
if ($bcode === 1) {
|
||||
$ajson['autodata'][] = ['value'=>$arec['InvID'], 'text'=>$arec['Nama_Produk'], 'data'=>$arec['Data2'], 'bc'=>1];
|
||||
} else {
|
||||
$stat = $this->db->runQuery("SELECT P.InvID,P.Nama_Produk,V.Kode_SKU,IFNULL(MV.Nama_Varian,'') Nama_Varian,MS.Nama_Satuan,CONCAT(V.SatuanID,':',V.VarianID,':',MS.Nama_Satuan) Data2 FROM (SELECT * FROM inv_produk WHERE Nama_Produk LIKE ? AND Aktif=1) P INNER JOIN inv_produk_varian V ON (V.InvID=P.InvID) LEFT JOIN para_satuan MS ON (MS.SatuanID=V.SatuanID) LEFT JOIN para_varian MV ON (MV.VarianID=V.VarianID) ORDER BY P.Nama_Produk,MS.Nama_Satuan LIMIT 50", ['%'.$tcari.'%']);
|
||||
while ($row = $stat->fetch(SimplePdo::FETCH_ASSOC)) {
|
||||
$ajson['autodata'][] = ['value'=>$row['InvID'], 'text'=>$row['Nama_Produk'], 'html'=>'<span class="text-primary">'.$row['Kode_SKU'].'</span> '.$row['Nama_Produk']." ".$row['Nama_Varian']." ".$row['Nama_Satuan'], 'data'=>$row['Data2'], 'bc'=>0];
|
||||
}
|
||||
}
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function form_master() {
|
||||
$ajson = [ 'error'=>"", 'html'=>"" ];
|
||||
$atabel = [];
|
||||
|
||||
if ($this->mode === "add") {
|
||||
$atabel = $this->Data_Beli("", true);
|
||||
} else if ($this->mode === "edit") {
|
||||
$this->inv->Detail_Copy($this->no_beli, true);
|
||||
$atabel = $this->Data_Beli($this->no_beli);
|
||||
} else if ($this->mode === "save") {
|
||||
$no_lama = $this->no_beli;
|
||||
if ($this->is_baru) {
|
||||
$this->no_beli = $this->inv->Nomor_Baru("R", Param::Get("Tgl_Beli"), true);
|
||||
}
|
||||
$this->inv->Detail_Save($this->no_beli, 4, $this->id_cab, Param::Get("Tgl_Beli"), $this->is_baru, $no_lama);
|
||||
|
||||
$tot_retur = $this->db->fetchField("SELECT SUM(Qty*Harga_Beli) Retur_Beli FROM inv_detail WHERE No_Ref=?", [$this->no_beli]) ?? 0;
|
||||
|
||||
$sql = new SQL($this->app);
|
||||
$sql->set_table("inv_beli");
|
||||
$sql->add_param_date("Tgl_Beli");
|
||||
$sql->add_param("CabID");
|
||||
$sql->add_param("SupID");
|
||||
$sql->add_param("Total_Beli", $tot_retur);
|
||||
$sql->add_param("Real_Beli", $tot_retur);
|
||||
$sql->add_param("No_Faktur");
|
||||
$sql->add_param("Tgl_Faktur", "Tgl_Beli", true);
|
||||
$sql->add_param("Data_Beli", 0);
|
||||
$sql->add_param_stamp();
|
||||
$sql->add_param_userid();
|
||||
$sql->add_where("No_Beli", $this->no_beli);
|
||||
$sql->UpdateDB();
|
||||
|
||||
$this->gel->Update_Lunas_Sup(Param::Int("SupID", 0));
|
||||
|
||||
// PROSES POSTING GL
|
||||
$ainfo = $this->db->fetchRow("SELECT B.*,S.Nama_Sup,-B.Real_Beli Tagihan FROM (SELECT * FROM inv_beli WHERE No_Beli=?) B LEFT JOIN para_supplier S ON (S.SupID=B.SupID)", [$this->no_beli]);
|
||||
if (count($ainfo) > 0) {
|
||||
$ajurnal = [
|
||||
'Kode_Jurnal' => $ainfo['No_Beli'],
|
||||
'TipeID' => 6,
|
||||
'CabID' => $ainfo['CabID'],
|
||||
'Tanggal' => tgl_sql2str($ainfo['Tgl_Beli']),
|
||||
'Kode_Ref' => $ainfo['No_Beli'],
|
||||
'Catatan' => "Retur Pembelian : ".$ainfo['No_Beli']." / ".$ainfo['Nama_Sup']
|
||||
];
|
||||
$adetail = [
|
||||
[ 'Kode_Rek' => $this->app_gel['STOK'], 'DK' => "K", 'Jumlah' => $ainfo['Tagihan'] ],
|
||||
[ 'Kode_Rek' => $this->app_gel['HUT_USAHA'], 'DK' => "D", 'Jumlah' => $ainfo['Tagihan'], 'SupID' => $ainfo['SupID'] ]
|
||||
];
|
||||
$this->gel->Jurnal_Post($ajurnal, $adetail);
|
||||
}
|
||||
$atabel = $this->Data_Beli($this->no_beli);
|
||||
$this->mode = "view";
|
||||
|
||||
} else if ($this->mode === "cancel") {
|
||||
$this->inv->Detail_Cancel($this->no_beli);
|
||||
$atabel = $this->Data_Beli();
|
||||
} else {
|
||||
$atabel = $this->Data_Beli($this->no_beli);
|
||||
}
|
||||
|
||||
$enable = in_array($this->mode, ["add","edit"]) ? true : false;
|
||||
$form = new Form($this->app);
|
||||
$tnota = $form->textbox("_", "No_Beli", $atabel['No_Beli'], !$enable, true, "text", "nomor transaksi");
|
||||
$ttglnota = $form->datebox("_", "Tgl_Beli", $atabel['Tgl_Beli'], $enable, true);
|
||||
$tcab = $form->option_db("_", "CabID", $atabel['CabID'], $enable, false, "para_cabang", ["CabID","Nama_Cab"], "Aktif=1 ORDER BY Nama_Cab", [0," "]);
|
||||
$tsup = $form->option_db("_", "SupID", $atabel['SupID'], $enable, false, "para_supplier", ["SupID","Nama_Sup"], "Aktif=1 ORDER BY Nama_Sup", [0," "]);
|
||||
$tcatat = $form->textbox("_", "No_Faktur", $atabel['No_Faktur'], $enable, true, "text", "catatan");
|
||||
$ajson['html'] = '
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-lg-6">
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="No_Beli">Nomor Transaksi</label>
|
||||
<div class="col"><div class="input-group">'.$tnota.'<button id="butBrow" class="btn btn-info" type="button"><i class="bi-search"></i></button></div></div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="Tgl_Beli">Tanggal Transaksi</label>
|
||||
<div class="col-sm-7 col-lg-5">'.$ttglnota.'</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-lg-6">
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="CabID">Nama Cabang</label>
|
||||
<div class="col">'.$tcab.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="SupID">Nama Supplier</label>
|
||||
<div class="col">'.$tsup.'</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-3 col-lg-2 col-form-label" for="No_Faktur" style="width:12.5%;">Catatan</label>
|
||||
<div class="col">'.$tcatat.'</div>
|
||||
</div>
|
||||
<div class="row mb-1"><div class="col"><hr class="my-1"></div></div>
|
||||
<input type="hidden" id="Lunas" value="'.$atabel['Lunas'].'" >
|
||||
<input type="hidden" id="mode" value="'.$this->mode.'" >';
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function form_produk() {
|
||||
$id = (int) Param::Get("ID", 0);
|
||||
$atabel = [ 'ID'=>$id, 'InvID'=>$this->id_inv, 'SatuanID'=>$this->id_satuan, 'VarianID'=>$this->id_varian, 'Nama_Produk'=>"", 'Nama_Satuan'=>"", 'Qty2'=>0, 'Harga_Beli'=>0 ];
|
||||
if ($id > 0) {
|
||||
$_row = $this->db->fetchRow("SELECT *,-Qty Qty2 FROM tmp_inv_detail WHERE No_Ref=? AND ID=?", [$this->no_beli, $id]);
|
||||
if ($_row) $atabel = array_merge($atabel, $_row->getData());
|
||||
}
|
||||
if ((int) $atabel['InvID'] > 0 && (int) $atabel['SatuanID'] > 0) {
|
||||
$_row = $this->db->fetchRow("SELECT Nama_Produk,Nama_Satuan FROM vi_inv_produk WHERE InvID=? AND SatuanID=? AND VarianID=?", [$atabel['InvID'], $atabel['SatuanID'], $atabel['VarianID']]);
|
||||
if ($_row) $atabel = array_merge($atabel, $_row->getData());
|
||||
}
|
||||
|
||||
$form = new Form($this->app);
|
||||
$tnama = $form->textauto("_", "Nama_Produk", ['value'=>$atabel['InvID'],'text'=>$atabel['Nama_Produk']], true, true, "ketik nama produk");
|
||||
$tvar = $form->option("_", "VarianID", $atabel['VarianID'], true, false, [$atabel['VarianID']=>"Tanpa Varian"]);
|
||||
$tqty = $form->textbox("_", "Qty", $atabel['Qty2'], true, true, "double");
|
||||
$tbeli = $form->textbox("_", "Harga_Beli", $atabel['Harga_Beli'], true, true, "double");
|
||||
$ttot = $form->textbox("_", "Jumlah", 0, false, false, "double");
|
||||
$tsat = $form->textbox("_", "Nama_Satuan", $atabel['Nama_Satuan'], false, false, "text");
|
||||
$ajson['html'] = '
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label" for="Nama_Produk">Nama Barang</label>
|
||||
<div class="col">'.$tnama.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label" for="VarianID">Nama Varian</label>
|
||||
<div class="col">'.$tvar.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label" for="Qty">Qty</label>
|
||||
<div class="col-sm-8 col-lg-5"><div class="input-group">'.$tqty.$tsat.'</div></div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label" for="Harga_Beli">Harga (@)</label>
|
||||
<div class="col-sm-8 col-lg-5">'.$tbeli.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label">Total</label>
|
||||
<div class="col-sm-8 col-lg-5">'.$ttot.'</div>
|
||||
</div>
|
||||
<input type="hidden" id="ID" value="'.$atabel['ID'].'" >
|
||||
<input type="hidden" id="InvID" value="'.$atabel['InvID'].'" >
|
||||
<input type="hidden" id="SatuanID" value="'.$atabel['SatuanID'].'" >
|
||||
<input type="hidden" id="mode_detail" value="'.$this->mode_detail.'" >';
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function proses_delete() {
|
||||
$this->db->runQuery("DELETE FROM inv_beli WHERE No_Beli=?", [$this->no_beli]);
|
||||
$this->db->runQuery("DELETE FROM inv_detail WHERE No_Ref=?", [$this->no_beli]);
|
||||
// PROSES POSTING GL
|
||||
$this->db->runQuery("DELETE FROM gel_jurnal WHERE Kode_Jurnal=?", [$this->no_beli]);
|
||||
$this->db->runQuery("DELETE FROM gel_jurnal_detail WHERE Kode_Jurnal=?", [$this->no_beli]);
|
||||
$this->app->json([ 'status' => true ]);
|
||||
}
|
||||
|
||||
public function option_varian() {
|
||||
$aoption = ['type' => "option", 'id' => "VarianID", 'value' => $this->id_varian, 'avalue' => [['value'=>0, 'html'=>"Tanpa Varian"]]];
|
||||
$avarian = $this->db->fetchAll("SELECT * FROM para_varian WHERE VarianID IN (SELECT VarianID FROM inv_produk_varian WHERE InvID=? AND SatuanID=?) ORDER BY Nama_Varian", [$this->id_inv, $this->id_satuan]);
|
||||
foreach ($avarian as $varian) {
|
||||
$aoption['avalue'][] = ['value'=>$varian['VarianID'], 'html'=>$varian['Nama_Varian']];
|
||||
}
|
||||
$this->app->json([ $aoption ]);
|
||||
}
|
||||
|
||||
public function index() {
|
||||
$this->app->json(['html' => '
|
||||
<div class="fade-in">
|
||||
<div class="card"><div class="card-body">
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="tx-tab" data-bs-toggle="tab" data-bs-target="#tx" type="button" role="tab" aria-controls="tx" aria-selected="true"><i class="bi-database me-2"></i>Transaksi Retur Pembelian</button>
|
||||
</li>
|
||||
<li class="nav-item ms-auto">
|
||||
<button class="btn btn-primary mb-1 ms-2" id="butTambah" type="button"><i class="bi-plus-lg me-2"></i>Tambah</button>
|
||||
<button class="btn btn-info mb-1 ms-2" id="butUbah" type="button"><i class="bi-clipboard me-2"></i>Ubah</button>
|
||||
<button class="btn btn-warning mb-1 ms-2" id="butHapus" type="button"><i class="bi-trash me-2"></i>Hapus</button>
|
||||
<button class="btn btn-secondary mb-1 ms-2" id="butPrint" type="button"><i class="bi-printer me-2"></i>Cetak</button>
|
||||
<button class="btn btn-danger mb-1 ms-2" id="butBatal" type="button"><i class="bi-x-lg me-2"></i>Batal</button>
|
||||
<button class="btn btn-success mb-1 ms-2" id="butSimpan" type="button"><i class="bi-save me-2"></i>Simpan</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content border border-top-0 p-3">
|
||||
<div class="tab-pane fade active show" id="tx" role="tabpanel" aria-labelledby="tx-tab">
|
||||
<div id="divTXMaster"> </div>
|
||||
<div id="divDetailTabel"> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
</div>'
|
||||
]);
|
||||
}
|
||||
|
||||
private function Data_Beli(string $nomor="", bool $baru=false): array {
|
||||
$aparam = [ 'No_Beli'=>$nomor, 'Lunas'=>0 ];
|
||||
if (empty($nomor)) {
|
||||
if ($baru) $aparam['No_Beli'] = "BERE".$this->web_app['SERVER_ID'].(string) $this->id_cab.$this->app->user()->id(3)."#00";
|
||||
$aparam['Tgl_Beli'] = tgl_ymd();
|
||||
$aparam['No_Faktur'] = "";
|
||||
$aparam['SupID'] = 0;
|
||||
$aparam['CabID'] = $this->id_cab;
|
||||
} else {
|
||||
$row = $this->db->fetchRow("SELECT * FROM inv_beli WHERE Data_Beli=0 AND No_Beli=?", [$nomor]);
|
||||
if ($row) $aparam = array_merge($aparam, $row->getData());
|
||||
}
|
||||
return $aparam;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
/*******************************************************************
|
||||
|
||||
PHP Class : /Controller/Inv/CekhargaController
|
||||
Description : Informasi Barang & Harga Jual
|
||||
Created By : Siau Pheng ([email protected]).
|
||||
Created Date : October 22nd, 2014.
|
||||
Last Modified : September 27th, 2026.
|
||||
|
||||
(c) 3FONIA Software; WWW.3FONIA.COM.
|
||||
|
||||
*******************************************************************/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller\Inv;
|
||||
|
||||
use flight\Engine;
|
||||
use flight\database\SimplePdo;
|
||||
use flight\Session;
|
||||
use Webapp\Web\Form;
|
||||
use Webapp\Web\Param;
|
||||
use Webapp\Web\Table;
|
||||
|
||||
class CekhargaController {
|
||||
|
||||
private int $id_grup_member;
|
||||
private int $id_inv;
|
||||
protected Engine $app;
|
||||
protected SimplePdo $db;
|
||||
|
||||
public function __construct(Engine $app, SimplePdo $db, Session $session) {
|
||||
$this->app = $app;
|
||||
$this->db = $db;
|
||||
$this->id_grup_member = $session->get('APP_INV')['ECERANID'];
|
||||
$this->id_inv = Param::Int("InvID", 0);
|
||||
}
|
||||
|
||||
public function brow_produk() {
|
||||
$tcari = Param::Get("Cari_Produk");
|
||||
$tsql = ''; $asql = [1, $this->id_grup_member];
|
||||
if (!empty($tcari)) {
|
||||
$tsql .= " AND Barcode_Nama LIKE ?";
|
||||
$asql[] = '%' . $tcari . '%';
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("inv_produk_join", "*", "Aktif=? AND Grup_MemberID=? AND Harga_Jual>0".$tsql, $asql);
|
||||
$obj->add_field("InvID", "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("Harga_Jual", "Harga Jual", "r", "rupiah");
|
||||
$obj->add_field("Satuan_Kemasan", "Satuan", "hid");
|
||||
$obj->set_field_order("Kode_SKU", "A");
|
||||
$obj->set_func_select("CekHargaJS.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
|
||||
// Kode_SKU + Kode_Barcode : Satuan_Kemasan : Harga_Jual
|
||||
$_row = $this->db->fetchRow("SELECT P.InvID,P.Nama_Produk_Varian,CONCAT(P.Kode_SKU,' / ',P.Kode_Barcode,':',P.Satuan_Kemasan,':',CONVERT(FORMAT(P.Harga_Jual,2) USING UTF8)) Data2 FROM (SELECT * FROM inv_produk_join WHERE Aktif=1 AND Harga_Jual>0 AND Grup_MemberID=? AND (Kode_SKU=? OR Kode_Barcode=?)) P", [$this->id_grup_member, $tcari, $tcari]);
|
||||
if ($_row) {
|
||||
$bcode = 1;
|
||||
$arec = $_row->getData();
|
||||
}
|
||||
if ($bcode === 1) {
|
||||
$ajson['autodata'][] = ['value'=>$arec['InvID'], 'text'=>$arec['Nama_Produk_Varian'], 'data'=>$arec['Data2'], 'bc'=>1];
|
||||
} else {
|
||||
$stat = $this->db->runQuery("SELECT P.InvID,P.Nama_Lengkap,P.Nama_Produk_Varian,P.Kode_SKU,P.Harga_Jual,CONCAT(P.Kode_SKU,' / ',P.Kode_Barcode,':',P.Satuan_Kemasan,':',CONVERT(FORMAT(P.Harga_Jual,2) USING UTF8)) Data2 FROM (SELECT * FROM inv_produk_join WHERE Barcode_Nama LIKE ? AND Aktif=1 AND Harga_Jual>0 AND Grup_MemberID=?) P ORDER BY P.Nama_Produk,P.Qty LIMIT 50", ['%'.$tcari.'%', $this->id_grup_member]);
|
||||
while ($row = $stat->fetch(SimplePdo::FETCH_ASSOC)) {
|
||||
$ajson['autodata'][] = ['value'=>$row['InvID'], 'text'=>$row['Nama_Produk_Varian'], 'html'=>'<span class="text-primary">'.$row['Kode_SKU'].'</span> '.$row['Nama_Lengkap'].' - <strong>Rp'.rupiah($row['Harga_Jual']).'</strong>', 'data'=>$row['Data2'], 'bc'=>0];
|
||||
}
|
||||
}
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function scan_produk() {
|
||||
$tcari = Param::Get("Cari_Produk", "");
|
||||
$scandata = ['Nama_Supplier'=>"BELUM ADA"];
|
||||
|
||||
// Cari by SKU + Barcode
|
||||
// InvID : Kode_SKU + Kode_Barcode : Nama_Lengkap : Satuan_Kemasan : Harga_Jual
|
||||
$_row = $this->db->fetchRow("SELECT P.InvID,CONCAT(K.Kode_SKU,' / ',K.Kode_Barcode) Kode_Barang,P.Nama_Produk_Varian Nama_Barang,P.Satuan_Kemasan Nama_Satuan,CONVERT(FORMAT(P.Harga_Jual,2) USING UTF8) Harga_Jual FROM (SELECT * FROM inv_produk_join WHERE Aktif=1 AND Harga_Jual>0 AND Grup_MemberID=? AND (Kode_SKU=? OR Kode_Barcode=?)) P", [$this->id_grup_member, $tcari, $tcari]);
|
||||
if ($_row) $scandata = array_merge($scandata, $_row->getData());
|
||||
|
||||
if (isset($scandata['InvID']) && $scandata['InvID'] > 0) {
|
||||
$_row = $this->db->fetchRow("SELECT Nama_Sup Nama_Supplier FROM para_supplier WHERE SupID=(SELECT SupID FROM inv_produk_sup WHERE InvID=? ORDER BY Aktif DESC LIMIT 1)", [$scandata['InvID']]);
|
||||
if ($_row) $scandata = array_merge($scandata, $_row->getData());
|
||||
}
|
||||
$this->app->json([ $scandata ]);
|
||||
}
|
||||
|
||||
public function update_sup() {
|
||||
$n_sup = $this->db->fetchField("SELECT Nama_Sup FROM para_supplier WHERE SupID=(SELECT SupID FROM inv_produk_sup WHERE InvID=? ORDER BY Aktif DESC LIMIT 1)", [$this->id_inv]) ?? "BELUM ADA";
|
||||
$this->app->json([ ['type'=>"form", 'id'=>"Nama_Supplier", 'value'=>$n_sup] ]);
|
||||
}
|
||||
|
||||
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);
|
||||
$tharga = $form->textbox("_", "Harga_Jual", "", false);
|
||||
$tsup = $form->textbox("_", "Nama_Supplier", "", false);
|
||||
$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">Harga Jual @</div><div class="col">'.$tharga.'</div></div>
|
||||
<div class="row mb-1"><div class="col-sm-3 col-lg-3 col-form-label">Supplier</div><div class="col">'.$tsup.'</div></div>
|
||||
<input type="hidden" id="InvID" value="0" />';
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,567 @@
|
||||
<?php
|
||||
|
||||
/*******************************************************************
|
||||
|
||||
PHP Class : /Controller/Inv/JualController
|
||||
Description : Transaksi Penjualan
|
||||
Created By : Siau Pheng ([email protected]).
|
||||
Created Date : May 22th, 2010.
|
||||
Last Modified : September 27th, 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 JualController {
|
||||
|
||||
private array $web_app;
|
||||
private array $app_gel;
|
||||
private int $id_cab;
|
||||
private int $id_member;
|
||||
private int $id_grup_member;
|
||||
private string $mode;
|
||||
private string $mode_detail;
|
||||
private string $no_jual;
|
||||
private bool $is_pend;
|
||||
private int $id_inv;
|
||||
private int $id_satuan;
|
||||
private int $id_varian;
|
||||
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->web_app = (array) $session->get('WEB_APP');
|
||||
$this->app_gel = (array) $session->get('APP_GEL');
|
||||
$this->id_cab = Param::Int("CabID", $session->get('APP_INV')['CABANGID']);
|
||||
$this->id_member = Param::Int("MemberID", 0);
|
||||
$this->id_grup_member = Param::Int("Grup_MemberID", $session->get('APP_INV')['ECERANID']);
|
||||
$this->mode = Param::Get("mode", "");
|
||||
$this->mode_detail = Param::Get("mode_detail", "");
|
||||
$this->no_jual = Param::Get("No_Jual", "");
|
||||
$this->is_pend = str_contains($this->no_jual, "JUAL") === true;
|
||||
$this->id_inv = Param::Int("InvID", 0);
|
||||
$this->id_satuan = Param::Int("SatuanID", 0);
|
||||
$this->id_varian = Param::Int("VarianID", 0);
|
||||
$this->inv = new Inv($app);
|
||||
$this->gel = new Gel($app);
|
||||
}
|
||||
|
||||
public function table_detail() {
|
||||
if (in_array($this->mode_detail, ["insert","update","delete"])) {
|
||||
$iqty = Param::Float("Qty", 0) * -1;
|
||||
$disk_rp = Param::Float("Disk_Rupiah", 0);
|
||||
$disk_psn = Param::Float("Disk_Persen", 0);
|
||||
if ($disk_psn > 0) $disk_rp = Param::Float("Harga_Jual", 0) * $disk_psn * 0.01;
|
||||
if ($iqty === 0) $disk_rp = 0;
|
||||
|
||||
$sql = new SQL($this->app);
|
||||
$sql->set_table("tmp_inv_detail");
|
||||
$sql->add_param("No_Ref", $this->no_jual);
|
||||
$sql->add_param("InvID");
|
||||
$sql->add_param("SatuanID");
|
||||
$sql->add_param("VarianID");
|
||||
$sql->add_param("Qty", $iqty);
|
||||
$sql->add_param("Harga_Beli");
|
||||
$sql->add_param("Harga_Jual");
|
||||
$sql->add_param("Disk_Rupiah", $disk_rp);
|
||||
$sql->add_param("Total_Diskon", "Disk_Rupiah*-Qty", true);
|
||||
$sql->add_param_unix();
|
||||
$sql->add_param_userid();
|
||||
$sql->add_where("ID");
|
||||
$sql->add_where("No_Ref", $this->no_jual);
|
||||
|
||||
if ( $this->mode_detail === "insert" ) {
|
||||
$sql->InsertDB();
|
||||
} else if ( $this->mode_detail === "update" ) {
|
||||
$sql->UpdateDB();
|
||||
} else if ( $this->mode_detail === "delete" ) {
|
||||
$sql->DeleteDB();
|
||||
}
|
||||
}
|
||||
|
||||
$tsql = ''; $asql = [$this->no_jual]; $qtabel = "inv_detail";
|
||||
if ($this->is_pend) $qtabel = "tmp_inv_detail";
|
||||
if (in_array($this->mode, ["add","edit"])) {
|
||||
if ($this->mode === "add") { $tsql = " AND Unix=?"; $asql[] = $this->app->user()->unix(); }
|
||||
$qtabel = "tmp_inv_detail";
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("(SELECT * FROM ".$qtabel." WHERE No_Ref=?".$tsql.") D LEFT JOIN vi_inv_produk P ON (D.InvID=P.InvID AND D.SatuanID=P.SatuanID AND D.VarianID=P.VarianID)", "D.*,-D.Qty Qty2,P.Kode_SKU,P.Nama_Lengkap,(-D.Qty*D.Harga_Jual)-D.Total_Diskon Total", "", $asql);
|
||||
$obj->set_footer("COUNT(*) Harga_Jual,SUM(D.Total_Diskon) Disk_Rupiah,SUM((-D.Qty*D.Harga_Jual)-D.Total_Diskon) Total");
|
||||
$obj->add_field("ID", "No", "c");
|
||||
$obj->add_field("InvID", "InvID", "hid");
|
||||
$obj->add_field("SatuanID", "SatuanID", "hid");
|
||||
$obj->add_field("VarianID", "VarianID", "hid");
|
||||
$obj->add_field("Kode_SKU", "SKU", "c");
|
||||
$obj->add_field("Nama_Lengkap", "Nama Barang", "awr");
|
||||
$obj->add_field("Qty2", "Qty", "r", "rupiah2");
|
||||
$obj->add_field("Harga_Jual", "Harga @", "r", "rupiah", "items");
|
||||
$obj->add_field("Disk_Rupiah", "Diskon @", "r", "rupiah", "rupiah");
|
||||
$obj->add_field("Total", "Jumlah", "r", "rupiah", "rupiah");
|
||||
$obj->add_field("Promo", "S", "c", [0=>"N",1=>"T",2=>"D",3=>"P",4=>"H"]);
|
||||
$obj->set_field_order("ID", "D");
|
||||
if (in_array($this->mode, ["add","edit"])) {
|
||||
$obj->add_row_btn("clipboard", "Ubah", "JualJS.detail_ubah");
|
||||
$obj->add_row_btn("trash", "Hapus", "JualJS.detail_hapus", "Unix", $this->app->user()->unix());
|
||||
$obj->set_func_btn("JualJS.produk_brow", '<i class="bi-table me-1"></i> Browse');
|
||||
}
|
||||
$ajson[] = $obj->json_table("divDetailTabel");
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function brow_tx() {
|
||||
$tcari = Param::Get("Cari_TX");
|
||||
$tsql1 = ''; $tsql2 = ''; $asql = [$this->id_cab];
|
||||
if (!empty($tcari)) {
|
||||
$tsql2 .= "CONCAT(J.No_Jual,DATE_FORMAT(J.Tgl_Jual,'%d-%m-%Y'),B.Nama_Member) LIKE ?";
|
||||
array_push($asql, '%' . $tcari . '%');
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("(SELECT *,Total_Jual-Total_Diskon Jumlah FROM inv_jual WHERE POS=0 AND CabID=?".$tsql1.") J LEFT JOIN para_member B ON (J.MemberID=B.MemberID)", "J.*,B.Nama_Member", $tsql2, $asql);
|
||||
$obj->add_field("No_Jual", "No. Trans", "c");
|
||||
$obj->add_field("Tgl_Jual", "Tgl. Trans", "c", "sqltgl", "", "val-tgl");
|
||||
$obj->add_field("Nama_Member", "Nama Member", "awr");
|
||||
$obj->add_field("Total_Jual", "Sub. Total", "r", "rupiah2");
|
||||
$obj->add_field("Total_Diskon", "Diskon", "r", "rupiah2");
|
||||
$obj->add_field("Jumlah", "Jumlah", "r", "rupiah2");
|
||||
$obj->set_field_order("No_Jual", "D");
|
||||
$obj->set_func_select("JualJS.tx_select");
|
||||
$this->app->json([ $obj->db_table("divBrowTX") ]);
|
||||
}
|
||||
|
||||
public function brow_pending() {
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("(SELECT *,Total_Jual-Total_Diskon Jumlah FROM inv_jual_pend WHERE POS=0 AND CabID=? AND UserID=?) J LEFT JOIN para_member B ON (J.MemberID=B.MemberID)", "J.*,B.Nama_Member", "", [$this->id_cab, $this->app->user()->id()]);
|
||||
$obj->add_field("No_Jual", "No. Trans", "c");
|
||||
$obj->add_field("Tgl_Jual", "Tgl. Pending", "c", "sqltgl", "", "val-tgl");
|
||||
$obj->add_field("Nama_Member", "Nama Member", "awr");
|
||||
$obj->add_field("Total_Jual", "Sub. Total", "r", "rupiah2");
|
||||
$obj->add_field("Total_Diskon", "Diskon", "r", "rupiah2");
|
||||
$obj->add_field("Jumlah", "Jumlah", "r", "rupiah2");
|
||||
$obj->set_field_order("No_Jual", "D");
|
||||
$obj->add_row_btn("save", "Pilih", "JualJS.pending_select");
|
||||
if ($this->app->user()->is_level(1)) $obj->add_row_btn("trash", "Hapus", "JualJS.pending_delete", "UserID", $this->app->user()->id());
|
||||
$this->app->json([ $obj->db_table("divBrowPending") ]);
|
||||
}
|
||||
|
||||
public function brow_member() {
|
||||
$tcari = Param::Get("Cari_Member");
|
||||
$tsql = ''; $asql = [1];
|
||||
if (!empty($tcari)) {
|
||||
$tsql .= " AND CONCAT_WS(Kode_Member,Nama_Member,Alamat_Member,Telp_Member) LIKE ?";
|
||||
$asql[] = '%' . $tcari . '%';
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("para_member", "*", "Aktif=?".$tsql, $asql);
|
||||
$obj->add_field("MemberID", "ID", "hid");
|
||||
$obj->add_field("Grup_MemberID", "Grup ID", "hid");
|
||||
$obj->add_field("Kode_Member", "Kode", "c");
|
||||
$obj->add_field("Nama_Member", "Nama Member", "awr");
|
||||
$obj->add_field("Alamat_Member", "Alamat", "awr");
|
||||
$obj->add_field("Telp_Member", "Telp.", "awr");
|
||||
$obj->set_field_order("Nama_Member", "A");
|
||||
$obj->set_func_select("JualJS.member_select");
|
||||
$this->app->json([ $obj->db_table("divBrowMember") ]);
|
||||
}
|
||||
|
||||
public function brow_produk() {
|
||||
$tcari = Param::Get("Cari_Produk");
|
||||
$tsql = ''; $asql = [1, $this->id_grup_member];
|
||||
if (!empty($tcari)) {
|
||||
$tsql .= " AND Barcode_Nama LIKE ?";
|
||||
$asql[] = '%' . $tcari . '%';
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("inv_produk_join", "*", "Aktif=? AND Grup_MemberID=? AND Harga_Jual>0".$tsql, $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("Harga_Jual", "Harga Jual", "r", "rupiah");
|
||||
$obj->set_field_order("Kode_SKU", "A");
|
||||
$obj->set_func_select("JualJS.produk_select");
|
||||
$this->app->json([ $obj->db_table("divBrowProduk") ]);
|
||||
}
|
||||
|
||||
public function auto_member() {
|
||||
$tcari = Param::Get("Auto_Query", "");
|
||||
$ajson['autodata'] = [];
|
||||
|
||||
$stat = $this->db->runQuery("SELECT MemberID,Grup_MemberID,Kode_Member,Nama_Member,CONCAT(IF(Kode_Member='','',CONCAT(Kode_Member,' - ')),Nama_Member) Kode_Nama FROM para_member WHERE Aktif=1 AND CONCAT(Kode_Member,Nama_Member,Alamat_Member,Telp_Member) LIKE ? ORDER BY Nama_Member LIMIT 50", ['%'.$tcari.'%']);
|
||||
while ($row = $stat->fetch(SimplePdo::FETCH_ASSOC)) {
|
||||
$ajson['autodata'][] = ['value'=>$row['MemberID'], 'text'=>$row['Kode_Nama'], 'html'=>'<span class="text-primary">'.$row['Kode_Member'].'</span> '.$row['Nama_Member'], 'data'=>$row['Grup_MemberID'], 'bc'=>0];
|
||||
}
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function auto_produk() {
|
||||
$tcari = Param::Get("Auto_Query", "");
|
||||
$ajson['autodata'] = [];
|
||||
$bcode = 0; $arec = [];
|
||||
|
||||
if (is_numeric($tcari) && strlen($tcari) === 8) {
|
||||
// Cari by Member
|
||||
// M : Grup_Member
|
||||
$_row = $this->db->fetchRow("SELECT MemberID InvID,Nama_Member Nama_Lengkap,CONCAT('M:',Grup_MemberID) Data2 FROM para_member WHERE Aktif=1 AND Kode_Member=?", [$tcari]);
|
||||
if ($_row) {
|
||||
$bcode = 1;
|
||||
$arec = $_row->getData();
|
||||
}
|
||||
}
|
||||
|
||||
// Cari by SKU + Barcode
|
||||
// P : Satuan : Varian : Harga_Pokok : Harga_Jual : Stok
|
||||
if ($bcode === 0) {
|
||||
$_row = $this->db->fetchRow("SELECT P.InvID,P.Nama_Lengkap,CONCAT('P:',P.SatuanID,':',P.VarianID,':',CONVERT(P.Harga_Pokok USING UTF8),':',CONVERT(P.Harga_Jual USING UTF8),':',CONVERT(IFNULL(X.Stok,0) USING UTF8)) Data2 FROM (SELECT * FROM inv_produk_join WHERE Aktif=1 AND Harga_Jual>0 AND Grup_MemberID=? AND (Kode_SKU=? OR Kode_Barcode=?)) P LEFT JOIN inv_stok X ON (X.CabID=? AND X.InvID=P.InvID)", [$this->id_grup_member, $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,P.Harga_Jual,CONCAT('P:',P.SatuanID,':',P.VarianID,':',CONVERT(P.Harga_Pokok USING UTF8),':',CONVERT(P.Harga_Jual USING UTF8),':',CONVERT(IFNULL(X.Stok,0) USING UTF8)) Data2 FROM (SELECT * FROM inv_produk_join WHERE Barcode_Nama LIKE ? AND Aktif=1 AND Harga_Jual>0 AND Grup_MemberID=?) 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_grup_member, $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'].' - <strong>Rp'.rupiah($row['Harga_Jual']).'</strong> <span class="text-danger">('.(string) $row['Sisa_Stok'].')</span>', 'data'=>$row['Data2'], 'bc'=>0];
|
||||
}
|
||||
}
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function form_master() {
|
||||
$ajson = [ 'error'=>"", 'html'=>"" ];
|
||||
$atabel = [];
|
||||
|
||||
if ($this->mode === "pending-edit") {
|
||||
$this->inv->Pending_Edit($this->no_jual);
|
||||
$atabel = $this->Data_Jual($this->no_jual);
|
||||
$this->mode = "edit";
|
||||
} else if ($this->mode === "pending-save") {
|
||||
$b_baru = false;
|
||||
if (str_ends_with($this->no_jual, "#00")) {
|
||||
$b_baru = true;
|
||||
$no_lama = $this->no_jual;
|
||||
$this->no_jual = $this->Pending_Nomor();
|
||||
$this->inv->Pending_Save($no_lama, $this->no_jual);
|
||||
}
|
||||
$apending = $this->db->fetchRow("SELECT SUM(-Qty*Harga_Jual) Jual,SUM(Total_Diskon) Diskon FROM tmp_inv_detail WHERE No_Ref=?", [$this->no_jual]) ?? ['Jual'=>0, 'Diskon'=>0];
|
||||
|
||||
$sql = new SQL($this->app);
|
||||
$sql->set_table("inv_jual_pend");
|
||||
$sql->add_param("No_Jual", $this->no_jual);
|
||||
$sql->add_param_date("Tgl_Jual");
|
||||
$sql->add_param("CabID");
|
||||
$sql->add_param("MemberID");
|
||||
$sql->add_param("Total_Jual", $apending['Jual']);
|
||||
$sql->add_param("Total_Diskon", $apending['Diskon']);
|
||||
$sql->add_param("POS", 0);
|
||||
$sql->add_param_userid();
|
||||
$sql->add_where("No_Jual", $this->no_jual);
|
||||
if ($b_baru) $sql->InsertDB();
|
||||
else $sql->UpdateDB();
|
||||
$atabel = $this->Data_Jual();
|
||||
} else if ($this->mode === "pending-delete") {
|
||||
$this->inv->Pending_Delete($this->no_jual);
|
||||
$this->db->delete("inv_jual_pend", "No_Jual=?", [$this->no_jual]);
|
||||
$atabel = $this->Data_Jual();
|
||||
} else if ($this->mode === "add") {
|
||||
$atabel = $this->Data_Jual("", true);
|
||||
} else if ($this->mode === "edit") {
|
||||
$this->inv->Detail_Copy($this->no_jual, true);
|
||||
$atabel = $this->Data_Jual($this->no_jual);
|
||||
} else if ($this->mode === "save") {
|
||||
$tgl_jual = Param::Get("Tgl_Jual", "");
|
||||
$no_lama = $this->no_jual;
|
||||
if ($this->is_pend) {
|
||||
$this->no_jual = $this->inv->Nomor_POS("FJ", $tgl_jual, true);
|
||||
if (!str_ends_with($no_lama, "#00")) $this->db->delete("inv_jual_pend", "No_Jual=?", [$no_lama]);
|
||||
}
|
||||
|
||||
$this->inv->Detail_Save($this->no_jual, 5, $this->id_cab, $tgl_jual, $this->is_pend, $no_lama);
|
||||
|
||||
$ajual = $this->db->fetchRow("SELECT SUM(-Qty*Harga_Jual) Jual, SUM(Total_Diskon) Diskon, SUM(-Qty*Harga_Beli) HPP FROM inv_detail WHERE No_Ref=?", [$this->no_jual]) ?? ['Jual'=>0, 'Diskon'=>0, 'HPP'=>0];
|
||||
|
||||
$sql = new SQL($this->app);
|
||||
$sql->set_table("inv_jual");
|
||||
$sql->add_param_date("Tgl_Jual");
|
||||
$sql->add_param("CabID", $this->id_cab);
|
||||
$sql->add_param("MemberID");
|
||||
$sql->add_param("Total_Jual", $ajual['Jual']);
|
||||
$sql->add_param("Total_Diskon", $ajual['Diskon']);
|
||||
$sql->add_param("Total_HPP", $ajual['HPP']);
|
||||
$sql->add_param("POS", 0);
|
||||
$sql->add_param_stamp();
|
||||
$sql->add_param_userid();
|
||||
$sql->add_where("No_Jual", $this->no_jual);
|
||||
$sql->UpdateDB();
|
||||
|
||||
$this->gel->Update_Lunas_Buy($this->id_member);
|
||||
|
||||
// PROSES MEMBER POINT
|
||||
if ($this->id_member > 0) {
|
||||
$apoint = $this->db->fetchColumn("SELECT Point_TipeID FROM inv_point_tipe WHERE Aktif=1 ORDER BY Point_TipeID") ?? [];
|
||||
if (count($apoint) > 0) {
|
||||
$amember = $this->db->fetchRow("SELECT Grup_MemberID,IM,Kode_Member FROM para_member WHERE MemberID=?", [$this->id_member]);
|
||||
if ($amember && ($amember['IM'] === 1 || ($amember['IM'] === 0 && !empty($amember['Kode_Member'])))) {
|
||||
$this->db->runQuery("DELETE FROM inv_point_tx WHERE No_TX=?", [$this->no_jual]);
|
||||
foreach ($apoint as $id_tipe) {
|
||||
if ($amember['IM'] === 0 && $id_tipe === 1) continue;
|
||||
$tot_point = $this->inv->Point_Hitung($this->no_jual, $tgl_jual, $amember['Grup_MemberID'], 0, $id_tipe);
|
||||
if ($tot_point > 0) $this->db->runQuery("INSERT INTO inv_point_tx (No_TX,Tgl_TX,Point_TipeID,CabID,MemberID,Point,Nilai_Point,DateStamp,UserID) VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), ?)", [$this->no_jual, tgl_sql2str($tgl_jual), $id_tipe, $this->id_cab, $this->id_member, $tot_point, $tot_point, $this->app->user()->id()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PROSES POSTING GL
|
||||
$ainfo = $this->db->fetchRow("SELECT J.*,B.Nama_Member,(J.Total_Jual-J.Total_Diskon) Tagihan FROM (SELECT * FROM inv_jual WHERE No_Jual=?) J LEFT JOIN para_member B ON (B.MemberID=J.MemberID)", [$this->no_jual]);
|
||||
if (count($ainfo) > 0) {
|
||||
$ajurnal = [
|
||||
'Kode_Jurnal' => $ainfo['No_Jual'],
|
||||
'TipeID' => 8,
|
||||
'CabID' => $ainfo['CabID'],
|
||||
'Tanggal' => tgl_sql2str($ainfo['Tgl_Jual']),
|
||||
'Kode_Ref' => $ainfo['No_Jual'],
|
||||
'Catatan' => "Penjualan : ".$ainfo['No_Jual']." | ".$ainfo['Nama_Member']." | ".$this->app->user()->username()
|
||||
];
|
||||
$adetail = [
|
||||
[ 'Kode_Rek' => $this->app_gel['HPP'], 'DK' => "D", 'Jumlah' => $ainfo['Total_HPP'] ],
|
||||
[ 'Kode_Rek' => $this->app_gel['STOK'], 'DK' => "K", 'Jumlah' => $ainfo['Total_HPP'] ],
|
||||
[ 'Kode_Rek' => $this->app_gel['PIU_USAHA'], 'DK' => "D", 'Jumlah' => $ainfo['Tagihan'], 'MemberID' => $ainfo['MemberID'] ],
|
||||
[ 'Kode_Rek' => $this->app_gel['JUAL'], 'DK' => "K", 'Jumlah' => $ainfo['Tagihan'] ]
|
||||
];
|
||||
$this->gel->Jurnal_Post($ajurnal, $adetail);
|
||||
}
|
||||
$atabel = $this->Data_Jual($this->no_jual);
|
||||
$this->mode = "view";
|
||||
|
||||
} else if ($this->mode === "cancel") {
|
||||
if (str_ends_with($this->no_jual, "#00") || !$this->is_pend) $this->inv->Detail_Cancel($this->no_jual);
|
||||
$atabel = $this->Data_Jual();
|
||||
} else {
|
||||
$atabel = $this->Data_Jual($this->no_jual);
|
||||
}
|
||||
|
||||
$enable = in_array($this->mode, ["add","edit"]) ? true : false;
|
||||
$form = new Form($this->app);
|
||||
$tnota = $form->textbox("_", "No_Jual", $atabel['No_Jual'], !$enable, true, "text", "nomor transaksi");
|
||||
$ttglnota = $form->datebox("_", "Tgl_Jual", $atabel['Tgl_Jual'], $enable, true);
|
||||
$ttgllunas = $form->datebox("_", "Tgl_Lunas", $atabel['Tgl_Lunas'], false, false);
|
||||
$tcab = $form->option_db("_", "CabID", $atabel['CabID'], $enable, false, "para_cabang", ["CabID","Nama_Cab"], "Aktif=1 ORDER BY Nama_Cab", [0," "]);
|
||||
$tmember = $form->textauto("_", "Nama_Member", ['value'=>$atabel['MemberID'],'text'=>$atabel['Nama_Member']], true, true, "nama member");
|
||||
$tpiutang = $form->textbox("_", "Total_Piutang", 0, false, false, "double");
|
||||
$ajson['html'] = '
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-lg-6">
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="No_Jual">Nomor Transaksi</label>
|
||||
<div class="col"><div class="input-group">'.$tnota.'<button id="butBrow" class="btn btn-info" type="button"><i class="bi-search"></i></button></div></div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="Tgl_Jual">Tanggal Transaksi</label>
|
||||
<div class="col-sm-7 col-lg-5">'.$ttglnota.'</div>
|
||||
</div>
|
||||
<div class="row mb-1 collapse iextra" id="iex1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label">Tanggal Lunas</label>
|
||||
<div class="col-sm-7 col-lg-5">'.$ttgllunas.'</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-lg-6">
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="CabID">Nama Cabang</label>
|
||||
<div class="col">'.$tcab.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="MemberID">Nama Member<span class="float-end"><a class="text-decoration-none text-active" type="button" data-bs-toggle="collapse" data-bs-target=".iextra" aria-expanded="false" aria-controls="iex1 iex2"><i class="fw-bolder bi-arrows-expand"></i></a></span></label>
|
||||
<div class="col"><div class="input-group">'.$tmember.'<button id="butBrowMember" class="btn btn-info" type="button"><i class="bi-people-fill"></i></button></div></div>
|
||||
</div>
|
||||
<div class="row mb-1 collapse iextra" id="iex2">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label">Jumlah Piutang</label>
|
||||
<div class="col">'.$tpiutang.'</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1"><div class="col"><hr class="my-1"></div></div>
|
||||
<div class="row mb-1'.(in_array($this->mode, ['add','edit']) ? '' : ' d-none').'">
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<input type="search" class="form-control fs-5" id="Nama_Produk" value="" placeholder="Scan SKU / Barcode / Ketik Nama Barang" autocomplete="off" />
|
||||
</div>
|
||||
<div class="col-sm-3 col-lg-2">
|
||||
<input type="double" class="form-control double fs-5" id="POS_Qty" value="1.00" maxlength="10" />
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" id="MemberID" value="'.$atabel['MemberID'].'" >
|
||||
<input type="hidden" id="Grup_MemberID" value="'.$atabel['Grup_MemberID'].'" >
|
||||
<input type="hidden" id="Lunas" value="'.$atabel['Lunas'].'" >
|
||||
<input type="hidden" id="mode" value="'.$this->mode.'" >';
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function form_produk() {
|
||||
$id = (int) Param::Get("ID", 0);
|
||||
$atabel = [ 'ID'=>$id, 'InvID'=>$this->id_inv, 'SatuanID'=>$this->id_satuan, 'VarianID'=>$this->id_varian, 'Kode_SKU'=>"", 'Kode_Barcode'=>"", 'Nama_Lengkap'=>"", 'Satuan_Kemasan'=>"", 'Qty'=>0, 'Harga_Beli'=>0, 'Harga_Jual'=>0, 'Disk_Rupiah'=>0 ];
|
||||
if ($id > 0) {
|
||||
$_row = $this->db->fetchRow("SELECT ID,-Qty Qty,Harga_Beli,Harga_Jual,Disk_Rupiah FROM tmp_inv_detail WHERE No_Ref=? AND ID=?", [$this->no_jual, $id]);
|
||||
if ($_row) $atabel = array_merge($atabel, $_row->getData());
|
||||
}
|
||||
if ($this->id_inv > 0 && $this->id_satuan > 0) {
|
||||
$_row = $this->db->fetchRow("SELECT Kode_SKU,Kode_Barcode,Nama_Lengkap,Satuan_Kemasan,Harga_Pokok Harga_Beli,Harga_Jual FROM inv_produk_join WHERE InvID=? AND SatuanID=? AND VarianID=? AND Grup_MemberID=?", [$this->id_inv, $this->id_satuan, $this->id_varian, $this->id_grup_member]);
|
||||
if ($_row) $atabel = array_merge($atabel, $_row->getData());
|
||||
}
|
||||
|
||||
$form = new Form($this->app);
|
||||
$tsku = $form->textbox("_", "Kode_SKU", $atabel['Kode_SKU']. " / " .$atabel['Kode_Barcode'], false);
|
||||
$tnama = $form->textbox("_", "Nama_Lengkap", $atabel['Nama_Lengkap'], false);
|
||||
$tqty = $form->textbox("_", "Qty", $atabel['Qty'], true, true, "double");
|
||||
$tjual = $form->textbox("_", "Harga_Jual", $atabel['Harga_Jual'], false, false, "double");
|
||||
$tdisrp = $form->textbox("_", "Disk_Rupiah", $atabel['Disk_Rupiah'], true, true, "double");
|
||||
$tdispn = $form->textbox("_", "Disk_Persen", 0, true, false, "double");
|
||||
$ttot = $form->textbox("_", "Jumlah", 0, false, false, "double");
|
||||
$tsat = $form->textbox("_", "Nama_Satuan", $atabel['Satuan_Kemasan'], false);
|
||||
$ajson['html'] = '
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label">Kode SKU / Barcode</label>
|
||||
<div class="col">'.$tsku.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label">Nama Barang</label>
|
||||
<div class="col">'.$tnama.'</div>
|
||||
</div>
|
||||
<div class="row mb-1"><hr class="my-1"></div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label" for="Qty">Qty</label>
|
||||
<div class="col-sm-4 col-lg-5"><div class="input-group">'.$tqty.$tsat.'</div></div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label">Harga (@)</label>
|
||||
<div class="col-sm-8 col-lg-5">'.$tjual.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label" for="Disk_Rupiah">Diskon (@)</label>
|
||||
<div class="col-sm-8 col-lg-5">'.$tdisrp.'</div>
|
||||
<div class="col-sm-3 col-lg-3"><div class="input-group"><div class="input-group-text">≈</div>'.$tdispn.'<div class="input-group-text">%</div></div></div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label">Sub Total</label>
|
||||
<div class="col-sm-8 col-lg-5">'.$ttot.'</div>
|
||||
</div>
|
||||
<input type="hidden" id="ID" value="'.$atabel['ID'].'" >
|
||||
<input type="hidden" id="InvID" value="'.$atabel['InvID'].'" >
|
||||
<input type="hidden" id="SatuanID" value="'.$atabel['SatuanID'].'" >
|
||||
<input type="hidden" id="VarianID" value="'.$atabel['VarianID'].'" >
|
||||
<input type="hidden" id="Harga_Beli" value="'.$atabel['Harga_Beli'].'" >
|
||||
<input type="hidden" id="mode_detail" value="'.$this->mode_detail.'" >';
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function proses_delete() {
|
||||
if ($this->is_pend === false) {
|
||||
$this->db->runQuery("DELETE FROM inv_jual WHERE No_Jual=?", [$this->no_jual]);
|
||||
$this->db->runQuery("DELETE FROM inv_detail WHERE No_Ref=?", [$this->no_jual]);
|
||||
// PROSES POSTING GL
|
||||
$this->db->runQuery("DELETE FROM gel_jurnal WHERE Kode_Jurnal=?", [$this->no_jual]);
|
||||
$this->db->runQuery("DELETE FROM gel_jurnal_detail WHERE Kode_Jurnal=?", [$this->no_jual]);
|
||||
// PROSES MEMBER POINT
|
||||
if ($this->id_member > 0) $this->db->runQuery("DELETE FROM inv_point_tx WHERE No_TX=?", [$this->no_jual]);
|
||||
} else {
|
||||
$this->db->runQuery("DELETE FROM inv_jual_pend WHERE No_Jual=?", [$this->no_jual]);
|
||||
$this->db->runQuery("DELETE FROM tmp_inv_detail WHERE No_Ref=?", [$this->no_jual]);
|
||||
}
|
||||
$this->app->json([ 'status' => true ]);
|
||||
}
|
||||
|
||||
public function update_piutang() {
|
||||
$_piut = $this->db->fetchField("SELECT SUM(Total_Jual-Total_Diskon-Total_Bayar-Total_Potong) Jumlah FROM inv_jual WHERE MemberID=? AND Lunas=0", [$this->id_member]) ?? 0;
|
||||
$this->app->json([ ['type'=>"form", 'id'=>"Total_Piutang", 'value'=>rupiah2($_piut)] ]);
|
||||
}
|
||||
|
||||
public function index() {
|
||||
$this->app->json(['html' => '
|
||||
<div class="fade-in">
|
||||
<div class="card"><div class="card-body">
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="tx-tab" data-bs-toggle="tab" data-bs-target="#tx" type="button" role="tab" aria-controls="tx" aria-selected="true"><i class="bi-database me-2"></i>Transaksi Penjualan</button>
|
||||
</li>
|
||||
<li class="nav-item ms-auto">
|
||||
<button class="btn btn-primary mb-1 ms-2" id="butTambah" type="button"><i class="bi-plus-lg me-2"></i>Tambah</button>
|
||||
<button class="btn btn-info mb-1 ms-2" id="butUbah" type="button"><i class="bi-clipboard me-2"></i>Ubah</button>
|
||||
<button class="btn btn-warning mb-1 ms-2" id="butHapus" type="button"><i class="bi-trash me-2"></i>Hapus</button>
|
||||
<button class="btn btn-info mb-1 ms-2" id="butPendingBrow" type="button"><i class="bi-cloud me-2"></i>Pending</button>
|
||||
<button class="btn btn-secondary mb-1 ms-2 dropdown-toggle" id="butPrint" type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="bi-printer me-2"></i>Cetak</button>
|
||||
<div class="dropdown-menu" aria-labelledby="butPrint">
|
||||
<a class="dropdown-item" href="#" id="printNota">Cetak Nota</a>
|
||||
<a class="dropdown-item" href="#" id="printPOS">Cetak POS</a>
|
||||
</div>
|
||||
<button class="btn btn-danger mb-1 ms-2" id="butBatal" type="button"><i class="bi-x-lg me-2"></i>Batal</button>
|
||||
<button class="btn btn-warning mb-1 ms-2" id="butPendingSimpan" type="button"><i class="bi-cloud-upload me-2"></i>Simpan Pending</button>
|
||||
<button class="btn btn-success mb-1 ms-2" id="butSimpan" type="button"><i class="bi-save me-2"></i>Simpan</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content border border-top-0 p-3">
|
||||
<div class="tab-pane fade active show" id="tx" role="tabpanel" aria-labelledby="tx-tab">
|
||||
<div id="divTXMaster"> </div>
|
||||
<div id="divDetailTabel"> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
</div>'
|
||||
]);
|
||||
}
|
||||
|
||||
private function Data_Jual(string $nomor="", bool $baru=false): array {
|
||||
$aparam = [
|
||||
'No_Jual' => $nomor,
|
||||
'Tgl_Jual' => tgl_ymd(),
|
||||
'Tgl_Lunas' => "0000-00-00",
|
||||
'CabID' => $this->id_cab,
|
||||
'MemberID' => $this->id_member,
|
||||
'Grup_MemberID' => $this->id_grup_member,
|
||||
'Nama_Member' => "",
|
||||
'Lunas' => 0
|
||||
];
|
||||
if ($baru) $aparam['No_Jual'] = "JUAL".$this->web_app['SERVER_ID'].(string) $this->id_cab.$this->app->user()->id(3)."#00";
|
||||
if (!empty($nomor)) {
|
||||
$tabel_jual = (str_contains($nomor, "JUAL") === false) ? "inv_jual" : "inv_jual_pend";
|
||||
$row = $this->db->fetchRow("SELECT * FROM ".$tabel_jual." WHERE CabID=? AND No_Jual=?", [$this->id_cab, $nomor]);
|
||||
if ($row) $aparam = array_merge($aparam, $row->getData());
|
||||
if ($aparam['MemberID'] > 0) {
|
||||
$row = $this->db->fetchRow("SELECT Grup_MemberID,Nama_Member FROM para_member WHERE MemberID=?", [$aparam['MemberID']]);
|
||||
if ($row) $aparam = array_merge($aparam, $row->getData());
|
||||
}
|
||||
}
|
||||
return $aparam;
|
||||
}
|
||||
|
||||
private function Pending_Nomor(): string {
|
||||
$tno = "JUAL".$this->web_app['SERVER_ID'].(string) $this->id_cab.$this->app->user()->id(3)."#";
|
||||
$ino = (int) $this->db->fetchField("SELECT MAX(RIGHT(No_Jual,2)) FROM inv_jual_pend WHERE No_Jual LIKE ?", [$tno.'%']) ?? 0;
|
||||
$tno .= isi_nol(++$ino, 2);
|
||||
return $tno;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,373 @@
|
||||
<?php
|
||||
|
||||
/*******************************************************************
|
||||
|
||||
PHP Class : /Controller/Inv/MutasiController
|
||||
Description : Transaksi Mutasi Stok Antar Cabang
|
||||
Created By : Siau Pheng (siaupheng@3fonia.com).
|
||||
Created Date : February 28th, 2011.
|
||||
Last Modified : September 27th, 2026.
|
||||
|
||||
(c) 3FONIA Software; WWW.3FONIA.COM.
|
||||
|
||||
*******************************************************************/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller\Inv;
|
||||
|
||||
use App\Utils\Inv;
|
||||
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 MutasiController {
|
||||
|
||||
private array $web_app;
|
||||
private int $id_cab_dari;
|
||||
private int $id_cab_ke;
|
||||
private string $mode;
|
||||
private string $mode_detail;
|
||||
private string $no_mutasi;
|
||||
private bool $is_baru;
|
||||
private int $id_inv;
|
||||
private int $id_satuan;
|
||||
private int $id_varian;
|
||||
private Inv $inv;
|
||||
protected Engine $app;
|
||||
protected SimplePdo $db;
|
||||
|
||||
public function __construct(Engine $app, SimplePdo $db, Session $session) {
|
||||
$this->app = $app;
|
||||
$this->db = $db;
|
||||
$this->web_app = (array) $session->get('WEB_APP');
|
||||
$this->id_cab_dari = Param::Int("Dari_CabID", $session->get('APP_INV')['CABANGID']);
|
||||
$this->id_cab_ke = Param::Int("Ke_CabID", 0);
|
||||
$this->mode = Param::Get("mode", "");
|
||||
$this->mode_detail = Param::Get("mode_detail", "");
|
||||
$this->no_mutasi = Param::Get("No_Mutasi", "");
|
||||
$this->is_baru = str_contains($this->no_mutasi, "MUTA") === true;
|
||||
$this->id_inv = Param::Int("InvID", 0);
|
||||
$this->id_satuan = Param::Int("SatuanID", 0);
|
||||
$this->id_varian = Param::Int("VarianID", 0);
|
||||
$this->inv = new Inv($app);
|
||||
}
|
||||
|
||||
public function table_detail() {
|
||||
if (in_array($this->mode_detail, ["insert","update","delete"])) {
|
||||
$iqty = Param::Float("Qty", 0);
|
||||
|
||||
$sql = new SQL($this->app);
|
||||
$sql->set_table("tmp_inv_detail");
|
||||
$sql->add_param("No_Ref", $this->no_mutasi);
|
||||
$sql->add_param("InvID");
|
||||
$sql->add_param("SatuanID");
|
||||
$sql->add_param("VarianID");
|
||||
$sql->add_param("Qty", $iqty);
|
||||
$sql->add_param("Harga_Beli");
|
||||
$sql->add_param("Harga_Jual", "Harga_Beli", true);
|
||||
$sql->add_param_unix();
|
||||
$sql->add_param_userid();
|
||||
$sql->add_where("ID");
|
||||
$sql->add_where("No_Ref", $this->no_mutasi);
|
||||
|
||||
if ( $this->mode_detail === "insert" ) {
|
||||
$sql->InsertDB();
|
||||
} else if ( $this->mode_detail === "update" ) {
|
||||
$sql->UpdateDB();
|
||||
} else if ( $this->mode_detail === "delete" ) {
|
||||
$sql->DeleteDB();
|
||||
}
|
||||
}
|
||||
|
||||
$tsql = ' AND Qty>0'; $asql = [$this->no_mutasi]; $qtabel = "inv_detail";
|
||||
if (in_array($this->mode, ["add","edit"])) {
|
||||
if ($this->mode === "add") { $tsql = " AND Unix=?"; array_push($asql, $this->app->user()->unix()); }
|
||||
$qtabel = "tmp_inv_detail";
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("(SELECT * FROM ".$qtabel." WHERE No_Ref=?".$tsql.") D LEFT JOIN vi_inv_produk P ON (D.InvID=P.InvID AND D.SatuanID=P.SatuanID AND D.VarianID=P.VarianID)", "D.*,P.Kode_SKU,P.Nama_Lengkap,(D.Qty*D.Harga_Beli) Total", "", $asql);
|
||||
$obj->set_footer("COUNT(*) Harga_Beli,SUM(D.Qty*D.Harga_Beli) Total");
|
||||
$obj->add_field("ID", "No", "c");
|
||||
$obj->add_field("InvID", "InvID", "hid");
|
||||
$obj->add_field("SatuanID", "SatuanID", "hid");
|
||||
$obj->add_field("VarianID", "VarianID", "hid");
|
||||
$obj->add_field("Kode_SKU", "SKU", "c");
|
||||
$obj->add_field("Nama_Lengkap", "Nama Barang", "awr");
|
||||
$obj->add_field("Qty", "Qty", "r", "rupiah2");
|
||||
$obj->add_field("Harga_Beli", "Harga @", "r", "rupiah", "items");
|
||||
$obj->add_field("Total", "Jumlah", "r", "rupiah", "rupiah");
|
||||
$obj->set_field_order("ID", "D");
|
||||
if (in_array($this->mode, ["add","edit"])) {
|
||||
$obj->add_row_btn("clipboard", "Ubah", "MutasiJS.detail_ubah");
|
||||
$obj->add_row_btn("trash", "Hapus", "MutasiJS.detail_hapus", "Unix", $this->app->user()->unix());
|
||||
$obj->set_func_btn("MutasiJS.produk_brow", '<i class="bi-table me-1"></i> Browse');
|
||||
}
|
||||
$ajson[] = $obj->json_table("divDetailTabel");
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function brow_tx() {
|
||||
$tcari = Param::Get("Cari_TX");
|
||||
$tsql = ''; $asql = [];
|
||||
if (!empty($tcari)) {
|
||||
$tsql .= " WHERE CONCAT(No_Mutasi,DATE_FORMAT(Tgl_Mutasi,'%d-%m-%Y')) LIKE ?";
|
||||
array_push($asql, '%' . $tcari . '%');
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("(SELECT * FROM inv_mutasi".$tsql.") M LEFT JOIN para_cabang C1 ON (C1.CabID=M.Dari_CabID) LEFT JOIN para_cabang C2 ON (C2.CabID=M.Ke_CabID)", "M.*,C1.Nama_Cab Cab1,C2.Nama_Cab Cab2", "", $asql);
|
||||
$obj->add_field("No_Mutasi", "No. Trans", "c");
|
||||
$obj->add_field("Tgl_Mutasi", "Tgl. Trans", "c", "sqltgl", "", "val-tgl");
|
||||
$obj->add_field("Cab1", "Dari Cab", "c");
|
||||
$obj->add_field("Cab2", "Ke Cab", "c");
|
||||
$obj->add_field("Total_Mutasi", "Total", "r", "rupiah2");
|
||||
$obj->set_field_order("No_Mutasi", "D");
|
||||
$obj->set_func_select("MutasiJS.tx_select");
|
||||
$this->app->json([ $obj->db_table("divBrowTX") ]);
|
||||
}
|
||||
|
||||
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_dari);
|
||||
|
||||
$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.InvID,P.SatuanID,P.VarianID,P.Kode_SKU,P.Kode_Barcode,P.Nama_Lengkap,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("Sisa_Stok", "Stok", "r", "rupiah2");
|
||||
$obj->set_field_order("Kode_SKU", "A");
|
||||
$obj->set_func_select("MutasiJS.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 : Harga_Pokok
|
||||
$_row = $this->db->fetchRow("SELECT P.InvID,P.Nama_Lengkap,CONCAT(P.SatuanID,':',P.VarianID,':',CONVERT(P.Harga_Pokok 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_dari]);
|
||||
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,':',CONVERT(P.Harga_Pokok 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_dari]);
|
||||
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 form_master() {
|
||||
$ajson = [ 'error'=>"", 'html'=>"" ];
|
||||
$atabel = [];
|
||||
|
||||
if ($this->mode === "add") {
|
||||
$atabel = $this->Data_Mutasi("", true);
|
||||
} else if ($this->mode === "edit") {
|
||||
$this->inv->Detail_Copy($this->no_mutasi, true);
|
||||
$atabel = $this->Data_Mutasi($this->no_mutasi);
|
||||
} else if ($this->mode === "save") {
|
||||
$no_lama = $this->no_mutasi;
|
||||
$tgl_mutasi = Param::Get("Tgl_Mutasi");
|
||||
if ($this->is_baru) {
|
||||
$this->no_mutasi = $this->inv->Nomor_Baru("M", $tgl_mutasi, true);
|
||||
}
|
||||
|
||||
$this->inv->Detail_Save($this->no_mutasi, 2, $this->id_cab_ke, $tgl_mutasi, $this->is_baru, $no_lama, 0, true, $this->id_cab_dari);
|
||||
|
||||
$tot_mutasi = $this->db->fetchField("SELECT SUM(Qty*Harga_Beli) Beli FROM inv_detail WHERE No_Ref=? AND Qty>0", [$this->no_mutasi]) ?? 0;
|
||||
|
||||
$sql = new SQL($this->app);
|
||||
$sql->set_table("inv_mutasi");
|
||||
$sql->add_param_date("Tgl_Mutasi");
|
||||
$sql->add_param("Dari_CabID");
|
||||
$sql->add_param("Ke_CabID");
|
||||
$sql->add_param("Total_Mutasi", $tot_mutasi);
|
||||
$sql->add_param("Catatan");
|
||||
$sql->add_param_stamp();
|
||||
$sql->add_param_userid();
|
||||
$sql->add_where("No_Mutasi", $this->no_mutasi);
|
||||
$sql->UpdateDB();
|
||||
|
||||
$atabel = $this->Data_Mutasi($this->no_mutasi);
|
||||
$this->mode = "view";
|
||||
|
||||
} else if ($this->mode === "cancel") {
|
||||
$this->inv->Detail_Cancel($this->no_mutasi);
|
||||
$atabel = $this->Data_Mutasi();
|
||||
} else {
|
||||
$atabel = $this->Data_Mutasi($this->no_mutasi);
|
||||
}
|
||||
|
||||
$enable = in_array($this->mode, ["add","edit"]) ? true : false;
|
||||
$form = new Form($this->app);
|
||||
$tnota = $form->textbox("_", "No_Mutasi", $atabel['No_Mutasi'], !$enable, true, "text", "nomor transaksi");
|
||||
$ttglnota = $form->datebox("_", "Tgl_Mutasi", $atabel['Tgl_Mutasi'], $enable, true);
|
||||
$tcab_dari = $form->option_db("_", "Dari_CabID", $atabel['Dari_CabID'], $enable, false, "para_cabang", ["CabID","Nama_Cab"], "Aktif=1 ORDER BY Nama_Cab", [0," "]);
|
||||
$tcab_ke = $form->option_db("_", "Ke_CabID", $atabel['Ke_CabID'], $enable, false, "para_cabang", ["CabID","Nama_Cab"], "Aktif=1 ORDER BY Nama_Cab", [0," "]);
|
||||
$tcatat = $form->textbox("_", "Catatan", $atabel['Catatan'], $enable, false, "text");
|
||||
$ajson['html'] = '
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-lg-6">
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="No_Mutasi">Nomor Transaksi</label>
|
||||
<div class="col"><div class="input-group">'.$tnota.'<button id="butBrow" class="btn btn-info" type="button"><i class="bi-search"></i></button></div></div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="Tgl_Mutasi">Tanggal Transaksi</label>
|
||||
<div class="col-sm-7 col-lg-5">'.$ttglnota.'</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-lg-6">
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="Dari_CabID">Dari Cabang</label>
|
||||
<div class="col">'.$tcab_dari.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="Ke_CabID">Ke Cabang</label>
|
||||
<div class="col">'.$tcab_ke.'</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-3 col-lg-2 col-form-label" for="Catatan" style="width:12.5%;">Catatan</label>
|
||||
<div class="col">'.$tcatat.'</div>
|
||||
</div>
|
||||
<div class="row mb-1"><div class="col"><hr class="my-1"></div></div>
|
||||
<div class="row mb-1'.(in_array($this->mode, ['add','edit']) ? '' : ' d-none').'">
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<input type="search" class="form-control fs-5" id="Nama_Produk" value="" placeholder="Scan SKU / Barcode / Ketik Nama Barang" autocomplete="off" />
|
||||
</div>
|
||||
<div class="col-sm-3 col-lg-2">
|
||||
<input type="double" class="form-control double fs-5" id="POS_Qty" value="1.00" maxlength="10" />
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" id="mode" value="'.$this->mode.'" >';
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function form_produk() {
|
||||
$id = (int) Param::Get("ID", 0);
|
||||
$atabel = [ 'ID'=>$id, 'InvID'=>$this->id_inv, 'SatuanID'=>$this->id_satuan, 'VarianID'=>$this->id_varian, 'Kode_SKU'=>"", 'Kode_Barcode'=>"", 'Nama_Lengkap'=>"", 'Satuan_Kemasan'=>"", 'Qty'=>0, 'Harga_Beli'=>0 ];
|
||||
if ($id > 0) {
|
||||
$_row = $this->db->fetchRow("SELECT ID,Qty,Harga_Beli FROM tmp_inv_detail WHERE No_Ref=? AND ID=?", [$this->no_mutasi, $id]);
|
||||
if ($_row) $atabel = array_merge($atabel, $_row->getData());
|
||||
}
|
||||
if ($this->id_inv > 0 && $this->id_satuan > 0) {
|
||||
$_row = $this->db->fetchRow("SELECT Kode_SKU,Kode_Barcode,Nama_Lengkap,Satuan_Kemasan,Harga_Pokok Harga_Beli FROM inv_produk_join WHERE InvID=? AND SatuanID=? AND VarianID=?", [$this->id_inv, $this->id_satuan, $this->id_varian]);
|
||||
if ($_row) $atabel = array_merge($atabel, $_row->getData());
|
||||
}
|
||||
|
||||
$form = new Form($this->app);
|
||||
$tsku = $form->textbox("_", "Kode_SKU", $atabel['Kode_SKU']. " / " .$atabel['Kode_Barcode'], false);
|
||||
$tnama = $form->textbox("_", "Nama_Lengkap", $atabel['Nama_Lengkap'], false);
|
||||
$tqty = $form->textbox("_", "Qty", $atabel['Qty'], true, true, "double");
|
||||
$tbeli = $form->textbox("_", "Harga_Beli", $atabel['Harga_Beli'], false, false, "double");
|
||||
$ttot = $form->textbox("_", "Jumlah", 0, false, false, "double");
|
||||
$tsat = $form->textbox("_", "Nama_Satuan", $atabel['Satuan_Kemasan'], false);
|
||||
$ajson['html'] = '
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label">Kode SKU / Barcode</label>
|
||||
<div class="col">'.$tsku.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label">Nama Barang</label>
|
||||
<div class="col">'.$tnama.'</div>
|
||||
</div>
|
||||
<div class="row mb-1"><hr class="my-1"></div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label" for="Qty">Qty</label>
|
||||
<div class="col-sm-4 col-lg-5"><div class="input-group">'.$tqty.$tsat.'</div></div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label">Harga (@)</label>
|
||||
<div class="col-sm-8 col-lg-5">'.$tbeli.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label">Sub Total</label>
|
||||
<div class="col-sm-8 col-lg-5">'.$ttot.'</div>
|
||||
</div>
|
||||
<input type="hidden" id="ID" value="'.$atabel['ID'].'" >
|
||||
<input type="hidden" id="InvID" value="'.$atabel['InvID'].'" >
|
||||
<input type="hidden" id="SatuanID" value="'.$atabel['SatuanID'].'" >
|
||||
<input type="hidden" id="VarianID" value="'.$atabel['VarianID'].'" >
|
||||
<input type="hidden" id="mode_detail" value="'.$this->mode_detail.'" >';
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function proses_delete() {
|
||||
$this->db->runQuery("DELETE FROM inv_mutasi WHERE No_Mutasi=?", [$this->no_mutasi]);
|
||||
$this->db->runQuery("DELETE FROM inv_detail WHERE No_Ref=?", [$this->no_mutasi]);
|
||||
$this->app->json([ 'status' => true ]);
|
||||
}
|
||||
|
||||
public function index() {
|
||||
$this->app->json(['html' => '
|
||||
<div class="fade-in">
|
||||
<div class="card"><div class="card-body">
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="tx-tab" data-bs-toggle="tab" data-bs-target="#tx" type="button" role="tab" aria-controls="tx" aria-selected="true"><i class="bi-database me-2"></i>Transaksi Mutasi Stok Cabang</button>
|
||||
</li>
|
||||
<li class="nav-item ms-auto">
|
||||
<button class="btn btn-primary mb-1 ms-2" id="butTambah" type="button"><i class="bi-plus-lg me-2"></i>Tambah</button>
|
||||
<button class="btn btn-info mb-1 ms-2" id="butUbah" type="button"><i class="bi-clipboard me-2"></i>Ubah</button>
|
||||
<button class="btn btn-warning mb-1 ms-2" id="butHapus" type="button"><i class="bi-trash me-2"></i>Hapus</button>
|
||||
<button class="btn btn-secondary mb-1 ms-2 dropdown-toggle" id="butPrint" type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="bi-printer me-2"></i>Cetak</button>
|
||||
<div class="dropdown-menu" aria-labelledby="butPrint">
|
||||
<a class="dropdown-item" href="#" id="printNota">Cetak Nota</a>
|
||||
<a class="dropdown-item" href="#" id="printPOS">Cetak POS</a>
|
||||
</div>
|
||||
<button class="btn btn-danger mb-1 ms-2" id="butBatal" type="button"><i class="bi-x-lg me-2"></i>Batal</button>
|
||||
<button class="btn btn-success mb-1 ms-2" id="butSimpan" type="button"><i class="bi-save me-2"></i>Simpan</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content border border-top-0 p-3">
|
||||
<div class="tab-pane fade active show" id="tx" role="tabpanel" aria-labelledby="tx-tab">
|
||||
<div id="divTXMaster"> </div>
|
||||
<div id="divDetailTabel"> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
</div>'
|
||||
]);
|
||||
}
|
||||
|
||||
private function Data_Mutasi(string $nomor="", bool $baru=false): array {
|
||||
$aparam = [
|
||||
'No_Mutasi' => $nomor,
|
||||
'Tgl_Mutasi' => tgl_ymd(),
|
||||
'Dari_CabID' => $this->id_cab_dari,
|
||||
'Ke_CabID' => $this->id_cab_ke,
|
||||
'Catatan' => ""
|
||||
];
|
||||
if ($baru) $aparam['No_Mutasi'] = "MUTA".$this->web_app['SERVER_ID'].(string) $this->id_cab_dari.$this->app->user()->id(3)."#00";
|
||||
if (!empty($nomor)) {
|
||||
$row = $this->db->fetchRow("SELECT * FROM inv_mutasi WHERE No_Mutasi=?", [$nomor]);
|
||||
if ($row) $aparam = array_merge($aparam, $row->getData());
|
||||
}
|
||||
return $aparam;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,376 @@
|
||||
<?php
|
||||
|
||||
/*******************************************************************
|
||||
|
||||
PHP Class : /Controller/Inv/OpnameController
|
||||
Description : Transaksi Opname Stok
|
||||
Created By : Siau Pheng (siaupheng@3fonia.com).
|
||||
Created Date : May 24th, 2010.
|
||||
Last Modified : September 28th, 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 OpnameController {
|
||||
|
||||
private array $web_app;
|
||||
private array $app_gel;
|
||||
private int $id_cab;
|
||||
private string $mode;
|
||||
private string $mode_detail;
|
||||
private string $no_opname;
|
||||
private bool $is_baru;
|
||||
private int $id_inv;
|
||||
private int $id_satuan;
|
||||
private int $id_varian;
|
||||
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->web_app = (array) $session->get('WEB_APP');
|
||||
$this->app_gel = (array) $session->get('APP_GEL');
|
||||
$this->id_cab = Param::Int("CabID", $session->get('APP_INV')['CABANGID']);
|
||||
$this->mode = Param::Get("mode", "");
|
||||
$this->mode_detail = Param::Get("mode_detail", "");
|
||||
$this->no_opname = Param::Get("No_Opname", "");
|
||||
$this->is_baru = str_contains($this->no_opname, "OPNA") === true;
|
||||
$this->id_inv = Param::Int("InvID", 0);
|
||||
$this->id_satuan = Param::Int("SatuanID", 0);
|
||||
$this->id_varian = Param::Int("VarianID", 0);
|
||||
$this->inv = new Inv($app);
|
||||
$this->gel = new Gel($app);
|
||||
}
|
||||
|
||||
public function table_detail() {
|
||||
if (in_array($this->mode_detail, ["insert","update","delete"])) {
|
||||
$iqty = Param::Float("Qty", 0);
|
||||
|
||||
$sql = new SQL($this->app);
|
||||
$sql->set_table("tmp_inv_detail");
|
||||
$sql->add_param("No_Ref", $this->no_opname);
|
||||
$sql->add_param("InvID");
|
||||
$sql->add_param("SatuanID");
|
||||
$sql->add_param("VarianID");
|
||||
$sql->add_param("Qty", $iqty);
|
||||
$sql->add_param("Harga_Beli");
|
||||
$sql->add_param("Harga_Jual", "Harga_Beli", true);
|
||||
$sql->add_param_unix();
|
||||
$sql->add_param_userid();
|
||||
$sql->add_where("ID");
|
||||
$sql->add_where("No_Ref", $this->no_opname);
|
||||
|
||||
if ( $this->mode_detail === "insert" ) {
|
||||
$sql->InsertDB();
|
||||
} else if ( $this->mode_detail === "update" ) {
|
||||
$sql->UpdateDB();
|
||||
} else if ( $this->mode_detail === "delete" ) {
|
||||
$sql->DeleteDB();
|
||||
}
|
||||
}
|
||||
|
||||
$tsql = ''; $asql = [$this->no_opname]; $qtabel = "inv_detail";
|
||||
if (in_array($this->mode, ["add","edit"])) {
|
||||
if ($this->mode === "add") { $tsql = " AND Unix=?"; array_push($asql, $this->app->user()->unix()); }
|
||||
$qtabel = "tmp_inv_detail";
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("(SELECT *,(Qty*Harga_Beli) Total FROM ".$qtabel." WHERE No_Ref=?".$tsql.") D LEFT JOIN vi_inv_produk P ON (D.InvID=P.InvID AND D.SatuanID=P.SatuanID AND D.VarianID=P.VarianID)", "D.*,P.Kode_SKU,P.Nama_Lengkap", "", $asql);
|
||||
$obj->set_footer("SUM(D.Total) Total");
|
||||
$obj->add_field("ID", "No", "c");
|
||||
$obj->add_field("InvID", "InvID", "hid");
|
||||
$obj->add_field("SatuanID", "SatuanID", "hid");
|
||||
$obj->add_field("VarianID", "VarianID", "hid");
|
||||
$obj->add_field("Kode_SKU", "SKU", "c");
|
||||
$obj->add_field("Nama_Lengkap", "Nama Barang", "awr");
|
||||
$obj->add_field("Qty", "Qty", "r", "rupiah2");
|
||||
$obj->add_field("Harga_Beli", "Harga @", "r", "rupiah");
|
||||
$obj->add_field("Total", "Jumlah", "r", "rupiah", "rupiah");
|
||||
$obj->set_field_order("ID", "D");
|
||||
if (in_array($this->mode, ["add","edit"])) {
|
||||
$obj->add_row_btn("clipboard", "Ubah", "OpnameJS.detail_ubah");
|
||||
$obj->add_row_btn("trash", "Hapus", "OpnameJS.detail_hapus", "Unix", $this->app->user()->unix());
|
||||
$obj->set_func_btn("OpnameJS.detail_tambah", '<i class="bi-plus-lg me-1"></i> Barang');
|
||||
$obj->set_func_btn("OpnameJS.produk_brow", '<i class="bi-table me-1"></i> Browse');
|
||||
}
|
||||
$ajson[] = $obj->json_table("divDetailTabel");
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function brow_tx() {
|
||||
$tcari = Param::Get("Cari_TX");
|
||||
$tsql = ''; $asql = [];
|
||||
if (!empty($tcari)) {
|
||||
$tsql .= " WHERE CONCAT(No_Opname,DATE_FORMAT(Tgl_Opname,'%d-%m-%Y')) LIKE ?";
|
||||
array_push($asql, '%' . $tcari . '%');
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("(SELECT * FROM inv_opname".$tsql.") O LEFT JOIN para_cabang C ON (C.CabID=O.CabID)", "O.*,C.Kode_Cab", "", $asql);
|
||||
$obj->add_field("No_Opname", "No. Trans", "c");
|
||||
$obj->add_field("Tgl_Opname", "Tgl. Trans", "c", "sqltgl", "", "val-tgl");
|
||||
$obj->add_field("Kode_Cab", "Cabang", "c");
|
||||
$obj->add_field("Total_Opname", "Total", "r", "rupiah2");
|
||||
$obj->add_field("Catatan", "Catatan", "awr");
|
||||
$obj->set_field_order("No_Opname", "D");
|
||||
$obj->set_func_select("OpnameJS.tx_select");
|
||||
$this->app->json([ $obj->db_table("divBrowTX") ]);
|
||||
}
|
||||
|
||||
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("Sisa_Stok", "Stok", "r", "rupiah2");
|
||||
$obj->set_field_order("Kode_SKU", "A");
|
||||
$obj->set_func_select("OpnameJS.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 : Harga_Pokok : Satuan : Stok
|
||||
if ($bcode === 0) {
|
||||
$_row = $this->db->fetchRow("SELECT P.InvID,P.Nama_Lengkap,CONCAT(P.SatuanID,':',P.VarianID,':',CONVERT(FORMAT(P.Harga_Pokok,2) USING UTF8),':',P.Satuan_Kemasan,':',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,':',CONVERT(FORMAT(P.Harga_Pokok,2) USING UTF8),':',P.Satuan_Kemasan,':',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 form_master() {
|
||||
$ajson = [ 'error'=>"", 'html'=>"" ];
|
||||
$atabel = [];
|
||||
|
||||
if ($this->mode === "add") {
|
||||
$atabel = $this->Data_Opname("", true);
|
||||
} else if ($this->mode === "edit") {
|
||||
$this->inv->Detail_Copy($this->no_opname, true);
|
||||
$atabel = $this->Data_Opname($this->no_opname);
|
||||
} else if ($this->mode === "save") {
|
||||
$no_lama = $this->no_opname;
|
||||
if ($this->is_baru) {
|
||||
$this->no_opname = $this->inv->Nomor_Baru("O", Param::Get("Tgl_Opname"), true);
|
||||
}
|
||||
$this->inv->Detail_Save($this->no_opname, 1, $this->id_cab, Param::Get("Tgl_Opname"), $this->is_baru, $no_lama);
|
||||
|
||||
$tot_opname = $this->db->fetchField("SELECT SUM(Qty*Harga_Beli) Opname FROM inv_detail WHERE No_Ref=?", [$this->no_opname]) ?? 0;
|
||||
|
||||
$sql = new SQL($this->app);
|
||||
$sql->set_table("inv_opname");
|
||||
$sql->add_param_date("Tgl_Opname");
|
||||
$sql->add_param("CabID");
|
||||
$sql->add_param("Total_Opname", $tot_opname);
|
||||
$sql->add_param("Catatan");
|
||||
$sql->add_param_stamp();
|
||||
$sql->add_param_userid();
|
||||
$sql->add_where("No_Opname", $this->no_opname);
|
||||
$sql->UpdateDB();
|
||||
|
||||
// PROSES POSTING GL
|
||||
$ainfo = $this->db->fetchRow("SELECT * FROM inv_opname WHERE No_Opname=?", [$this->no_opname]);
|
||||
if (count($ainfo) > 0) {
|
||||
$ajurnal = [
|
||||
'Kode_Jurnal' => $ainfo['No_Opname'],
|
||||
'TipeID' => 12,
|
||||
'CabID' => $ainfo['CabID'],
|
||||
'Tanggal' => tgl_sql2str($ainfo['Tgl_Opname']),
|
||||
'Kode_Ref' => $ainfo['No_Opname'],
|
||||
'Catatan' => "Opname Stok / Penyesuaian : ".$ainfo['No_Opname']." - ".tgl_sql2str($ainfo['Tgl_Opname'])
|
||||
];
|
||||
$_dkD = ($ainfo['Total_Opname'] > 0) ? "K" : "D";
|
||||
$_dkK = ($ainfo['Total_Opname'] < 0) ? "K" : "D";
|
||||
$adetail = [
|
||||
[ 'Kode_Rek' => $this->app_gel['HPP'], 'DK' => $_dkD, 'Jumlah' => $ainfo['Total_Opname'] ],
|
||||
[ 'Kode_Rek' => $this->app_gel['STOK'], 'DK' => $_dkK, 'Jumlah' => $ainfo['Total_Opname'] ]
|
||||
];
|
||||
$this->gel->Jurnal_Post($ajurnal, $adetail);
|
||||
}
|
||||
$atabel = $this->Data_Opname($this->no_opname);
|
||||
$this->mode = "view";
|
||||
|
||||
} else if ($this->mode === "cancel") {
|
||||
$this->inv->Detail_Cancel($this->no_opname);
|
||||
$atabel = $this->Data_Opname();
|
||||
} else {
|
||||
$atabel = $this->Data_Opname($this->no_opname);
|
||||
}
|
||||
|
||||
$enable = in_array($this->mode, ["add","edit"]) ? true : false;
|
||||
$form = new Form($this->app);
|
||||
$tnota = $form->textbox("_", "No_Opname", $atabel['No_Opname'], !$enable, true, "text", "nomor transaksi");
|
||||
$ttglnota = $form->datebox("_", "Tgl_Opname", $atabel['Tgl_Opname'], $enable, true);
|
||||
$tcab = $form->option_db("_", "CabID", $atabel['CabID'], $enable, false, "para_cabang", ["CabID","Nama_Cab"], "Aktif=1 ORDER BY Nama_Cab", [0," "]);
|
||||
$tcatat = $form->textbox("_", "Catatan", $atabel['Catatan'], $enable, true, "text", "catatan");
|
||||
$ajson['html'] = '
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-lg-6">
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="No_Opname">Nomor Transaksi</label>
|
||||
<div class="col"><div class="input-group">'.$tnota.'<button id="butBrow" class="btn btn-info" type="button"><i class="bi-search"></i></button></div></div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="Tgl_Opname">Tanggal Transaksi</label>
|
||||
<div class="col-sm-7 col-lg-5">'.$ttglnota.'</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-lg-6">
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="CabID">Nama Cabang</label>
|
||||
<div class="col">'.$tcab.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-5 col-lg-3 col-form-label" for="Catatan">Catatan</label>
|
||||
<div class="col">'.$tcatat.'</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1"><div class="col"><hr class="my-1"></div></div>
|
||||
<input type="hidden" id="mode" value="'.$this->mode.'" >';
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function form_produk() {
|
||||
$id = (int) Param::Get("ID", 0);
|
||||
$atabel = [ 'ID'=>$id, 'InvID'=>$this->id_inv, 'SatuanID'=>$this->id_satuan, 'VarianID'=>$this->id_varian, 'Nama_Lengkap'=>"", 'Nama_Satuan'=>"", 'Qty'=>0, 'Stok'=>0, 'Harga_Beli'=>0, 'Kali'=>1 ];
|
||||
if ($id > 0) {
|
||||
$_row = $this->db->fetchRow("SELECT ID,Qty,Harga_Beli FROM tmp_inv_detail WHERE No_Ref=? AND ID=?", [$this->no_opname, $id]);
|
||||
if ($_row) $atabel = array_merge($atabel, $_row->getData());
|
||||
}
|
||||
if ((int) $atabel['InvID'] > 0 && (int) $atabel['SatuanID'] > 0) {
|
||||
$_row = $this->db->fetchRow("SELECT Nama_Lengkap,Nama_Satuan,Harga_Pokok Harga_Beli,Qty Kali FROM vi_inv_produk WHERE InvID=? AND SatuanID=? AND VarianID=?", [$atabel['InvID'], $atabel['SatuanID'], $atabel['VarianID']]);
|
||||
if ($_row) $atabel = array_merge($atabel, $_row->getData());
|
||||
$_stok = $this->db->fetchField("SELECT Stok FROM inv_stok WHERE CabID=? AND InvID=?", [$this->id_cab, $atabel['InvID']]) ?? 1;
|
||||
$atabel['Stok'] = $_stok / ($atabel['Kali'] ?? 1);
|
||||
}
|
||||
|
||||
$form = new Form($this->app);
|
||||
$tnama = $form->textauto("_", "Nama_Produk", ['value'=>$atabel['InvID'],'text'=>$atabel['Nama_Lengkap']], true, true, "ketik nama produk");
|
||||
$tqty = $form->textbox("_", "Qty", $atabel['Qty'], true, true, "double");
|
||||
$tstok = $form->textbox("_", "Stok", $atabel['Stok'], false, false, "double");
|
||||
$tbeli = $form->textbox("_", "Harga_Beli", $atabel['Harga_Beli'], false, false, "double");
|
||||
$tsat1 = $form->textbox("_", "Nama_Satuan1", $atabel['Nama_Satuan'], false);
|
||||
$tsat2 = $form->textbox("_", "Nama_Satuan2", $atabel['Nama_Satuan'], false);
|
||||
$ajson['html'] = '
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label" for="Nama_Produk">Nama Barang</label>
|
||||
<div class="col">'.$tnama.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label">HPP (@)</label>
|
||||
<div class="col-sm-8 col-lg-5">'.$tbeli.'</div>
|
||||
</div>
|
||||
<div class="row mb-1"><hr class="my-1"></div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label" for="Qty">Penyesuaian</label>
|
||||
<div class="col-sm-8 col-lg-5"><div class="input-group">'.$tqty.$tsat1.'</div></div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label">Stok Sistem</label>
|
||||
<div class="col-sm-8 col-lg-5"><div class="input-group">'.$tstok.$tsat2.'</div></div>
|
||||
</div>
|
||||
<input type="hidden" id="ID" value="'.$atabel['ID'].'" >
|
||||
<input type="hidden" id="InvID" value="'.$atabel['InvID'].'" >
|
||||
<input type="hidden" id="SatuanID" value="'.$atabel['SatuanID'].'" >
|
||||
<input type="hidden" id="VarianID" value="'.$atabel['VarianID'].'" >
|
||||
<input type="hidden" id="mode_detail" value="'.$this->mode_detail.'" >';
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function proses_delete() {
|
||||
$this->db->runQuery("DELETE FROM inv_opname WHERE No_Opname=?", [$this->no_opname]);
|
||||
$this->db->runQuery("DELETE FROM inv_detail WHERE No_Ref=?", [$this->no_opname]);
|
||||
// PROSES POSTING GL
|
||||
$this->db->runQuery("DELETE FROM gel_jurnal WHERE Kode_Jurnal=?", [$this->no_opname]);
|
||||
$this->db->runQuery("DELETE FROM gel_jurnal_detail WHERE Kode_Jurnal=?", [$this->no_opname]);
|
||||
$this->app->json([ 'status' => true ]);
|
||||
}
|
||||
|
||||
public function index() {
|
||||
$this->app->json(['html' => '
|
||||
<div class="fade-in">
|
||||
<div class="card"><div class="card-body">
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="tx-tab" data-bs-toggle="tab" data-bs-target="#tx" type="button" role="tab" aria-controls="tx" aria-selected="true"><i class="bi-database me-2"></i>Transaksi Penyesuaian Stok</button>
|
||||
</li>
|
||||
<li class="nav-item ms-auto">
|
||||
<button class="btn btn-primary mb-1 ms-2" id="butTambah" type="button"><i class="bi-plus-lg me-2"></i>Tambah</button>
|
||||
<button class="btn btn-info mb-1 ms-2" id="butUbah" type="button"><i class="bi-clipboard me-2"></i>Ubah</button>
|
||||
<button class="btn btn-warning mb-1 ms-2" id="butHapus" type="button"><i class="bi-trash me-2"></i>Hapus</button>
|
||||
<button class="btn btn-secondary mb-1 ms-2" id="butPrint" type="button"><i class="bi-printer me-2"></i>Cetak</button>
|
||||
<button class="btn btn-danger mb-1 ms-2" id="butBatal" type="button"><i class="bi-x-lg me-2"></i>Batal</button>
|
||||
<button class="btn btn-success mb-1 ms-2" id="butSimpan" type="button"><i class="bi-save me-2"></i>Simpan</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content border border-top-0 p-3">
|
||||
<div class="tab-pane fade active show" id="tx" role="tabpanel" aria-labelledby="tx-tab">
|
||||
<div id="divTXMaster"> </div>
|
||||
<div id="divDetailTabel"> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
</div>'
|
||||
]);
|
||||
}
|
||||
|
||||
private function Data_Opname(string $nomor="", bool $baru=false): array {
|
||||
$aparam = [ 'No_Opname'=>$nomor, 'Catatan'=>"" ];
|
||||
if (empty($nomor)) {
|
||||
if ($baru) $aparam['No_Opname'] = "OPNA".$this->web_app['SERVER_ID'].(string) $this->id_cab.$this->app->user()->id(3)."#00";
|
||||
$aparam['Tgl_Opname'] = tgl_ymd();
|
||||
$aparam['CabID'] = $this->id_cab;
|
||||
} else {
|
||||
$row = $this->db->fetchRow("SELECT * FROM inv_opname WHERE No_Opname=?", [$nomor]);
|
||||
if ($row) $aparam = array_merge($aparam, $row->getData());
|
||||
}
|
||||
return $aparam;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
|
||||
/*******************************************************************
|
||||
|
||||
PHP Class : /Controller/Inv/OpnamebarangController
|
||||
Description : Transaksi Penyesuaian Stok Per Barang
|
||||
Created By : Siau Pheng (siaupheng@3fonia.com).
|
||||
Created Date : October 22nd, 2014.
|
||||
Last Modified : October 11th, 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 = ['Nama_Supplier'=>"BELUM ADA"];
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,645 @@
|
||||
<?php
|
||||
|
||||
/*******************************************************************
|
||||
|
||||
PHP Class : /Controller/Inv/PosController
|
||||
Description : Transaksi Penjualan POS
|
||||
Created By : Siau Pheng (siaupheng@3fonia.com).
|
||||
Created Date : August 5th, 2012.
|
||||
Last Modified : September 27th, 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 PosController {
|
||||
|
||||
private array $web_app;
|
||||
private array $app_gel;
|
||||
private array $app_inv;
|
||||
private int $id_cab;
|
||||
private int $id_member_def;
|
||||
private int $id_member;
|
||||
private int $id_grup_member;
|
||||
private string $mode;
|
||||
private string $mode_detail;
|
||||
private string $no_jual;
|
||||
private bool $is_pend;
|
||||
private int $id_inv;
|
||||
private int $id_satuan;
|
||||
private int $id_varian;
|
||||
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->web_app = (array) $session->get('WEB_APP');
|
||||
$this->app_gel = (array) $session->get('APP_GEL');
|
||||
$this->app_inv = (array) $session->get('APP_INV');
|
||||
$this->id_cab = $session->get('APP_INV')['CABANGID'];
|
||||
$this->id_member_def = $session->get('APP_INV')['MEMBERID'];
|
||||
$this->id_member = Param::Int("MemberID", $this->id_member_def);
|
||||
$this->id_grup_member = Param::Int("Grup_MemberID", $session->get('APP_INV')['ECERANID']);
|
||||
$this->mode = Param::Get("mode", "");
|
||||
$this->mode_detail = Param::Get("mode_detail", "");
|
||||
$this->no_jual = Param::Get("No_Jual", "");
|
||||
$this->is_pend = str_contains($this->no_jual, "POS") === true;
|
||||
$this->id_inv = Param::Int("InvID", 0);
|
||||
$this->id_satuan = Param::Int("SatuanID", 0);
|
||||
$this->id_varian = Param::Int("VarianID", 0);
|
||||
$this->inv = new Inv($app);
|
||||
$this->gel = new Gel($app);
|
||||
}
|
||||
|
||||
public function table_detail() {
|
||||
if ( in_array($this->mode_detail, ["insert","update"]) ) {
|
||||
$iqty = Param::Float("Qty", 0) * -1;
|
||||
$disk_rp = Param::Float("Disk_Rupiah", 0);
|
||||
$disk_psn = Param::Float("Disk_Persen", 0);
|
||||
if ($disk_psn > 0) $disk_rp = Param::Float("Harga_Jual", 0) * $disk_psn * 0.01;
|
||||
|
||||
$sql = new SQL($this->app);
|
||||
$sql->set_table("tmp_inv_detail");
|
||||
$sql->add_param("No_Ref", $this->no_jual);
|
||||
$sql->add_param("InvID");
|
||||
$sql->add_param("SatuanID");
|
||||
$sql->add_param("VarianID");
|
||||
$sql->add_param("Qty", $iqty);
|
||||
$sql->add_param("Harga_Beli");
|
||||
$sql->add_param("Harga_Jual");
|
||||
$sql->add_param("Disk_Rupiah", $disk_rp);
|
||||
$sql->add_param("Total_Diskon", "Disk_Rupiah*-Qty", true);
|
||||
$sql->add_param_unix();
|
||||
$sql->add_param_userid();
|
||||
$sql->add_where("ID");
|
||||
$sql->add_where("No_Ref", $this->no_jual);
|
||||
|
||||
if ( $this->mode_detail === "insert" ) {
|
||||
$sql->InsertDB();
|
||||
} else if ( $this->mode_detail === "update" ) {
|
||||
$sql->UpdateDB();
|
||||
}
|
||||
} else if ( $this->mode_detail === "delete" ) {
|
||||
$this->db->runQuery("UPDATE tmp_inv_detail SET Qty=0,Stok=0,Disk_Rupiah=0,Total_Diskon=0 WHERE No_Ref=? AND ID=?", [$this->no_jual, Param::Int("ID", 0)]);
|
||||
}
|
||||
|
||||
$asql = [$this->no_jual, $this->app->user()->unix()];
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_css("tabel-pos");
|
||||
$obj->set_table("(SELECT * FROM tmp_inv_detail WHERE No_Ref=? AND Unix=? AND Promo<2) D LEFT JOIN vi_inv_produk P ON (D.InvID=P.InvID AND D.SatuanID=P.SatuanID AND D.VarianID=P.VarianID)", "D.*,-D.Qty Qty2,P.Kode_SKU,P.Nama_Lengkap,-D.Qty*(D.Harga_Jual-D.Disk_Rupiah) Total,IF(D.Qty=0,0,1) IDEL", "", $asql);
|
||||
$obj->set_footer("CONCAT('Q: ',FORMAT(SUM(-D.Qty),2),' / I: ',FORMAT(COUNT(DISTINCT D.InvID),0)) Harga_Jual,SUM(-D.Qty*D.Disk_Rupiah) Disk_Rupiah,SUM(-D.Qty*(D.Harga_Jual-D.Disk_Rupiah)) Total");
|
||||
$obj->add_field("ID", "No", "c");
|
||||
$obj->add_field("InvID", "InvID", "hid");
|
||||
$obj->add_field("SatuanID", "SatuanID", "hid");
|
||||
$obj->add_field("VarianID", "VarianID", "hid");
|
||||
$obj->add_field("Kode_SKU", "SKU", "c");
|
||||
$obj->add_field("Nama_Lengkap", "Nama Barang", "awr");
|
||||
$obj->add_field("Qty2", "Qty", "r", "rupiah2");
|
||||
$obj->add_field("Harga_Jual", "Harga @", "r", "rupiah");
|
||||
$obj->add_field("Disk_Rupiah", "Diskon @", "r", "rupiah", "rupiah");
|
||||
$obj->add_field("Total", "Jumlah", "r", "rupiah", "rupiah");
|
||||
$obj->add_field("Promo", "S", "c", [0=>"N",1=>"T",2=>"D",3=>"P",4=>"H"]);
|
||||
$obj->set_field_order("ID", "D");
|
||||
$obj->set_row_color("IDEL", "0", "rcoret");
|
||||
$obj->add_row_btn("clipboard", "Ubah", "POSJS.detail_ubah");
|
||||
$obj->add_row_btn("trash", "Hapus", "POSJS.detail_hapus", "IDEL", "1");
|
||||
$ajson[] = $obj->json_table("divPOS1", 8);
|
||||
|
||||
$ainfo = ['Total'=>0, 'Item'=>0];
|
||||
$_info = $this->db->fetchRow("SELECT SUM(-Qty*(Harga_Jual-Disk_Rupiah)) Total,COUNT(*) Item FROM tmp_inv_detail WHERE No_Ref=? AND Unix=? AND Promo<2", $asql);
|
||||
if ($_info) $ainfo = $_info->getData();
|
||||
$ajson[] = ['type'=>"form", 'id'=>"Total_Nota", 'value'=>$ainfo['Total']];
|
||||
$ajson[] = ['type'=>"form", 'id'=>"Total_Item", 'value'=>$ainfo['Item']];
|
||||
if ($ainfo['Item'] > 0) $ajson[] = ['type'=>"html", 'id'=>"Total_Disp", 'value'=>rupiah($ainfo['Total'])];
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function brow_nota() {
|
||||
$tcari = Param::Get("Cari_Nota");
|
||||
$tsql = ''; $asql = [$this->id_cab];
|
||||
if (empty($tcari)) {
|
||||
$tsql .= " AND UserID=? AND Tgl_Jual=?";
|
||||
array_push($asql, $this->app->user()->id(), tgl_ymd());
|
||||
} else {
|
||||
$tsql .= " AND CONCAT(No_Jual,DATE_FORMAT(Tgl_Jual,'%d-%m-%Y')) LIKE ?";
|
||||
array_push($asql, '%' . $tcari . '%');
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("(SELECT * FROM inv_jual WHERE POS=1 AND CabID=?".$tsql.") J LEFT JOIN para_rek_pos P ON (J.KartuID=P.KartuID) LEFT JOIN para_member M ON (J.MemberID=M.MemberID)", "J.*,DATE_FORMAT(J.DateStamp,'%H:%i:%s') Tgl_Jual2,J.Total_Jual-J.Total_Diskon Total,IFNULL(M.Nama_Member,'') Nama_Member,IF(ISNULL(P.Kode_Kartu),'Tunai',P.Kode_Kartu) Kartu", "", $asql);
|
||||
$obj->set_footer("SUM(Total_Jual) Total_Jual,SUM(Total_Diskon) Total_Diskon,SUM(Total_Jual-Total_Diskon) Total");
|
||||
$obj->add_field("No_Jual", "No. Nota", "c");
|
||||
$obj->add_field("Tgl_Jual", "Tanggal", "c", "sqltgl", "", "val-tgl");
|
||||
$obj->add_field("Tgl_Jual2", "Jam", "c");
|
||||
$obj->add_field("Nama_Member", "Member", "awr");
|
||||
$obj->add_field("Total_Jual", "Sub. Total", "r", "rupiah2", "rupiah2");
|
||||
$obj->add_field("Total_Diskon", "Diskon", "r", "rupiah2", "rupiah2");
|
||||
$obj->add_field("Total", "Jumlah", "r", "rupiah2", "rupiah2");
|
||||
$obj->add_field("Kartu", "C / D", "l");
|
||||
if (empty($tcari)) {
|
||||
$obj->set_field_order("Tgl_Jual2", "D");
|
||||
} else {
|
||||
$obj->set_field_order("Tgl_Jual", "D");
|
||||
}
|
||||
$obj->add_row_btn("printer", "Cetak", "POSJS.nota_print");
|
||||
$obj->add_row_btn("clipboard", "Ubah", "POSJS.nota_select");
|
||||
if ($this->app->user()->is_level(1)) $obj->add_row_btn("trash", "Hapus", "POSJS.nota_delete", "CabID", $this->id_cab);
|
||||
else $obj->add_row_btn("trash", "Hapus", "POSJS.nota_delete", "UserID", $this->app->user()->id());
|
||||
$this->app->json([ $obj->db_table("divBrowNota") ]);
|
||||
}
|
||||
|
||||
public function brow_pending() {
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("(SELECT *,Total_Jual-Total_Diskon Jumlah FROM inv_jual_pend WHERE POS=1 AND CabID=? AND UserID=?) J LEFT JOIN para_member B ON (J.MemberID=B.MemberID)", "J.*,B.Nama_Member", "", [$this->id_cab, $this->app->user()->id()]);
|
||||
$obj->add_field("No_Jual", "No. Nota", "c");
|
||||
$obj->add_field("Tgl_Jual", "Tgl. Pending", "c", "sqltgl", "", "val-tgl");
|
||||
$obj->add_field("Nama_Member", "Nama Member", "awr");
|
||||
$obj->add_field("Total_Jual", "Sub. Total", "r", "rupiah2");
|
||||
$obj->add_field("Total_Diskon", "Diskon", "r", "rupiah2");
|
||||
$obj->add_field("Jumlah", "Jumlah", "r", "rupiah2");
|
||||
$obj->set_field_order("No_Jual", "D");
|
||||
$obj->add_row_btn("save", "Pilih", "POSJS.pending_select");
|
||||
if ($this->app->user()->is_level(1)) $obj->add_row_btn("trash", "Hapus", "POSJS.pending_delete", "UserID", $this->app->user()->id());
|
||||
$this->app->json([ $obj->db_table("divBrowPending") ]);
|
||||
}
|
||||
|
||||
public function brow_member() {
|
||||
$tcari = Param::Get("Cari_Member");
|
||||
$tsql = ''; $asql = [1];
|
||||
if (!empty($tcari)) {
|
||||
$tsql .= " AND CONCAT_WS(Kode_Member,Nama_Member,Alamat_Member,Telp_Member) LIKE ?";
|
||||
$asql[] = '%' . $tcari . '%';
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("para_member", "*,TRIM(CONCAT(Kode_Member,'\n',Kota_Member)) Info_Member", "Aktif=?".$tsql, $asql);
|
||||
$obj->add_field("MemberID", "ID", "hid");
|
||||
$obj->add_field("Grup_MemberID", "Grup ID", "hid");
|
||||
$obj->add_field("Kode_Member", "Kode", "c");
|
||||
$obj->add_field("Nama_Member", "Nama Member", "awr");
|
||||
$obj->add_field("Alamat_Member", "Alamat", "awr");
|
||||
$obj->add_field("Telp_Member", "Telp.", "awr");
|
||||
$obj->add_field("Info_Member", "Info", "hid");
|
||||
$obj->set_field_order("Nama_Member", "A");
|
||||
$obj->set_func_select("POSJS.member_select");
|
||||
$this->app->json([ $obj->db_table("divBrowMember") ]);
|
||||
}
|
||||
|
||||
public function brow_produk() {
|
||||
$tcari = Param::Get("Cari_Produk");
|
||||
$tsql = ''; $asql = [1, $this->id_grup_member];
|
||||
if (!empty($tcari)) {
|
||||
$tsql .= " AND Barcode_Nama LIKE ?";
|
||||
$asql[] = '%' . $tcari . '%';
|
||||
}
|
||||
|
||||
$obj = new Table($this->app);
|
||||
$obj->set_table("inv_produk_join", "*", "Aktif=? AND Grup_MemberID=? AND Harga_Jual>0".$tsql, $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("Harga_Jual", "Harga Jual", "r", "rupiah");
|
||||
$obj->set_field_order("Kode_SKU", "A");
|
||||
$obj->set_func_select("POSJS.produk_select");
|
||||
$this->app->json([ $obj->db_table("divBrowProduk") ]);
|
||||
}
|
||||
|
||||
public function auto_member() {
|
||||
$tcari = Param::Get("Auto_Query", "");
|
||||
$ajson['autodata'] = [];
|
||||
|
||||
$stat = $this->db->runQuery("SELECT MemberID,Grup_MemberID,Kode_Member,Nama_Member,TRIM(CONCAT(Kode_Member,'\n',Kota_Member)) Info_Member FROM para_member WHERE Aktif=1 AND CONCAT(Kode_Member,Nama_Member,Alamat_Member,Telp_Member) LIKE ? ORDER BY Nama_Member LIMIT 50", ['%'.$tcari.'%']);
|
||||
while ($row = $stat->fetch(SimplePdo::FETCH_ASSOC)) {
|
||||
$ajson['autodata'][] = ['value'=>$row['MemberID'], 'text'=>$row['Nama_Member'], 'html'=>'<span class="text-primary">'.$row['Kode_Member'].'</span> '.$row['Nama_Member'], 'data'=>$row['Grup_MemberID'].':'.$row['Info_Member'], 'bc'=>0];
|
||||
}
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function auto_produk() {
|
||||
$tcari = Param::Get("Auto_Query", "");
|
||||
$ajson['autodata'] = [];
|
||||
$bcode = 0; $arec = [];
|
||||
|
||||
if (is_numeric($tcari) && strlen($tcari) === 8) {
|
||||
// Cari by Member
|
||||
// M : Grup_Member : Info_Member
|
||||
$_row = $this->db->fetchRow("SELECT MemberID InvID,Nama_Member Nama_Lengkap,CONCAT('M:',Grup_MemberID,':',TRIM(CONCAT(Kode_Member,'\n',Kota_Member))) Data2 FROM para_member WHERE Aktif=1 AND Kode_Member=?", [$tcari]);
|
||||
if ($_row) {
|
||||
$bcode = 1;
|
||||
$arec = $_row->getData();
|
||||
}
|
||||
}
|
||||
|
||||
// Cari by SKU + Barcode
|
||||
// P : Satuan : Varian : Harga_Pokok : Harga_Jual : Stok
|
||||
if ($bcode === 0) {
|
||||
$_row = $this->db->fetchRow("SELECT P.InvID,P.Nama_Lengkap,CONCAT('P:',P.SatuanID,':',P.VarianID,':',CONVERT(P.Harga_Pokok USING UTF8),':',CONVERT(P.Harga_Jual USING UTF8),':',CONVERT(IFNULL(X.Stok,0) USING UTF8)) Data2 FROM (SELECT * FROM inv_produk_join WHERE Aktif=1 AND Harga_Jual>0 AND Grup_MemberID=? AND (Kode_SKU=? OR Kode_Barcode=?)) P LEFT JOIN inv_stok X ON (X.CabID=? AND X.InvID=P.InvID)", [$this->id_grup_member, $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,P.Harga_Jual,CONCAT('P:',P.SatuanID,':',P.VarianID,':',CONVERT(P.Harga_Pokok USING UTF8),':',CONVERT(P.Harga_Jual USING UTF8),':',CONVERT(IFNULL(X.Stok,0) USING UTF8)) Data2 FROM (SELECT * FROM inv_produk_join WHERE Barcode_Nama LIKE ? AND Aktif=1 AND Harga_Jual>0 AND Grup_MemberID=?) 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_grup_member, $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'].' - <strong>Rp'.rupiah($row['Harga_Jual']).'</strong> <span class="text-danger">('.(string) $row['Sisa_Stok'].')</span>', 'data'=>$row['Data2'], 'bc'=>0];
|
||||
}
|
||||
}
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function form_master() {
|
||||
$ajson = [ 'error'=>"", 'html'=>"" ];
|
||||
$atabel = [];
|
||||
|
||||
if ($this->mode === "pending-edit") {
|
||||
$this->inv->Pending_Edit($this->no_jual);
|
||||
$atabel = $this->Data_Jual($this->no_jual);
|
||||
$this->mode = "edit";
|
||||
} else if ($this->mode === "pending-save") {
|
||||
$b_baru = false;
|
||||
if (str_ends_with($this->no_jual, "#00")) {
|
||||
$b_baru = true;
|
||||
$no_lama = $this->no_jual;
|
||||
$this->no_jual = $this->Pending_Nomor();
|
||||
$this->inv->Pending_Save($no_lama, $this->no_jual);
|
||||
}
|
||||
$apending = $this->db->fetchRow("SELECT SUM(-Qty*Harga_Jual) Jual,SUM(-Qty*Disk_Rupiah) Diskon FROM tmp_inv_detail WHERE No_Ref=?", [$this->no_jual]) ?? ['Jual'=>0, 'Diskon'=>0];
|
||||
|
||||
$sql = new SQL($this->app);
|
||||
$sql->set_table("inv_jual_pend");
|
||||
$sql->add_param("No_Jual", $this->no_jual);
|
||||
$sql->add_param_date("Tgl_Jual");
|
||||
$sql->add_param("CabID", $this->id_cab);
|
||||
$sql->add_param("MemberID");
|
||||
$sql->add_param("Total_Jual", $apending['Jual']);
|
||||
$sql->add_param("Total_Diskon", $apending['Diskon']);
|
||||
$sql->add_param_userid();
|
||||
$sql->add_where("No_Jual", $this->no_jual);
|
||||
if ($b_baru) $sql->InsertDB();
|
||||
else $sql->UpdateDB();
|
||||
$atabel = $this->Data_Jual();
|
||||
} else if ($this->mode === "pending-delete") {
|
||||
$this->inv->Pending_Delete($this->no_jual);
|
||||
$this->db->delete("inv_jual_pend", "No_Jual=?", [$this->no_jual]);
|
||||
$atabel = $this->Data_Jual();
|
||||
} else if ($this->mode === "edit") {
|
||||
$this->inv->Detail_Copy($this->no_jual, true);
|
||||
$atabel = $this->Data_Jual($this->no_jual);
|
||||
} else if ($this->mode === "save") {
|
||||
$no_lama = $this->no_jual;
|
||||
if ($this->is_pend) {
|
||||
$this->no_jual = $this->inv->Nomor_POS("", tgl_dmy(), true);
|
||||
if (!str_ends_with($no_lama, "#00")) $this->db->delete("inv_jual_pend", "No_Jual=?", [$no_lama]);
|
||||
}
|
||||
|
||||
// PROSES PROMO
|
||||
$this->inv->Promo_Barang($no_lama, tgl_dmy(), $this->id_grup_member);
|
||||
$tot_potong = $this->inv->Promo_Total($no_lama, tgl_dmy(), $this->id_grup_member);
|
||||
|
||||
$this->inv->Detail_Save($this->no_jual, 6, $this->id_cab, tgl_dmy(), $this->is_pend, $no_lama);
|
||||
|
||||
$ajual = $this->db->fetchRow("SELECT SUM(-Qty*Harga_Jual) Jual, SUM(-Qty*Disk_Rupiah) Diskon, SUM(-Qty*Harga_Beli) HPP FROM inv_detail WHERE No_Ref=?", [$this->no_jual]) ?? ['Jual'=>0, 'Diskon'=>0, 'HPP'=>0];
|
||||
|
||||
$id_kartu = Param::Int("KartuID", 0);
|
||||
$no_kartu = ""; $nama_kartu = ""; $rek_debit = $this->app_gel['KAS_TUNAI'];
|
||||
if ($id_kartu > 0) {
|
||||
$no_kartu = Param::Get("No_Kartu", "");
|
||||
$nama_kartu = Param::Get("Nama_Kartu", "");
|
||||
$rek_debit = $this->db->fetchField("SELECT Kode_Rek FROM para_rek_pos WHERE KartuID=?", [$id_kartu]) ?? $rek_debit;
|
||||
}
|
||||
|
||||
$sql = new SQL($this->app);
|
||||
$sql->set_table("inv_jual");
|
||||
$sql->add_param("Tgl_Jual", tgl_ymd());
|
||||
$sql->add_param("Tgl_Lunas", tgl_ymd());
|
||||
$sql->add_param("CabID", $this->id_cab);
|
||||
$sql->add_param("MemberID");
|
||||
$sql->add_param("Total_Jual", $ajual['Jual']);
|
||||
$sql->add_param("Total_Diskon", $ajual['Diskon']);
|
||||
$sql->add_param("Total_Potong", $tot_potong);
|
||||
$sql->add_param("Total_HPP", $ajual['HPP']);
|
||||
$sql->add_param("Total_Bayar");
|
||||
$sql->add_param("Total_Kartu");
|
||||
$sql->add_param("KartuID", $id_kartu);
|
||||
$sql->add_param("No_Kartu", $no_kartu);
|
||||
$sql->add_param("Nama_Kartu", $nama_kartu);
|
||||
$sql->add_param("Lunas", 1);
|
||||
$sql->add_param_stamp();
|
||||
$sql->add_param_userid();
|
||||
$sql->add_where("No_Jual", $this->no_jual);
|
||||
$sql->UpdateDB();
|
||||
|
||||
// PROSES MEMBER POINT
|
||||
if ($this->id_member > 0) {
|
||||
$apoint = $this->db->fetchColumn("SELECT Point_TipeID FROM inv_point_tipe WHERE Aktif=1 ORDER BY Point_TipeID") ?? [];
|
||||
if (count($apoint) > 0) {
|
||||
$amember = $this->db->fetchRow("SELECT Grup_MemberID,IM,Kode_Member FROM para_member WHERE MemberID=?", [$this->id_member]);
|
||||
if ($amember && ($amember['IM'] === 1 || ($amember['IM'] === 0 && !empty($amember['Kode_Member'])))) {
|
||||
$this->db->runQuery("DELETE FROM inv_point_tx WHERE No_TX=?", [$this->no_jual]);
|
||||
foreach ($apoint as $id_tipe) {
|
||||
if ($amember['IM'] === 0 && $id_tipe === 1) continue;
|
||||
$tot_point = $this->inv->Point_Hitung($this->no_jual, tgl_dmy(), $amember['Grup_MemberID'], $id_kartu, $id_tipe);
|
||||
if ($tot_point > 0) $this->db->runQuery("INSERT INTO inv_point_tx (No_TX,Tgl_TX,Point_TipeID,CabID,MemberID,Point,Nilai_Point,DateStamp,UserID) VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), ?)", [$this->no_jual, tgl_ymd(), $id_tipe, $this->id_cab, $this->id_member, $tot_point, $tot_point, $this->app->user()->id()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PROSES POSTING GL
|
||||
$ainfo = $this->db->fetchRow("SELECT J.*,B.Nama_Member,(J.Total_Jual-J.Total_Diskon) Tagihan FROM (SELECT * FROM inv_jual WHERE No_Jual=?) J LEFT JOIN para_member B ON (B.MemberID=J.MemberID)", [$this->no_jual]);
|
||||
if (count($ainfo) > 0) {
|
||||
$ajurnal = [
|
||||
'Kode_Jurnal' => $ainfo['No_Jual'],
|
||||
'TipeID' => 7,
|
||||
'CabID' => $ainfo['CabID'],
|
||||
'Tanggal' => tgl_sql2str($ainfo['Tgl_Jual']),
|
||||
'Kode_Ref' => $ainfo['No_Jual'],
|
||||
'Catatan' => "Penjualan POS : ".$ainfo['No_Jual']." | ".$ainfo['Nama_Member']." | ".$this->app->user()->username()
|
||||
];
|
||||
$_rek_d = "D"; $_rek_k = "K";
|
||||
if ($ainfo['Tagihan'] < 0) { $_rek_d = "K"; $_rek_k = "D"; }
|
||||
$adetail = [
|
||||
[ 'Kode_Rek' => $this->app_gel['HPP'], 'DK' => $_rek_d, 'Jumlah' => $ainfo['Total_HPP'] ],
|
||||
[ 'Kode_Rek' => $this->app_gel['STOK'], 'DK' => $_rek_k, 'Jumlah' => $ainfo['Total_HPP'] ],
|
||||
[ 'Kode_Rek' => $rek_debit, 'DK' => $_rek_d, 'Jumlah' => $ainfo['Tagihan'] ],
|
||||
[ 'Kode_Rek' => $this->app_gel['JUAL'], 'DK' => $_rek_k, 'Jumlah' => $ainfo['Tagihan']+$ainfo['Total_Potong'] ]
|
||||
];
|
||||
if ($ainfo['Total_Potong'] > 0) array_push($adetail, [ 'Kode_Rek' => $this->app_gel['POT_JUAL'], 'DK' => "D", 'Jumlah' => $ainfo['Total_Potong'] ]);
|
||||
$this->gel->Jurnal_Post($ajurnal, $adetail);
|
||||
}
|
||||
|
||||
$atabel = $this->Data_Jual();
|
||||
$atabel['No_Cetak'] = $this->no_jual;
|
||||
$_kembali = (float) $this->db->fetchField("SELECT (Total_Jual-Total_Diskon-Total_Potong-Total_Bayar) Sisa FROM inv_jual WHERE No_Jual=?", [$this->no_jual]) ?? 0;
|
||||
if ($_kembali !== 0) $atabel['Kembali'] = '<span style="text-danger">'.rupiah($_kembali).'</span>';
|
||||
|
||||
//MONITOR DISPLAY
|
||||
if ($this->app_inv['MON_ENABLE']) {
|
||||
$this->db->runQuery("UPDATE disp_login SET No_Cetak=? WHERE CabID=? AND UserID=? AND Unix=?", [$this->no_jual, $this->id_cab, $this->app->user()->id(), $this->app->user()->unix()]);
|
||||
}
|
||||
|
||||
if ($this->app_inv['PRINT_AUTO'] === 1) {
|
||||
$this->mode = "print";
|
||||
} else {
|
||||
$this->mode = ($this->app_inv['PRINT_OPENCD'] === 1) ? "opencd" : "saveonly";
|
||||
}
|
||||
|
||||
} else if ($this->mode === "delete") {
|
||||
// PROSES UPDATE PROMO
|
||||
$ajual = $this->db->fetchRow("SELECT J.*,M.Grup_MemberID FROM (SELECT MemberID,Tgl_Jual FROM inv_jual WHERE No_Jual=?) J LEFT JOIN para_member M ON (M.MemberID=J.MemberID)", [$this->no_jual]);
|
||||
if ($ajual) $this->inv->Promo_Hapus($this->no_jual, tgl_sql2str($ajual['Tgl_Jual']), $ajual['Grup_MemberID']);
|
||||
|
||||
// PROSES MEMBER POINT
|
||||
if ($ajual['MemberID'] > 0) $this->db->runQuery("DELETE FROM inv_point_tx WHERE No_TX=?", [$this->no_jual]);
|
||||
// PROSES POSTING GL
|
||||
$this->db->runQuery("DELETE FROM gel_jurnal WHERE Kode_Jurnal=?", [$this->no_jual]);
|
||||
$this->db->runQuery("DELETE FROM gel_jurnal_detail WHERE Kode_Jurnal=?", [$this->no_jual]);
|
||||
|
||||
$this->db->runQuery("DELETE FROM inv_jual WHERE No_Jual=?", [$this->no_jual]);
|
||||
$this->db->runQuery("DELETE FROM inv_detail WHERE No_Ref=?", [$this->no_jual]);
|
||||
$atabel = $this->Data_Jual();
|
||||
|
||||
} else if ($this->mode === "cancel") {
|
||||
if (str_ends_with($this->no_jual, "#00") || !$this->is_pend) $this->inv->Detail_Cancel($this->no_jual);
|
||||
$atabel = $this->Data_Jual();
|
||||
} else {
|
||||
$atabel = $this->Data_Jual();
|
||||
}
|
||||
|
||||
//MONITOR DISPLAY
|
||||
if ($this->app_inv['MON_ENABLE']) {
|
||||
$this->db->runQuery("UPDATE disp_login SET No_Pos=? WHERE CabID=? AND UserID=? AND Unix=?", [$atabel['No_Jual'], $this->id_cab, $this->app->user()->id(), $this->app->user()->unix()]);
|
||||
}
|
||||
|
||||
$form = new Form($this->app);
|
||||
$tno_jual = $form->textbox("_", "No_Jual", $atabel['No_Jual'], false);
|
||||
$tn_member = $form->textauto("_", "Nama_Member", ['value'=>$atabel['MemberID'],'text'=>$atabel['Nama_Member']], true, true, "cari member");
|
||||
$ti_member = $form->textarea("_", "Info_Member", $atabel['Info_Member'], false);
|
||||
$tinfo = '<div class="card bg-light"><img class="img-fluid p-1" src="'.PROJECT_BASE.'assets/images/logo60.png" style="opacity:.75;"></div>';
|
||||
$ajson['html'] = '
|
||||
<div class="row mb-3">
|
||||
<div class="col"><div class="border border-success rounded px-2 display-6 text-end" id="Total_Disp">'.$atabel['Kembali'].'</div></div>
|
||||
</div>
|
||||
<div class="row mb-1"><div class="col">'.$tinfo.'</div></div>
|
||||
<div class="row mb-1">
|
||||
<div class="col"><div class="input-group">'.$tno_jual.'<button class="btn btn-info shadow-none" type="button" id="posPEND"><i class="bi-search"></i></button></div></div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<div class="col"><div class="input-group">'.$tn_member.'<button class="btn btn-warning shadow-none" type="button" id="posMEMBER"><i class="bi-people-fill"></i></button></div></div>
|
||||
</div>
|
||||
<div class="row mb-1"><div class="col">'.$ti_member.'</div></div>
|
||||
<div class="row mb-1 mt-4"><div class="col d-grid gap-2">
|
||||
<button type="button" class="btn btn-success" id="posSIMPAN"><i class="bi-cart-plus me-1"></i>Bayar</button>
|
||||
<button type="button" class="btn btn-danger" id="posBATAL"><i class="bi-x-lg me-1"></i>Batal</button>
|
||||
</div></div>
|
||||
<div class="row mb-1 mt-4"><div class="col d-grid gap-2">
|
||||
<button type="button" class="btn btn-outline-info" id="posNOTA"><i class="bi-list me-1"></i>Daftar Transaksi</button>
|
||||
<button type="button" class="btn btn-outline-info" id="posBARANG"><i class="bi-search me-1"></i>Cari Barang</button>
|
||||
</div></div>
|
||||
<input type="hidden" id="No_Cetak" value="'.$atabel['No_Cetak'].'" />
|
||||
<input type="hidden" id="Total_Tunai" value="'.$atabel['Total_Tunai'].'" />
|
||||
<input type="hidden" id="Total_Kartu" value="'.$atabel['Total_Kartu'].'" />
|
||||
<input type="hidden" id="Total_Bayar" value="'.$atabel['Total_Bayar'].'" />
|
||||
<input type="hidden" id="Total_Nota" value="'.$atabel['Total_Nota'].'" />
|
||||
<input type="hidden" id="Total_Item" value="'.$atabel['Total_Item'].'" />
|
||||
<input type="hidden" id="Tgl_Jual" value="'.tgl_sql2str($atabel['Tgl_Jual']).'" />
|
||||
<input type="hidden" id="MemberID" value="'.$atabel['MemberID'].'" />
|
||||
<input type="hidden" id="Grup_MemberID" value="'.$atabel['Grup_MemberID'].'" />
|
||||
<input type="hidden" id="KartuID" value="'.$atabel['KartuID'].'" />
|
||||
<input type="hidden" id="No_Kartu" value="'.$atabel['No_Kartu'].'" />
|
||||
<input type="hidden" id="Nama_Kartu" value="'.$atabel['Nama_Kartu'].'" />
|
||||
<input type="hidden" id="mode" value="'.$this->mode.'" />';
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function form_produk() {
|
||||
$id = (int) Param::Get("ID", 0);
|
||||
$atabel = [ 'ID'=>$id, 'InvID'=>$this->id_inv, 'SatuanID'=>$this->id_satuan, 'VarianID'=>$this->id_varian, 'Kode_SKU'=>"", 'Kode_Barcode'=>"", 'Nama_Lengkap'=>"", 'Satuan_Kemasan'=>"", 'Qty'=>0, 'Harga_Beli'=>0, 'Harga_Jual'=>0, 'Disk_Rupiah'=>0 ];
|
||||
if ($id > 0) {
|
||||
$_row = $this->db->fetchRow("SELECT ID,-Qty Qty,Harga_Beli,Harga_Jual,Disk_Rupiah FROM tmp_inv_detail WHERE No_Ref=? AND ID=?", [$this->no_jual, $id]);
|
||||
if ($_row) $atabel = array_merge($atabel, $_row->getData());
|
||||
}
|
||||
if ($this->id_inv > 0 && $this->id_satuan > 0) {
|
||||
$_row = $this->db->fetchRow("SELECT Kode_SKU,Kode_Barcode,Nama_Lengkap,Satuan_Kemasan,Harga_Pokok Harga_Beli,Harga_Jual FROM inv_produk_join WHERE InvID=? AND SatuanID=? AND VarianID=? AND Grup_MemberID=?", [$this->id_inv, $this->id_satuan, $this->id_varian, $this->id_grup_member]);
|
||||
if ($_row) $atabel = array_merge($atabel, $_row->getData());
|
||||
}
|
||||
|
||||
$form = new Form($this->app);
|
||||
$tsku = $form->textbox("_", "Kode_SKU", $atabel['Kode_SKU']. " / " .$atabel['Kode_Barcode'], false);
|
||||
$tnama = $form->textbox("_", "Nama_Lengkap", $atabel['Nama_Lengkap'], false);
|
||||
$tqty = $form->textbox("_", "Qty", $atabel['Qty'], true, true, "double");
|
||||
$tjual = $form->textbox("_", "Harga_Jual", $atabel['Harga_Jual'], false, false, "double");
|
||||
$tdisrp = $form->textbox("_", "Disk_Rupiah", $atabel['Disk_Rupiah'], true, false, "double");
|
||||
$tdispn = $form->textbox("_", "Disk_Persen", 0, true, false, "double");
|
||||
$ttot = $form->textbox("_", "Jumlah", 0, false, false, "double");
|
||||
$tsat = $form->textbox("_", "Nama_Satuan", $atabel['Satuan_Kemasan'], false);
|
||||
$ajson['html'] = '
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label">Kode SKU / Barcode</label>
|
||||
<div class="col">'.$tsku.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label">Nama Barang</label>
|
||||
<div class="col">'.$tnama.'</div>
|
||||
</div>
|
||||
<div class="row mb-1"><hr class="my-1"></div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label" for="Qty">Qty</label>
|
||||
<div class="col-sm-4 col-lg-5"><div class="input-group">'.$tqty.$tsat.'</div></div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label">Harga (@)</label>
|
||||
<div class="col-sm-8 col-lg-5">'.$tjual.'</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label" for="Disk_Rupiah">Diskon (@)</label>
|
||||
<div class="col-sm-8 col-lg-5">'.$tdisrp.'</div>
|
||||
<div class="col-sm-3 col-lg-3"><div class="input-group"><div class="input-group-text">≈</div>'.$tdispn.'<div class="input-group-text">%</div></div></div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col-sm-4 col-lg-3 col-form-label">Sub Total</label>
|
||||
<div class="col-sm-8 col-lg-5">'.$ttot.'</div>
|
||||
</div>
|
||||
<input type="hidden" id="ID" value="'.$atabel['ID'].'" >
|
||||
<input type="hidden" id="InvID" value="'.$atabel['InvID'].'" >
|
||||
<input type="hidden" id="SatuanID" value="'.$atabel['SatuanID'].'" >
|
||||
<input type="hidden" id="VarianID" value="'.$atabel['VarianID'].'" >
|
||||
<input type="hidden" id="Harga_Beli" value="'.$atabel['Harga_Beli'].'" >
|
||||
<input type="hidden" id="mode_detail" value="'.$this->mode_detail.'" >';
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function form_kasir() {
|
||||
$tot_jual = Param::Float("Total_Nota", 0);
|
||||
$tot_jual -= $this->inv->Promo_Hitung($this->no_jual, tgl_dmy(), $this->id_grup_member);
|
||||
|
||||
$form = new Form($this->app);
|
||||
$tjual = $form->textbox("_", "popTotal_Jual", uang($tot_jual), false, false, "double");
|
||||
$ttunai = $form->textbox("_", "popTotal_Tunai", 0, true, false, "double");
|
||||
$tkartu = $form->textbox("_", "popTotal_Kartu", 0, true, false, "double");
|
||||
$tsisa = $form->textbox("_", "popTotal_Sisa", 0, false, false, "double");
|
||||
$okartu = $form->option_db("_", "popKartuID", 0, true, false, "para_rek_pos", ["KartuID","Kode_Kartu"], "Aktif=1", [0,"Pilihan Non Tunai"]);
|
||||
$tnokartu = $form->textbox("_", "popNo_Kartu", "", true, false, "text");
|
||||
$tnamakartu = $form->textbox("_", "popNama_Kartu", "", true, false, "text");
|
||||
$ajson['html'] = '
|
||||
<div class="row mb-1"><div class="col-sm-6 col-lg-5 col-form-label">Total Nota Rp.</div><div class="col-sm-6 col-lg-7">'.$tjual.'</div></div>
|
||||
<div class="row mb-1"><div class="col-sm-6 col-lg-5 col-form-label">Tunai Rp.</div><div class="col-sm-6 col-lg-7">'.$ttunai.'</div></div>
|
||||
<div class="row mb-1"><div class="col-sm-6 col-lg-5">'.$okartu.'</div><div class="col-sm-6 col-lg-7">'.$tkartu.'</div></div>
|
||||
<div class="row mb-1"><div class="col-sm-6 col-lg-5 col-form-label">Kembali Rp.</div><div class="col-sm-6 col-lg-7">'.$tsisa.'</div></div>
|
||||
<hr class="my-2 ckartu d-none">
|
||||
<div class="row mb-1 ckartu d-none"><div class="col-sm-6 col-lg-5 col-form-label">Nomor Kartu</div><div class="col-sm-6 col-lg-7">'.$tnokartu.'</div></div>
|
||||
<div class="row mb-1 ckartu d-none"><div class="col-sm-6 col-lg-5 col-form-label">Nama Pemilik</div><div class="col-sm-6 col-lg-7">'.$tnamakartu.'</div></div>
|
||||
<hr class="my-2">
|
||||
<div class="row mt-1">
|
||||
<div class="col-3 d-grid"><button type="button" class="btn btn-primary" id="butKPend">Pending</button></div>
|
||||
<div class="col-3"> </div>
|
||||
<div class="col-3 d-grid"><button type="button" class="btn btn-danger" id="butKBatal" data-bs-dismiss="modal">Batal</button></div>
|
||||
<div class="col-3 d-grid"><button type="button" class="btn btn-success" id="butKBayar">Bayar</button></div>
|
||||
</div>
|
||||
<input type="hidden" id="popTotal_Bayar" value="0" />';
|
||||
$ajson['Total_Disp'] = rupiah($tot_jual);
|
||||
$this->app->json($ajson);
|
||||
}
|
||||
|
||||
public function config_pole() {
|
||||
$apole = [];
|
||||
$_pole = $this->db->fetchRow("SELECT * FROM disp_config WHERE REG_ID=?", [$this->web_app['APP_CODE']]);
|
||||
if ($_pole) {
|
||||
foreach ($_pole->getData() as $_key => $_val) {
|
||||
if (str_contains($_key, "POLE")) {
|
||||
if (str_contains($_key, "ENABLE")) $_val = (int) $_val;
|
||||
$apole[str_replace("POLE_","",$_key)] = $_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->app->json([ 'pole'=> $apole ]);
|
||||
}
|
||||
|
||||
public function index() {
|
||||
$this->app->json(['html' => '
|
||||
<div class="fade-in">
|
||||
<div class="card"><div class="card-body">
|
||||
<div class="row flex-column-reverse flex-md-row">
|
||||
<div class="col-sm-12 col-md-9 col-lg-10 mt-3 mt-md-0">
|
||||
<div class="row mb-1">
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<input type="search" class="form-control fs-5" id="Nama_Produk" value="" placeholder="Scan SKU / Barcode / Ketik Nama Barang" autocomplete="off" />
|
||||
</div>
|
||||
<div class="col-sm-3 col-lg-2">
|
||||
<input type="double" class="form-control double fs-5" id="POS_Qty" value="1.00" maxlength="10" />
|
||||
</div>
|
||||
</div>
|
||||
<div id="divPOS1"> </div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-3 col-lg-2 border-start">
|
||||
<div id="divPOS2"> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div></div></div>'
|
||||
]);
|
||||
}
|
||||
|
||||
private function Data_Jual(string $nomor=""): array {
|
||||
$aparam = [
|
||||
'No_Jual' => "POS".$this->web_app['SERVER_ID'].(string) $this->id_cab.$this->app->user()->id(3)."#00",
|
||||
'No_Cetak' => "",
|
||||
'Tgl_Jual' => tgl_ymd(),
|
||||
'MemberID' => $this->id_member,
|
||||
'Grup_MemberID' => $this->id_grup_member,
|
||||
'Nama_Member' => "",
|
||||
'Info_Member' => "",
|
||||
'Total_Nota' => 0,
|
||||
'Total_Item' => 0,
|
||||
'Total_Tunai' => 0,
|
||||
'Total_Kartu' => 0,
|
||||
'Total_Bayar' => 0,
|
||||
'KartuID' => 0,
|
||||
'No_Kartu' => "",
|
||||
'Nama_Kartu' => "",
|
||||
'Kembali' => "0"
|
||||
];
|
||||
if (empty($nomor)) {
|
||||
$aparam['MemberID'] = $this->id_member_def;
|
||||
} else {
|
||||
$tabel_jual = (str_contains($nomor, "POS") === false) ? "inv_jual" : "inv_jual_pend";
|
||||
$row = $this->db->fetchRow("SELECT * FROM ".$tabel_jual." WHERE CabID=? AND No_Jual=?", [$this->id_cab, $nomor]);
|
||||
if ($row) $aparam = array_merge($aparam, $row->getData());
|
||||
}
|
||||
if ($aparam['MemberID'] > 0) {
|
||||
$row = $this->db->fetchRow("SELECT Grup_MemberID,Nama_Member,TRIM(CONCAT(Kode_Member,'\n',Kota_Member)) Info_Member FROM para_member WHERE MemberID=?", [$aparam['MemberID']]);
|
||||
if ($row) $aparam = array_merge($aparam, $row->getData());
|
||||
}
|
||||
return $aparam;
|
||||
}
|
||||
|
||||
private function Pending_Nomor(): string {
|
||||
$tno = "POS".$this->web_app['SERVER_ID'].(string) $this->id_cab.$this->app->user()->id(3)."#";
|
||||
$ino = (int) $this->db->fetchField("SELECT MAX(RIGHT(No_Jual,2)) FROM inv_jual_pend WHERE No_Jual LIKE ?", [$tno.'%']) ?? 0;
|
||||
$tno .= isi_nol(++$ino, 2);
|
||||
return $tno;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user