Files
be-accone/application/controllers/mockup/mutasi/Requestmutasi.php

1402 lines
58 KiB
PHP

<?php
class Requestmutasi extends MY_Controller
{
var $db;
public function index()
{
echo "Request Mutasi API";
}
public function __construct()
{
parent::__construct();
}
function search()
{
try {
if (!$this->isLogin) {
$this->sys_error("invalid token");
exit;
}
$prm = $this->sys_input;
$user = $this->sys_user;
$start_date = $prm['start_date'];
$end_date = $prm['end_date'];
$search = '%' . $prm['search'] . '%';
$page = 0;
$limit = 15;
if ($prm['current_page'] > 0) {
$page = ($prm['current_page'] - 1) * $limit;
}
$status = $prm['status'];
$status_rm = "";
if ($status != "") {
$status_rm .= " AND MutasiRequestStatus = '{$status}'";
}
$sql = "SELECT DISTINCT MutasiRequestID,
MutasiRequestDate,
MutasiRequestNumber,
MutasiRequestTotalValue,
MutasiRequestStatus,
MutasiRequestNote,
itemCategoryID,
itemCategoryName,
a.M_BranchID as branch_asal_id,
a.M_BranchCode as branch_asal_code,
a.M_BranchName as branch_asal_name,
b.M_BranchID as branch_tujuan_id,
b.M_BranchCode as branch_tujuan_code,
b.M_BranchName as branch_tujuan_name
FROM mutasi_request
JOIN item_category ON MutasiRequestItemCategoryID = itemCategoryID
AND itemCategoryIsActive = 'Y'
JOIN m_branch a ON MutasiRequestFromBranchID = a.M_BranchID
AND a.M_BranchIsActive = 'Y'
JOIN m_branch b ON MutasiRequestToBranchID = b.M_BranchID
AND b.M_BranchIsActive = 'Y'
WHERE MutasiRequestIsActive = 'Y'
$status_rm
AND (MutasiRequestNumber LIKE ?)
AND MutasiRequestDate BETWEEN DATE(?) AND DATE(?)
ORDER BY MutasiRequestID DESC";
$sqltotal = "SELECT COUNT(*) as total FROM ($sql) as x";
$qrytotal = $this->db->query($sqltotal, [$search, $start_date, $end_date]);
if (!$qrytotal) {
$this->sys_error_db("['Error'] get total data mutasi", $this->db);
exit;
}
$total = $qrytotal->row_array()['total'];
$sqldata = $sql . " LIMIT ? OFFSET ?";
$qrydata = $this->db->query($sqldata, [
$search,
$start_date,
$end_date,
$limit,
$page
]);
if (!$qrydata) {
$this->sys_error_db("[Error] get list data mutasi", $this->db);
exit;
}
$rows = $qrydata->result_array();
$result = array(
"total_page" => ceil($total / $limit),
"records" => $rows
);
$this->sys_ok($result);
} catch (Exception $exc) {
$message = $exc->getMessage();
$this->sys_error($message);
}
}
function getCategory()
{
try {
if (!$this->isLogin) {
$this->sys_error("invalid token");
exit;
}
$prm = $this->sys_input;
$search = '%' . $prm["search"] . '%';
$sql = "SELECT itemCategoryID,
itemCategoryName
FROM item_category
WHERE itemCategoryIsActive = 'Y'
AND itemCategoryName LIKE ?
AND itemCategoryID IN (2,3)
ORDER BY itemCategoryName ASC";
$qry = $this->db->query($sql, [$search]);
if (!$qry) {
$this->sys_error_db("[Error] Query getCategory");
return;
}
$rows = $qry->result_array();
$result = array(
"records" => $rows
);
$this->sys_ok($result);
} catch (Exception $exc) {
$message = $exc->getMessage();
$this->sys_error($message);
}
}
function getBranchAsal()
{
try {
if (!$this->isLogin) {
$this->sys_error("invalid token");
exit;
}
$prm = $this->sys_input;
$user = $this->sys_user;
$sql = "SELECT M_BranchID,
M_BranchCode,
M_BranchName
FROM m_branch
WHERE M_BranchIsActive = 'Y'
AND M_BranchID = ?";
$qry = $this->db->query($sql, [$user['M_BranchID']]);
if (!$qry) {
$this->sys_error_db("[Error] Query getBranchAsal");
return;
}
$rows = $qry->result_array();
$result = array(
"records" => $rows
);
$this->sys_ok($result);
} catch (Exception $exc) {
$message = $exc->getMessage();
$this->sys_error($message);
}
}
function getBranchTujuan()
{
try {
if (!$this->isLogin) {
$this->sys_error("invalid token");
exit;
}
$prm = $this->sys_input;
$user = $this->sys_user;
$search = '%' . $prm["search"] . '%';
$sql = "SELECT M_BranchID,
M_BranchCode,
M_BranchName
FROM m_branch
WHERE M_BranchIsActive = 'Y'
AND M_BranchS_RegionalID = ?
AND M_BranchID <> ?
AND M_BranchName LIKE ?
ORDER BY M_BranchName ASC";
$qry = $this->db->query($sql, [$user['S_RegionalID'], $user['M_BranchID'], $search]);
if (!$qry) {
$this->sys_error_db("[Error] Query getBranchTujuan");
return;
}
$rows = $qry->result_array();
$result = array(
"records" => $rows
);
$this->sys_ok($result);
} catch (Exception $exc) {
$message = $exc->getMessage();
$this->sys_error($message);
}
}
function getReceiveOrderPo()
{
try {
if (!$this->isLogin) {
$this->sys_error("invalid token");
exit;
}
$prm = $this->sys_input;
$itemCategoryID = $prm["itemCategoryID"];
$branchAsalCode = $prm["branchAsalCode"];
$search = '%' . $prm["search"] . '%';
$sql = "SELECT DISTINCT ReceiveOrderPoID,
ReceiveOrderPoNumber,
ReceiveOrderPoIDate,
ReceiveOrderPoWarehouseID,
ReceiveOrderPoM_BranchCode
FROM receive_order_po
JOIN t_barcode_barang ON T_BarcodeBarangReceiveOrderPoID = ReceiveOrderPoID
AND T_BarcodeBarangIsActive = 'Y'
AND T_BarcodeBarangStockID <> 0
JOIN m_item ON T_BarcodeBarangM_ItemID = M_ItemID
AND M_ItemIsActive = 'Y'
AND M_ItemItem_CategoryID = ?
WHERE ReceiveOrderPoIsActive = 'Y'
AND ReceiveOrderPoM_BranchCode = ?
AND ReceiveOrderPoIsHandover = 'Y'
AND ReceiveOrderPoConfirmed = 'Y'
AND (ReceiveOrderPoNumber LIKE ?)
GROUP BY ReceiveOrderPoID
ORDER BY ReceiveOrderPoNumber DESC";
$qry = $this->db->query($sql, [$itemCategoryID, $branchAsalCode, $search]);
if (!$qry) {
$this->sys_error_db("[Error] Query getReceiveOrderPo");
return;
}
$rows = $qry->result_array();
$result = array(
"records" => $rows
);
$this->sys_ok($result);
} catch (Exception $exc) {
$message = $exc->getMessage();
$this->sys_error($message);
}
}
function getItemReceive()
{
try {
if (!$this->isLogin) {
$this->sys_error("invalid token");
exit;
}
$prm = $this->sys_input;
$search = '%' . $prm["search"] . '%';
$warhouseID = $prm["warhouseID"];
$branchAsalCode = $prm["branchAsalCode"];
$receiveOrderPoID = $prm["receiveOrderPoID"];
$totalCount = 0;
$totalPage = 0;
$number_offset = 0;
$number_limit = 15;
if ($prm["current_page"] > 0) {
$number_offset = ($prm["current_page"] - 1) * $number_limit;
}
$sql_branch = "SELECT M_BranchID,
M_BranchCode
FROM m_branch
WHERE M_BranchIsActive = 'Y'
AND M_BranchCode = ?";
$qry_branch = $this->db->query($sql_branch, [$branchAsalCode]);
if (!$qry_branch) {
$this->sys_error_db("[Error] Query getItem - branch");
return;
}
$row_branch = $qry_branch->result_array()[0];
$sql = "SELECT
ro.ReceiveOrderPoID,
ro.ReceiveOrderPoNumber,
i.M_ItemID,
i.M_ItemCode,
i.M_ItemDesc,
iu.ItemUnitID,
iu.ItemUnitCode,
iu.ItemUnitName,
s.StockID,
s.StockQty AS stock_total,
COUNT(b.T_BarcodeBarangID) AS barcode_total,
COUNT(DISTINCT l.MutasiStockLockT_BarcodeBarangID) AS qty_locked,
(COUNT(b.T_BarcodeBarangID) - COUNT(DISTINCT l.MutasiStockLockT_BarcodeBarangID)) AS qty_available,
w.WarehouseID,
0 AS qty_mutasi,
GROUP_CONCAT(b.T_BarcodeBarangID) as barcode_ids
FROM t_barcode_barang b
JOIN receive_order_po ro ON b.T_BarcodeBarangReceiveOrderPoID = ro.ReceiveOrderPoID
AND ro.ReceiveOrderPoIsActive = 'Y'
AND ro.ReceiveOrderPoID = ?
JOIN stock s ON s.StockID = b.T_BarcodeBarangStockID
JOIN warehouse w ON s.StockWarehouseID = w.WarehouseID
AND w.WarehouseIsActive = 'Y'
AND w.WarehouseM_BranchID = ?
JOIN m_item i ON i.M_ItemID = b.T_BarcodeBarangM_ItemID
JOIN itemunit iu ON b.T_BarcodeBarangItemUnitID = iu.ItemUnitID
LEFT JOIN (
SELECT MutasiStockLockT_BarcodeBarangID
FROM mutasi_stock_lock
WHERE MutasiStockLockIsActive = 'Y'
AND MutasiStockLockStatus = 'ACTIVE'
AND MutasiStockLockType = 'INV'
) l
ON l.MutasiStockLockT_BarcodeBarangID = b.T_BarcodeBarangID
WHERE
s.StockWarehouseID = ?
AND b.T_BarcodeBarangIsActive = 'Y'
AND b.T_BarcodeBarangStockID <> 0
AND (i.M_ItemCode LIKE ? OR i.M_ItemDesc LIKE ?)
GROUP BY
ro.ReceiveOrderPoID,
s.StockID,
i.M_ItemID
ORDER BY ro.ReceiveOrderPoID DESC";
$sqltotal = "SELECT COUNT(*) as total FROM ($sql) as x";
$qrytotal = $this->db->query($sqltotal, [$receiveOrderPoID, $row_branch['M_BranchID'], $warhouseID, $search, $search]);
if ($qrytotal) {
$totalCount = $qrytotal->result_array()[0]['total'];
$totalPage = ceil($totalCount / $number_limit);
} else {
$this->sys_error_db("[Error] Query getItem - total", $this->db);
exit;
}
$sql_list = $sql . " LIMIT ? OFFSET ?";
$qry = $this->db->query($sql_list, [$receiveOrderPoID, $row_branch['M_BranchID'], $warhouseID, $search, $search, $number_limit, $number_offset]);
if (!$qry) {
$this->sys_error_db("[Error] Query getItem");
return;
}
$rows = $qry->result_array();
$result = array(
"total_page" => $totalPage,
"records" => $rows
);
$this->sys_ok($result);
} catch (Exception $exc) {
$message = $exc->getMessage();
$this->sys_error($message);
}
}
private function getDataMutasiRequest($id)
{
$sql = "SELECT * FROM mutasi_request WHERE MutasiRequestID = ?";
$qry = $this->db->query($sql, [$id]);
if (!$qry) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] get mutasi request", $this->db);
exit;
}
$header = $qry->row_array();
$sqldetail = "SELECT * FROM mutasi_request_detail
WHERE MutasiRequestDetailMutasiRequestID = ? AND MutasiRequestDetailIsActive = 'Y'";
$qrydetail = $this->db->query($sqldetail, [$id]);
if (!$qrydetail) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] get mutasi request detail", $this->db);
exit;
}
$detail = $qrydetail->result_array();
$header['details'] = $detail;
return $header;
}
function saveMutasi()
{
try {
if (!$this->isLogin) {
$this->sys_error("invalid token");
exit;
}
$this->db->trans_begin();
$prm = $this->sys_input;
$user = $this->sys_user;
# VALIDASI HEADER #
if (intval($prm["branch_asal_id"]) == intval($prm["branch_tujuan_id"])) {
$this->sys_error("Branch Asal dan Branch Tujuan tidak boleh sama");
exit;
}
if (count($prm["list_mutasi"]) == 0) {
$this->sys_error("Tidak ada item untuk dimutasi");
exit;
}
# CEK JENIS #
$isInventaris = (intval($prm["category_id"]) === 2);
$isAsset = (intval($prm["category_id"]) === 3);
if ($isAsset && count($prm["list_mutasi"]) > 1) {
$this->sys_error("Mutasi asset hanya boleh 1 item");
exit;
}
# HITUNG NILAI #
$totalValue = 0;
foreach ($prm["list_mutasi"] as $item) {
if ($isInventaris) {
if (intval($item['qty_mutasi']) <= 0 || intval($item['qty_mutasi']) > intval($item['qty_available'])) {
$this->sys_error('QTY mutasi melebihi item yang tersedia');
exit;
}
# GET BARCODE IDS FIFO #
$sql_barcode_ids = "SELECT T_BarcodeBarangID,
T_BarcodeBarangStockID,
T_BarcodeBarangNumber
FROM t_barcode_barang
WHERE T_BarcodeBarangIsActive = 'Y'
AND T_BarcodeBarangReceiveOrderPoID = ?
ORDER BY T_BarcodeBarangID ASC";
$qry_barcode_ids = $this->db->query($sql_barcode_ids, [$item["ReceiveOrderPoID"]]);
if (!$qry_barcode_ids) {
$this->sys_error_db("[Error] Query getBarcode", $this->db);
exit;
}
$barcode_rows = $qry_barcode_ids->result_array();
$selected_barcodes = [];
$count = 0;
foreach ($barcode_rows as $b) {
if ($count >= intval($item['qty_mutasi'])) {
break;
}
$selected_barcodes[] = $b;
$count++;
}
$detailItems[] = [
'receive_order_po_id' => $item['ReceiveOrderPoID'],
'receive_order_po_number' => $item['ReceiveOrderPoNumber'],
'item_id' => $item['M_ItemID'],
'item_desc' => $item['M_ItemDesc'],
'itemunit_id' => $item['ItemUnitID'],
'itemunit_name' => $item['ItemUnitName'],
'stock_id' => $item['StockID'],
'warehouse_id' => $item['WarehouseID'],
'barcode_ids' => $selected_barcodes,
'qty' => $item['qty_mutasi'],
'book_value' => 1,
'lock_type' => 'INV'
];
$totalValue = 1;
} else {
// ASSET
if (intval($item['qty_mutasi']) != 1) {
$this->sys_error("Qty asset harus 1");
exit;
}
// $asset = getAssetByItemID($item['M_ItemID']);
// $itemBookValue = $asset->BookValue;
// $totalValue = $itemBookValue;
// $detailItems[] = [
// 'item_id' => $item['M_ItemID'],
// 'itemunit_id' => $item['ItemUnitID'],
// 'stock_id' => $item['StockID'],
// 'warehouse_id' => $item['WarehouseID'],
// 'barcode_ids' => $item['T_BarcodeBarangID'],
// 'qty' => 1,
// 'book_value' => 1, // nanti diganti nilai buku
// 'lock_type' => 'AST'
// ];
// $totalValue = 1; // atau nilai buku asset
}
}
# INSERT HEADER #
$sql_header = "INSERT INTO mutasi_request(
MutasiRequestDate,
MutasiRequestNumber,
MutasiRequestItemCategoryID,
MutasiRequestFromBranchID,
MutasiRequestToBranchID,
MutasiRequestTotalValue,
MutasiRequestNote,
MutasiRequestStatus,
MutasiRequestIsActive,
MutasiRequestCreated,
MutasiRequestUserID) VALUES(?,fn_numbering('RM'),?,?,?,?,?,'Draft','Y',NOW(),?)";
$qry_header = $this->db->query($sql_header, [
$prm['mutasi_date'],
$prm['category_id'],
$prm['branch_asal_id'],
$prm['branch_tujuan_id'],
$totalValue,
$prm['note'],
$user['M_UserID']
]);
if (!$qry_header) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] insert into table mutasi request", $this->db);
exit;
}
$mrID = $this->db->insert_id();
# INSERT DETAIL #
$logDesc = [];
foreach ($detailItems as $d) {
$sql_detail = "INSERT INTO mutasi_request_detail(
MutasiRequestDetailMutasiRequestID,
MutasiRequestDetailReceiveOrderPoID,
MutasiRequestDetailReceiveOrderPoNumber,
MutasiRequestDetailStockID,
MutasiRequestDetailM_ItemID,
MutasiRequestDetailItemUnitID,
MutasiRequestDetailQty,
MutasiRequestDetailBookValue,
MutasiRequestDetailIsActive,
MutasiRequestDetailCreated,
MutasiRequestDetailUserID
) VALUES(?,?,?,?,?,?,?,?,'Y',NOW(),?)";
$qry_detail = $this->db->query($sql_detail, [
$mrID,
$d['receive_order_po_id'],
$d['receive_order_po_number'],
$d['stock_id'],
$d['item_id'],
$d['itemunit_id'],
$d['qty'],
$d['book_value'],
$user['M_UserID']
]);
if (!$qry_detail) {
$this->db->trans_rollback();
$this->sys_error_db("['Error'] insert into table mutasi request detail", $this->db);
exit;
}
// ambil detail_id
$detail_id = $this->db->insert_id();
$logDesc[] = "- ADD {$d['item_desc']} {$d['qty']} {$d['itemunit_name']} dengan receive po number {$d['receive_order_po_number']}";
# VALIDASI STOCK #
if ($d['lock_type'] === 'INV') {
$sqlCheck = "SELECT COUNT(*) AS qty_available
FROM t_barcode_barang b
LEFT JOIN mutasi_stock_lock l
ON l.MutasiStockLockT_BarcodeBarangID = b.T_BarcodeBarangID
AND l.MutasiStockLockStatus = 'ACTIVE'
AND l.MutasiStockLockIsActive = 'Y'
WHERE
b.T_BarcodeBarangReceiveOrderPoID = ?
AND b.T_BarcodeBarangIsActive = 'Y'
AND l.MutasiStockLockID IS NULL
FOR UPDATE";
$row = $this->db->query($sqlCheck, [$d['receive_order_po_id']])->row();
if (!$row || $row->qty_available < $d['qty']) {
$this->db->trans_rollback();
$this->sys_error("Stock tidak mencukupi (sudah di-lock)");
exit;
}
} else if ($d['lock_type'] === 'AST') {
if (empty($d['barcode_ids'])) {
$this->db->trans_rollback();
$this->sys_error("Asset wajib memiliki barcode");
exit;
}
}
// INSERT STOCK LOCK
if (count($d['barcode_ids']) > 0) {
foreach ($d['barcode_ids'] as $b) {
$sqlLock = "INSERT INTO mutasi_stock_lock(
MutasiStockLockMutasiRequestID,
MutasiStockLockMutasiRequestDetailID,
MutasiStockLockM_ItemID,
MutasiStockLockStockID,
MutasiStockLockT_BarcodeBarangID,
MutasiStockLockM_BranchID,
MutasiStockLockWarehouseID,
MutasiStockLockQtyLocked,
MutasiStockLockType,
MutasiStockLockStatus,
MutasiStockLockIsActive,
MutasiStockLockCreated,
MutasiStockLockUserID
) VALUES(?,?,?,?,?,?,?,?,?,'ACTIVE','Y',NOW(),?)";
$qryLock = $this->db->query($sqlLock, [
$mrID,
$detail_id,
$d['item_id'],
$d['stock_id'],
$b['T_BarcodeBarangID'],
$prm['branch_asal_id'],
$d['warehouse_id'],
1,
$d['lock_type'],
$user['M_UserID']
]);
if (!$qryLock) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] insert table stock lock", $this->db);
exit;
}
}
}
}
$dataMrAfter = $this->getDataMutasiRequest($mrID);
$this->insertLogMutasiRequest($mrID, 'ADD', '', $dataMrAfter, $user['M_UserID'], implode("\n", $logDesc));
$this->insertUserActivity('MR', implode("\n", $logDesc), 'ADD', $mrID, $user['M_UserID']);
$this->db->trans_commit();
$this->sys_ok("Request mutasi created successfully");
} catch (Exception $exc) {
$message = $exc->getMessage();
$this->sys_error($message);
}
}
function getItemMutasiUpdate()
{
try {
if (!$this->isLogin) {
$this->sys_error("invalid token");
exit;
}
$prm = $this->sys_input;
$mutasiRequestID = $prm['mutasiRequestID'];
$sql = "SELECT
MutasiRequestDetailID,
MutasiRequestDetailMutasiRequestID,
MutasiRequestDetailReceiveOrderPoID AS ReceiveOrderPoID,
MutasiRequestDetailReceiveOrderPoNumber AS ReceiveOrderPoNumber,
M_ItemID,
M_ItemCode,
M_ItemDesc,
ItemUnitID,
ItemUnitCode,
ItemUnitName,
w.WarehouseID,
s.StockID,
s.StockQty AS stock_total,
IFNULL(bc.barcode_total, 0) AS barcode_total,
COUNT(DISTINCT lk.MutasiStockLockT_BarcodeBarangID) AS qty_locked,
IFNULL(bc.barcode_total, 0) - COUNT(DISTINCT lk.MutasiStockLockT_BarcodeBarangID) AS qty_available,
MutasiRequestDetailQty AS qty_mutasi
FROM mutasi_request_detail
JOIN mutasi_request
ON MutasiRequestDetailMutasiRequestID = MutasiRequestID
JOIN m_item
ON MutasiRequestDetailM_ItemID = M_ItemID
JOIN itemunit
ON MutasiRequestDetailItemUnitID = ItemUnitID
JOIN stock s
ON MutasiRequestDetailStockID = s.StockID
JOIN warehouse w
ON s.StockWarehouseID = w.WarehouseID
AND w.WarehouseIsActive = 'Y'
-- total barcode per stock + PO
LEFT JOIN (
SELECT
b.T_BarcodeBarangStockID,
b.T_BarcodeBarangReceiveOrderPoID,
COUNT(*) AS barcode_total
FROM t_barcode_barang b
WHERE b.T_BarcodeBarangIsActive = 'Y'
GROUP BY
b.T_BarcodeBarangStockID,
b.T_BarcodeBarangReceiveOrderPoID
) bc
ON bc.T_BarcodeBarangStockID = s.StockID
AND bc.T_BarcodeBarangReceiveOrderPoID = MutasiRequestDetailReceiveOrderPoID
-- barcode yang sedang di-lock
LEFT JOIN (
SELECT
l.MutasiStockLockT_BarcodeBarangID,
b.T_BarcodeBarangStockID,
b.T_BarcodeBarangReceiveOrderPoID
FROM mutasi_stock_lock l
JOIN t_barcode_barang b
ON b.T_BarcodeBarangID = l.MutasiStockLockT_BarcodeBarangID
WHERE
l.MutasiStockLockIsActive = 'Y'
AND l.MutasiStockLockStatus = 'ACTIVE'
AND l.MutasiStockLockType = 'INV'
) lk
ON lk.T_BarcodeBarangStockID = s.StockID
AND lk.T_BarcodeBarangReceiveOrderPoID = MutasiRequestDetailReceiveOrderPoID
WHERE
MutasiRequestDetailIsActive = 'Y'
AND MutasiRequestDetailMutasiRequestID = ?
GROUP BY
MutasiRequestDetailID,
s.StockID,
bc.barcode_total
ORDER BY
MutasiRequestDetailID";
$qry = $this->db->query($sql, [$mutasiRequestID]);
if (!$qry) {
$this->sys_error_db("[Error] get item update", $this->db);
exit;
}
$data = $qry->result_array();
$result = array(
"records" => $data
);
$this->sys_ok($result);
} catch (Exception $exc) {
$message = $exc->getMessage();
$this->sys_error($message);
}
}
function saveEditMutasi()
{
try {
if (!$this->isLogin) {
$this->sys_error("invalid token");
exit;
}
$this->db->trans_begin();
$prm = $this->sys_input;
$user = $this->sys_user;
# VALIDASI HEADER #
if (intval($prm["branch_asal_id"]) == intval($prm["branch_tujuan_id"])) {
$this->sys_error("Branch Asal dan Branch Tujuan tidak boleh sama");
exit;
}
if (count($prm["list_mutasi"]) == 0) {
$this->sys_error("Tidak ada item untuk dimutasi");
exit;
}
# CEK JENIS #
$isInventaris = (intval($prm["category_id"]) === 2);
$isAsset = (intval($prm["category_id"]) === 3);
if ($isAsset && count($prm["list_mutasi"]) > 1) {
$this->sys_error("Mutasi asset hanya boleh 1 item");
exit;
}
# get data mutasi for log #
$dataMrBefore = $this->getDataMutasiRequest($prm['mutasi_request_id']);
# HITUNG NILAI #
$totalValue = 0;
foreach ($prm["list_mutasi"] as $item) {
if ($isInventaris) {
if (intval($item['qty_mutasi']) <= 0 || intval($item['qty_mutasi']) > intval($item['qty_available'])) {
$this->sys_error('QTY mutasi melebihi item yang tersedia');
exit;
}
# GET BARCODE IDS FIFO #
$sql_barcode_ids = "SELECT T_BarcodeBarangID,
T_BarcodeBarangStockID,
T_BarcodeBarangNumber
FROM t_barcode_barang
WHERE T_BarcodeBarangIsActive = 'Y'
AND T_BarcodeBarangReceiveOrderPoID = ?
ORDER BY T_BarcodeBarangID ASC";
$qry_barcode_ids = $this->db->query($sql_barcode_ids, [$item["ReceiveOrderPoID"]]);
if (!$qry_barcode_ids) {
$this->sys_error_db("[Error] Query getBarcode", $this->db);
exit;
}
$barcode_rows = $qry_barcode_ids->result_array();
$selected_barcodes = [];
$count = 0;
foreach ($barcode_rows as $b) {
if ($count >= intval($item['qty_mutasi'])) {
break;
}
$selected_barcodes[] = $b;
$count++;
}
$detailItems[] = [
'MutasiRequestDetailID' => $item['MutasiRequestDetailID'],
'MutasiRequestID' => $item['MutasiRequestDetailMutasiRequestID'],
'receive_order_po_id' => $item['ReceiveOrderPoID'],
'receive_order_po_number' => $item['ReceiveOrderPoNumber'],
'item_id' => $item['M_ItemID'],
'itemunit_id' => $item['ItemUnitID'],
'stock_id' => $item['StockID'],
'warehouse_id' => $item['WarehouseID'],
'barcode_ids' => $selected_barcodes,
'qty' => $item['qty_mutasi'],
'book_value' => 1,
'lock_type' => 'INV'
];
$totalValue = 1;
} else {
// ASSET
if (intval($item['qty_mutasi']) != 1) {
$this->sys_error("Qty asset harus 1");
exit;
}
// $asset = getAssetByItemID($item['M_ItemID']);
// $itemBookValue = $asset->BookValue;
// $totalValue = $itemBookValue;
// $detailItems[] = [
// 'item_id' => $item['M_ItemID'],
// 'itemunit_id' => $item['ItemUnitID'],
// 'stock_id' => $item['StockID'],
// 'warehouse_id' => $item['WarehouseID'],
// 'barcode_id' => $item['T_BarcodeBarangID'],
// 'qty' => 1,
// 'book_value' => 1, // nanti diganti nilai buku
// 'lock_type' => 'AST'
// ];
// $totalValue = 1; // atau nilai buku asset
}
}
# UPDATE MUTASI #
$sql_mutasi = "UPDATE mutasi_request SET
MutasiRequestDate = ?,
MutasiRequestItemCategoryID = ?,
MutasiRequestFromBranchID = ?,
MutasiRequestToBranchID = ?,
MutasiRequestTotalValue = ?,
MutasiRequestNote = ?,
MutasiRequestLastUpdated = NOW(),
MutasiRequestUserID = ?
WHERE MutasiRequestID = ?";
$qry_mutasi = $this->db->query($sql_mutasi, [
$prm['mutasi_date'],
$prm['category_id'],
$prm['branch_asal_id'],
$prm['branch_tujuan_id'],
$totalValue,
$prm['note'],
$user['M_UserID'],
$prm['mutasi_request_id']
]);
if (!$qry_mutasi) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] update mutasi request", $this->db);
exit;
}
# check jika detail sudah ada #
$sql_check_detail = "SELECT MutasiRequestDetailID,
MutasiRequestDetailMutasiRequestID
FROM mutasi_request_detail
WHERE MutasiRequestDetailMutasiRequestID = ?
AND MutasiRequestDetailIsActive = 'Y'";
$qry_check_detail = $this->db->query($sql_check_detail, [$prm['mutasi_request_id']]);
if (!$qry_check_detail) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] get list check detail mutasi", $this->db);
exit;
}
$list_detail_check = $qry_check_detail->result_array();
$array_detailID = array_column($list_detail_check, 'MutasiRequestDetailID');
$input_detail = array_column($detailItems, 'MutasiRequestDetailID');
$update_detail = [];
$insert_detail = [];
$delete_detail = [];
foreach ($detailItems as $key => $value) {
if (empty($value['MutasiRequestDetailID'])) {
$insert_detail[] = $value;
continue;
}
if (in_array($value['MutasiRequestDetailID'], $array_detailID)) {
$update_detail[] = $value;
}
}
foreach ($list_detail_check as $key => $value) {
if (!in_array($value['MutasiRequestDetailID'], $input_detail)) {
$delete_detail[] = $value;
}
}
# UPDATE MUTASI DETAIL #
foreach ($update_detail as $k => $v) {
$sql_update_detail = "UPDATE mutasi_request_detail SET
MutasiRequestDetailMutasiRequestID = ?,
MutasiRequestDetailReceiveOrderPoID = ?,
MutasiRequestDetailReceiveOrderPoNumber = ?,
MutasiRequestDetailStockID = ?,
MutasiRequestDetailM_ItemID = ?,
MutasiRequestDetailItemUnitID = ?,
MutasiRequestDetailQty = ?,
MutasiRequestDetailBookValue = ?,
MutasiRequestDetailLastUpdated = NOW(),
MutasiRequestDetailUserID = ?
WHERE MutasiRequestDetailID = ?";
$qry_update_detail = $this->db->query($sql_update_detail, [
$v['MutasiRequestID'],
$v['receive_order_po_id'],
$v['receive_order_po_number'],
$v['stock_id'],
$v['item_id'],
$v['itemunit_id'],
$v['qty'],
$v['book_value'],
$user['M_UserID'],
$v['MutasiRequestDetailID']
]);
if (!$qry_update_detail) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] update mutasi request detail", $this->db);
exit;
}
# cek qty tersedia (inventaris)
if ($v['lock_type'] === 'INV') {
$sqlCheck = "SELECT COUNT(*) AS qty_available
FROM t_barcode_barang b
LEFT JOIN mutasi_stock_lock l
ON l.MutasiStockLockT_BarcodeBarangID = b.T_BarcodeBarangID
AND l.MutasiStockLockStatus = 'ACTIVE'
AND l.MutasiStockLockIsActive = 'Y'
WHERE
b.T_BarcodeBarangReceiveOrderPoID = ?
AND b.T_BarcodeBarangIsActive = 'Y'
AND l.MutasiStockLockID IS NULL
FOR UPDATE";
$row = $this->db->query($sqlCheck, [$v['receive_order_po_id']])->row();
if (!$row || $row->qty_available < $v['qty']) {
$this->db->trans_rollback();
$this->sys_error("Stock tidak mencukupi (sudah di-lock)");
exit;
}
} else if ($v['lock_type'] === 'AST') {
if (empty($v['barcode_id'])) {
$this->db->trans_rollback();
$this->sys_error("Asset wajib memiliki barcode");
exit;
}
}
# tentukan barcode yang di insert, update, delete #
$sql_lock = "SELECT MutasiStockLockT_BarcodeBarangID as T_BarcodeBarangID
FROM mutasi_stock_lock WHERE MutasiStockLockMutasiRequestDetailID = ?";
$row_lock = $this->db->query($sql_lock, [$v['MutasiRequestDetailID']]);
if (!$row_lock) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] get mutasi stock lock", $this->db);
exit;
}
$lock_data = $row_lock->result_array();
$array_barcodeID = array_column($lock_data, 'T_BarcodeBarangID');
$input_barcode = array_column($v['barcode_ids'], 'T_BarcodeBarangID');
$update_barcode = [];
$insert_barcode = [];
$delete_barcode = [];
foreach ($v['barcode_ids'] as $key => $value) {
if (!in_array($value['T_BarcodeBarangID'], $array_barcodeID)) {
$insert_barcode[] = $value;
continue;
}
if (in_array($value['T_BarcodeBarangID'], $array_barcodeID)) {
$update_barcode[] = $value;
}
}
foreach ($lock_data as $key => $value) {
if (!in_array($value['T_BarcodeBarangID'], $input_barcode)) {
$delete_barcode[] = $value;
}
}
# UPDATE STOCK LOCK
foreach ($update_barcode as $k => $ub) {
$sql_update_lock = "UPDATE mutasi_stock_lock SET
MutasiStockLockMutasiRequestID = ?,
MutasiStockLockMutasiRequestDetailID = ?,
MutasiStockLockM_ItemID = ?,
MutasiStockLockStockID = ?,
MutasiStockLockT_BarcodeBarangID = ?,
MutasiStockLockM_BranchID = ?,
MutasiStockLockWarehouseID = ?,
MutasiStockLockQtyLocked = ?,
MutasiStockLockType = ?,
MutasiStockLockLastUpdated = NOW(),
MutasiStockLockUserID = ?
WHERE MutasiStockLockT_BarcodeBarangID = ?";
$qry_update_lock = $this->db->query($sql_update_lock, [
$prm['mutasi_request_id'],
$v['MutasiRequestDetailID'],
$v['item_id'],
$v['stock_id'],
$ub['T_BarcodeBarangID'],
$prm['branch_asal_id'],
$v['warehouse_id'],
1,
$v['lock_type'],
$user['M_UserID'],
$ub['T_BarcodeBarangID']
]);
if (!$qry_update_lock) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] update mutasi stock lock", $this->db);
exit;
}
}
# INSERT STOCK LOCK
foreach ($insert_barcode as $k => $ib) {
$sqlLock = "INSERT INTO mutasi_stock_lock(
MutasiStockLockMutasiRequestID,
MutasiStockLockMutasiRequestDetailID,
MutasiStockLockM_ItemID,
MutasiStockLockStockID,
MutasiStockLockT_BarcodeBarangID,
MutasiStockLockM_BranchID,
MutasiStockLockWarehouseID,
MutasiStockLockQtyLocked,
MutasiStockLockType,
MutasiStockLockStatus,
MutasiStockLockIsActive,
MutasiStockLockCreated,
MutasiStockLockUserID
) VALUES(?,?,?,?,?,?,?,?,?,'ACTIVE','Y',NOW(),?)";
$qryLock = $this->db->query($sqlLock, [
$v['MutasiRequestID'],
$v['MutasiRequestDetailID'],
$v['item_id'],
$v['stock_id'],
$ib['T_BarcodeBarangID'],
$prm['branch_asal_id'],
$v['warehouse_id'],
1,
$v['lock_type'],
$user['M_UserID']
]);
if (!$qryLock) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] insert table stock lock", $this->db);
exit;
}
}
# DELETE STOCK LOCK
foreach ($delete_barcode as $k => $db) {
$sql_delete_lock = "UPDATE mutasi_stock_lock SET
MutasiStockLockStatus = 'INACTIVE',
MutasiStockLockIsActive = 'N',
MutasiStockLockLastUpdated = NOW(),
MutasiStockLockUserID = ?
WHERE MutasiStockLockMutasiRequestDetailID = ?
AND MutasiStockLockT_BarcodeBarangID = ?";
$qry_delete_lock = $this->db->query($sql_delete_lock, [
$user['M_UserID'],
$v['MutasiRequestDetailID'],
$db['T_BarcodeBarangID']
]);
if (!$qry_delete_lock) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] delete mutasi stock lock", $this->db);
exit;
}
}
}
# INSERT MUTASI DETAIL BARU #
foreach ($insert_detail as $k => $v) {
$sql_detail = "INSERT INTO mutasi_request_detail(
MutasiRequestDetailMutasiRequestID,
MutasiRequestDetailReceiveOrderPoID,
MutasiRequestDetailReceiveOrderPoNumber,
MutasiRequestDetailStockID,
MutasiRequestDetailM_ItemID,
MutasiRequestDetailItemUnitID,
MutasiRequestDetailQty,
MutasiRequestDetailBookValue,
MutasiRequestDetailIsActive,
MutasiRequestDetailCreated,
MutasiRequestDetailUserID
) VALUES(?,?,?,?,?,?,?,?,'Y',NOW(),?)";
$qry_detail = $this->db->query($sql_detail, [
$prm['mutasi_request_id'],
$v['receive_order_po_id'],
$v['receive_order_po_number'],
$v['stock_id'],
$v['item_id'],
$v['itemunit_id'],
$v['qty'],
$v['book_value'],
$user['M_UserID']
]);
if (!$qry_detail) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] Re-insert table mutasi request detail", $this->db);
exit;
}
$detail_id = $this->db->insert_id();
# cek qty tersedia (inventaris)
if ($v['lock_type'] === 'INV') {
$sqlCheck = "SELECT COUNT(*) AS qty_available
FROM t_barcode_barang b
LEFT JOIN mutasi_stock_lock l
ON l.MutasiStockLockT_BarcodeBarangID = b.T_BarcodeBarangID
AND l.MutasiStockLockStatus = 'ACTIVE'
AND l.MutasiStockLockIsActive = 'Y'
WHERE
b.T_BarcodeBarangReceiveOrderPoID = ?
AND b.T_BarcodeBarangIsActive = 'Y'
AND l.MutasiStockLockID IS NULL
FOR UPDATE";
$row = $this->db->query($sqlCheck, [$v['receive_order_po_id']])->row();
if (!$row || $row->qty_available < $v['qty']) {
$this->db->trans_rollback();
$this->sys_error("Stock tidak mencukupi (sudah di-lock)");
exit;
}
} else if ($v['lock_type'] === 'AST') {
if (empty($v['barcode_id'])) {
$this->db->trans_rollback();
$this->sys_error("Asset wajib memiliki barcode");
exit;
}
}
# INSERT STOCK LOCK
if (count($v['barcode_ids']) > 0) {
foreach ($v['barcode_ids'] as $b) {
$sqlLock = "INSERT INTO mutasi_stock_lock(
MutasiStockLockMutasiRequestID,
MutasiStockLockMutasiRequestDetailID,
MutasiStockLockM_ItemID,
MutasiStockLockStockID,
MutasiStockLockT_BarcodeBarangID,
MutasiStockLockM_BranchID,
MutasiStockLockWarehouseID,
MutasiStockLockQtyLocked,
MutasiStockLockType,
MutasiStockLockStatus,
MutasiStockLockIsActive,
MutasiStockLockCreated,
MutasiStockLockUserID
) VALUES(?,?,?,?,?,?,?,?,?,'ACTIVE','Y',NOW(),?)";
$qryLock = $this->db->query($sqlLock, [
$prm['mutasi_request_id'],
$detail_id,
$v['item_id'],
$v['stock_id'],
$b['T_BarcodeBarangID'],
$prm['branch_asal_id'],
$v['warehouse_id'],
1,
$v['lock_type'],
$user['M_UserID']
]);
if (!$qryLock) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] insert table stock lock", $this->db);
exit;
}
}
}
}
# DELETE MUTASI DETAIL #
if (count($delete_detail) > 0) {
$delete_id = array_column($delete_detail, 'MutasiRequestDetailID');
$placeholders = implode(', ', array_fill(0, count($delete_id), '?'));
$delete_param = array_merge(array($user['M_UserID']), $delete_id);
$sql_delete_detail = "UPDATE mutasi_request_detail SET
MutasiRequestDetailIsActive = 'N',
MutasiRequestDetailLastUpdated = NOW(),
MutasiRequestDetailUserID = ?
WHERE MutasiRequestDetailID IN ($placeholders)";
$qry_delete_detail = $this->db->query($sql_delete_detail, $delete_param);
if (!$qry_delete_detail) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] delete mutasi request detail", $this->db);
exit;
}
# delete mutasi stock lock
$sql_update_stock_lock = "UPDATE mutasi_stock_lock SET
MutasiStockLockStatus = 'INACTIVE',
MutasiStockLockIsActive = 'N',
MutasiStockLockLastUpdated = NOW(),
MutasiStockLockUserID = ?
WHERE MutasiStockLockMutasiRequestDetailID = ?";
$qry_update_stock_lock = $this->db->query($sql_update_stock_lock, $delete_param);
if (!$qry_update_stock_lock) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] update mutasi stock lock", $this->db);
exit;
}
}
$dataMrAfter = $this->getDataMutasiRequest($prm['mutasi_request_id']);
$this->insertLogMutasiRequest($prm['mutasi_request_id'], 'EDIT', $dataMrBefore, $dataMrAfter, $user['M_UserID'], "Edit data mutasi request ID : {$prm['mutasi_request_id']}");
$this->insertUserActivity('MR', "Edit data mutasi request ID : {$prm['mutasi_request_id']}", 'EDIT', $prm['mutasi_request_id'], $user['M_UserID']);
$this->db->trans_commit();
$this->sys_ok("Update mutasi successfully");
} catch (Exception $exc) {
$message = $exc->getMessage();
$this->sys_error($message);
}
}
function deleteMutasi()
{
try {
if (!$this->isLogin) {
$this->sys_error("invalid token");
exit;
}
$this->db->trans_begin();
$prm = $this->sys_input;
$user = $this->sys_user;
$mutasiRequestID = $prm['mutasiRequestID'];
# get data before for log #
$dataMrBefore = $this->getDataMutasiRequest($mutasiRequestID);
$sql_mutasi = "UPDATE mutasi_request SET
MutasiRequestIsActive = 'N',
MutasiRequestLastUpdated = NOW(),
MutasiRequestUserID = ?
WHERE MutasiRequestID = ?";
$qry_mutasi = $this->db->query($sql_mutasi, [
$user['M_UserID'],
$mutasiRequestID
]);
if (!$qry_mutasi) {
$this->db->trans_rollback();
$this->sys_error_db('[Error] delete mutasi request', $this->db);
exit;
}
$sql_mutasi_detail = "UPDATE mutasi_request_detail SET
MutasiRequestDetailIsActive = 'N',
MutasiRequestDetailLastUpdated = NOW(),
MutasiRequestDetailUserID = ?
WHERE MutasiRequestDetailMutasiRequestID = ?";
$qry_mutasi_detail = $this->db->query($sql_mutasi_detail, [
$user['M_UserID'],
$mutasiRequestID
]);
if (!$qry_mutasi_detail) {
$this->db->trans_rollback();
$this->sys_error_db('[Error] delete mutasi detail', $this->db);
exit;
}
$sql_stock_lock = "UPDATE mutasi_stock_lock SET
MutasiStockLockStatus = 'INACTIVE',
MutasiStockLockIsActive = 'N',
MutasiStockLockLastUpdated = NOW(),
MutasiStockLockUserID = ?
WHERE MutasiStockLockMutasiRequestID = ?";
$qry_stock_lock = $this->db->query($sql_stock_lock, [
$user['M_UserID'],
$mutasiRequestID
]);
if (!$qry_stock_lock) {
$this->db->trans_rollback();
$this->sys_error_db('[Error] mutasi stock lock', $this->db);
exit;
}
$dataMrAfter = $this->getDataMutasiRequest($mutasiRequestID);
$this->insertLogMutasiRequest($mutasiRequestID, 'DELETE', $dataMrBefore, $dataMrAfter, $user['M_UserID'], "Delete data mutasi request ID : {$mutasiRequestID}");
$this->insertUserActivity('MR', "Delete data mutasi request ID : {$mutasiRequestID}", 'DELETE', $mutasiRequestID, $user['M_UserID']);
$this->db->trans_commit();
$this->sys_ok("Delete Request mutasi successfully");
} catch (Exception $exc) {
$message = $exc->getMessage();
$this->sys_error($message);
}
}
//
private function insertUserActivity(
$code,
$user_desc = '',
$status,
$reff_id,
$userId
) {
$sql_log = "INSERT INTO user_activity(
UserActivityCode,
UserActivityStatus,
UserActivityDescription,
UserActivityRefID,
UserActivityUserID,
UserActivityCreated
) VALUES(?,?,?,?,?,NOW())";
$qry_log = $this->db->query($sql_log, [
$code,
$status,
$user_desc,
$reff_id,
$userId
]);
if (!$qry_log) {
$this->db->trans_rollback();
$this->sys_error_db("insert log", $this->db);
exit;
}
}
private function insertLogMutasiRequest(
$id,
$type,
$dataBefore,
$dataAfter,
$userID,
$desc = ''
) {
$sql = "INSERT INTO acc_one_log.mutasi_request_log(
MutasiRequestLogMutasiRequestID,
MutasiRequestLogType,
MutasiRequestLogDesc,
MutasiRequestLogJsonBefore,
MutasiRequestLogJsonAfter,
MutasiRequestLogUserID,
MutasiRequestLogCreated
) VALUES(?,?,?,?,?,?,NOW())";
$qry = $this->db->query($sql, [
$id,
$type,
$desc,
!empty($dataBefore) ? json_encode($dataBefore) : '',
!empty($dataAfter) ? json_encode($dataAfter) : '',
$userID
]);
if (!$qry) {
$this->db->trans_rollback();
$this->sys_error_db("[Error] insert log mutasi request", $this->db);
exit;
}
}
}