Compare commits
14 Commits
b03ae67f75
...
feat-repor
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0823867277 | ||
|
|
7d8dd0f660 | ||
|
|
76258c7c61 | ||
|
|
578371dc01 | ||
|
|
e186b5f491 | ||
|
|
eac89f6ddd | ||
|
|
67441e9666 | ||
|
|
0236c44349 | ||
|
|
eee6993679 | ||
|
|
57642e5277 | ||
|
|
9e7493c18b | ||
|
|
1ace1600ce | ||
|
|
c0cfc3ea88 | ||
|
|
a2f3509d78 |
@@ -1,10 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class InventarisCoaMapping extends MY_Controller
|
class InventarisCoaMapping extends MY_Controller {
|
||||||
{
|
|
||||||
var $db;
|
var $db;
|
||||||
public function index()
|
public function index() {
|
||||||
{
|
|
||||||
echo "Inventaris COA Mapping API";
|
echo "Inventaris COA Mapping API";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,226 +11,8 @@ class InventarisCoaMapping extends MY_Controller
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
## QUERY ##
|
|
||||||
public function getListCoa()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if (!$this->isLogin) {
|
|
||||||
throw new Exception('Invalid token');
|
|
||||||
}
|
|
||||||
|
|
||||||
$para = $this->sys_input;
|
|
||||||
$keyword = "%" . $para['keyword'] . "%";
|
|
||||||
|
|
||||||
$sql = "SELECT
|
|
||||||
coaID,
|
|
||||||
coaAccountNo,
|
|
||||||
coaDescription
|
|
||||||
FROM coa
|
|
||||||
WHERE coaIsInput = 'Y'
|
|
||||||
AND (
|
|
||||||
coaDescription LIKE ?
|
|
||||||
OR coaAccountNo LIKE ?
|
|
||||||
)
|
|
||||||
AND coaIsActive = 'Y'
|
|
||||||
LIMIT 15";
|
|
||||||
$que = $this->db->query($sql, [$keyword, $keyword]);
|
|
||||||
if (!$que) {
|
|
||||||
throw new Exception('failed to query data inventaris gol', 1);
|
|
||||||
}
|
|
||||||
$data = $que->result_array();
|
|
||||||
|
|
||||||
$this->sys_ok($data);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$msg = '[Error] ' . $e->getMessage();
|
|
||||||
$code = $e->getCode();
|
|
||||||
if ($code == 0) {
|
|
||||||
$this->sys_error($msg);
|
|
||||||
} else {
|
|
||||||
$this->sys_error_db($msg);
|
|
||||||
}
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getListInventarisGol()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if (!$this->isLogin) {
|
|
||||||
throw new Exception('Invalid token');
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql = "SELECT
|
|
||||||
M_InventarisGolID,
|
|
||||||
M_InventarisGolCode,
|
|
||||||
M_InventarisGolName
|
|
||||||
FROM m_inventaris_gol gol
|
|
||||||
WHERE gol.M_InventarisGolIsActive = 'Y'
|
|
||||||
AND NOT EXISTS (
|
|
||||||
SELECT 1
|
|
||||||
FROM m_inventaris_coa_mapping m
|
|
||||||
WHERE m.M_InventarisCoaMappingM_InventarisGolID = gol.M_InventarisGolID
|
|
||||||
AND m.M_InventarisCoaMappingIsActive = 'Y'
|
|
||||||
);";
|
|
||||||
$que = $this->db->query($sql);
|
|
||||||
if (!$que) {
|
|
||||||
throw new Exception('failed to query data inventaris gol', 1);
|
|
||||||
}
|
|
||||||
$data = $que->result_array();
|
|
||||||
|
|
||||||
$output = [
|
|
||||||
'records' => $data,
|
|
||||||
'total' => count($data)
|
|
||||||
];
|
|
||||||
|
|
||||||
$this->sys_ok($output);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$msg = '[Error] ' . $e->getMessage();
|
|
||||||
$code = $e->getCode();
|
|
||||||
if ($code == 0) {
|
|
||||||
$this->sys_error($msg);
|
|
||||||
} else {
|
|
||||||
$this->sys_error_db($msg);
|
|
||||||
}
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getListInventorygolMapping()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if (!$this->isLogin) {
|
|
||||||
throw new Exception('invalid token');
|
|
||||||
}
|
|
||||||
|
|
||||||
$para = $this->sys_input;
|
|
||||||
$keyword = "%" . $para['keyword'] . "%";
|
|
||||||
|
|
||||||
$limit = 10;
|
|
||||||
$offset = 0;
|
|
||||||
if ($para['currpage'] > 0) {
|
|
||||||
$offset = ($para['currpage'] - 1) * $limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql = "SELECT
|
|
||||||
M_InventarisGolID,
|
|
||||||
M_InventarisGolCode,
|
|
||||||
M_InventarisGolName,
|
|
||||||
M_InventarisCoaMappingID,
|
|
||||||
M_InventarisCoaMappingCoaInventarisID,
|
|
||||||
coaInv.coaAccountNo AS CoaInventarisAccountNo,
|
|
||||||
coaInv.coaDescription AS CoaInventarisDescription,
|
|
||||||
M_InventarisCoaMappingCoaHutangID,
|
|
||||||
coaHtg.coaAccountNo AS CoaHutangAccountNo,
|
|
||||||
coaHtg.coaDescription AS CoaHutangDescription,
|
|
||||||
M_InventarisCoaMappingCoaBebanPenyusutanID,
|
|
||||||
coaBbn.coaAccountNo AS CoaBebanPenyusutanAccountNo,
|
|
||||||
coaBbn.coaDescription AS CoaBebanPenyusutanDescription,
|
|
||||||
M_InventarisCoaMappingCoaAkumulasiPenyusutanID,
|
|
||||||
coaAkm.coaAccountNo AS CoaAkumulasiPenyusutanAccountNo,
|
|
||||||
coaAkm.coaDescription AS CoaAkumulasiPenyusutanDescription,
|
|
||||||
M_InventarisCoaMappingCoaLabaPelepasanID,
|
|
||||||
coaLab.coaAccountNo AS CoaLabaPelepasanAccountNo,
|
|
||||||
coaLab.coaDescription AS CoaLabaPelepasanDescription,
|
|
||||||
M_InventarisCoaMappingCoaRugiPelepasanID,
|
|
||||||
coaRug.coaAccountNo AS CoaRugiPelepasanAccountNo,
|
|
||||||
coaRug.coaDescription AS CoaRugiPelepasanDescription
|
|
||||||
FROM m_inventaris_gol
|
|
||||||
JOIN m_inventaris_coa_mapping
|
|
||||||
ON M_InventarisCoaMappingM_InventarisGolID = M_InventarisGolID
|
|
||||||
AND M_InventarisCoaMappingIsActive = 'Y'
|
|
||||||
AND M_InventarisGolIsActive = 'Y'
|
|
||||||
AND M_InventarisGolName LIKE ?
|
|
||||||
LEFT JOIN coa AS coaInv
|
|
||||||
ON M_InventarisCoaMappingCoaInventarisID = coaInv.coaID
|
|
||||||
LEFT JOIN coa AS coaHtg
|
|
||||||
ON M_InventarisCoaMappingCoaHutangID = coaHtg.coaID
|
|
||||||
LEFT JOIN coa AS coaBbn
|
|
||||||
ON M_InventarisCoaMappingCoaBebanPenyusutanID = coaBbn.coaID
|
|
||||||
LEFT JOIN coa AS coaAkm
|
|
||||||
ON M_InventarisCoaMappingCoaAkumulasiPenyusutanID = coaAkm.coaID
|
|
||||||
LEFT JOIN coa AS coaLab
|
|
||||||
ON M_InventarisCoaMappingCoaLabaPelepasanID = coaLab.coaID
|
|
||||||
LEFT JOIN coa AS coaRug
|
|
||||||
ON M_InventarisCoaMappingCoaRugiPelepasanID = coaRug.coaID
|
|
||||||
WHERE M_InventarisGolIsActive = 'Y'";
|
|
||||||
|
|
||||||
$sql_data = $sql . " ORDER BY M_InventarisGolID LIMIT ? OFFSET ? ";
|
|
||||||
$que = $this->db->query($sql_data, [
|
|
||||||
$keyword,
|
|
||||||
$limit,
|
|
||||||
$offset
|
|
||||||
]);
|
|
||||||
if (!$que) {
|
|
||||||
throw new Exception('failed to query data mapping coa inventaris golongan', 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql_total = "SELECT COUNT(*) AS total FROM ($sql) AS x";
|
|
||||||
$que_total = $this->db->query($sql_total, [$keyword]);
|
|
||||||
if (!$que_total) {
|
|
||||||
throw new Exception('failed to get total rows data', 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->sys_ok([
|
|
||||||
"records" => $que->result_array(),
|
|
||||||
"total" => $que_total->row_array()['total']
|
|
||||||
]);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$msg = '[Error] ' . $e->getMessage();
|
|
||||||
$code = $e->getCode();
|
|
||||||
if ($code == 0) {
|
|
||||||
$this->sys_error($msg);
|
|
||||||
} else {
|
|
||||||
$this->sys_error_db($msg);
|
|
||||||
}
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getInvCoaMappingDetail()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if (!$this->isLogin) {
|
|
||||||
$this->sys_error("invalid token");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$para = $this->sys_input;
|
|
||||||
|
|
||||||
$sql = "SELECT
|
|
||||||
M_InventarisCoaMappingID,
|
|
||||||
M_InventarisCoaMappingM_InventarisGolID,
|
|
||||||
M_InventarisCoaMappingCoaInventarisID,
|
|
||||||
M_InventarisCoaMappingCoaHutangID,
|
|
||||||
M_InventarisCoaMappingCoaPembelianID,
|
|
||||||
M_InventarisCoaMappingCoaBebanPenyusutanID,
|
|
||||||
M_InventarisCoaMappingCoaAkumulasiPenyusutanID,
|
|
||||||
M_InventarisCoaMappingCoaLabaPelepasanID,
|
|
||||||
M_InventarisCoaMappingCoaRugiPelepasanID,
|
|
||||||
M_InventarisCoaMappingCreatedUserID,
|
|
||||||
M_InventarisCoaMappingCreated,
|
|
||||||
M_InventarisCoaMappingLastUpdated
|
|
||||||
FROM m_inventaris_coa_mapping
|
|
||||||
WHERE M_InventarisCoaMappingIsActive = 'Y'
|
|
||||||
AND M_InventarisCoaMappingID = ?";
|
|
||||||
$query = $this->db->query($sql, [$para['M_InventarisCoaMappingID']]);
|
|
||||||
if (!$query) {
|
|
||||||
$this->sys_error_db("[Error] get data m_inventaris_coa_mapping");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
$data = $query->row_array();
|
|
||||||
|
|
||||||
$this->sys_ok($data);
|
|
||||||
} catch (Exception $exc) {
|
|
||||||
$msg = $exc->getMessage();
|
|
||||||
$this->sys_error($msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
## MUTATIONS ##
|
## MUTATIONS ##
|
||||||
public function createInvCoaMapping()
|
public function createInvCoaMapping() {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
if (!$this->isLogin) {
|
if (!$this->isLogin) {
|
||||||
$this->sys_error("invalid token");
|
$this->sys_error("invalid token");
|
||||||
@@ -284,8 +64,48 @@ class InventarisCoaMapping extends MY_Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function editInvCoaMapping()
|
## QUERY ##
|
||||||
{
|
public function getInvCoaMapping() {
|
||||||
|
try {
|
||||||
|
if (!$this->isLogin) {
|
||||||
|
$this->sys_error("invalid token");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$para = $this->sys_input;
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
M_InventarisCoaMappingID,
|
||||||
|
M_InventarisCoaMappingM_InventarisGolID,
|
||||||
|
M_InventarisCoaMappingCoaInventarisID,
|
||||||
|
M_InventarisCoaMappingCoaHutangID,
|
||||||
|
M_InventarisCoaMappingCoaPembelianID,
|
||||||
|
M_InventarisCoaMappingCoaBebanPenyusutanID,
|
||||||
|
M_InventarisCoaMappingCoaAkumulasiPenyusutanID,
|
||||||
|
M_InventarisCoaMappingCoaLabaPelepasanID,
|
||||||
|
M_InventarisCoaMappingCoaRugiPelepasanID,
|
||||||
|
M_InventarisCoaMappingCreatedUserID,
|
||||||
|
M_InventarisCoaMappingCreated,
|
||||||
|
M_InventarisCoaMappingLastUpdated
|
||||||
|
FROM m_inventaris_coa_mapping
|
||||||
|
WHERE M_InventarisCoaMappingIsActive = 'Y'
|
||||||
|
AND M_InventarisCoaMappingID = ?";
|
||||||
|
$query = $this->db->query($sql, [$para['M_InventarisCoaMappingID']]);
|
||||||
|
if (!$query) {
|
||||||
|
$this->sys_error_db("[Error] get data m_inventaris_coa_mapping");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$data = $query->row_array();
|
||||||
|
|
||||||
|
$this->sys_ok($data);
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$msg = $exc->getMessage();
|
||||||
|
$this->sys_error($msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## MUTATIONS ##
|
||||||
|
public function editInvCoaMapping() {
|
||||||
try {
|
try {
|
||||||
if (!$this->isLogin) {
|
if (!$this->isLogin) {
|
||||||
$this->sys_error("invalid token");
|
$this->sys_error("invalid token");
|
||||||
@@ -334,8 +154,7 @@ class InventarisCoaMapping extends MY_Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteInvCoaMapping()
|
public function deleteInvCoaMapping() {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
if (!$this->isLogin) {
|
if (!$this->isLogin) {
|
||||||
$this->sys_error("invalid token");
|
$this->sys_error("invalid token");
|
||||||
@@ -366,129 +185,8 @@ class InventarisCoaMapping extends MY_Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
## QUERY ITEM ##
|
|
||||||
public function getListItemInventaris()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if (!$this->isLogin) {
|
|
||||||
throw new Exception('Invalid token');
|
|
||||||
}
|
|
||||||
|
|
||||||
$para = $this->sys_input;
|
|
||||||
|
|
||||||
$sql = "SELECT
|
|
||||||
M_ItemID,
|
|
||||||
M_ItemCode,
|
|
||||||
M_ItemDesc,
|
|
||||||
M_ItemM_InventarisGolID AS itemGolID,
|
|
||||||
IFNULL(M_InventarisItemCoaMappingID, 0) AS itemCoaMapID,
|
|
||||||
M_InventarisItemCoaMappingCoaInventarisID,
|
|
||||||
coaInv.coaAccountNo AS CoaInventarisAccountNo,
|
|
||||||
coaInv.coaDescription AS CoaInventarisDescription,
|
|
||||||
M_InventarisItemCoaMappingCoaHutangID,
|
|
||||||
coaHtg.coaAccountNo AS CoaHutangAccountNo,
|
|
||||||
coaHtg.coaDescription AS CoaHutangDescription,
|
|
||||||
M_InventarisItemCoaMappingCoaBebanPenyusutanID,
|
|
||||||
coaBbn.coaAccountNo AS CoaBebanPenyusutanAccountNo,
|
|
||||||
coaBbn.coaDescription AS CoaBebanPenyusutanDescription,
|
|
||||||
M_InventarisItemCoaMappingCoaAkumulasiPenyusutanID,
|
|
||||||
coaAkm.coaAccountNo AS CoaAkumulasiPenyusutanAccountNo,
|
|
||||||
coaAkm.coaDescription AS CoaAkumulasiPenyusutanDescription,
|
|
||||||
M_InventarisItemCoaMappingCoaLabaPelepasanID,
|
|
||||||
coaLab.coaAccountNo AS CoaLabaPelepasanAccountNo,
|
|
||||||
coaLab.coaDescription AS CoaLabaPelepasanDescription,
|
|
||||||
M_InventarisItemCoaMappingCoaRugiPelepasanID,
|
|
||||||
coaRug.coaAccountNo AS CoaRugiPelepasanAccountNo,
|
|
||||||
coaRug.coaDescription AS CoaRugiPelepasanDescription
|
|
||||||
FROM m_item
|
|
||||||
LEFT JOIN m_inventaris_item_coa_mapping
|
|
||||||
ON M_ItemID = M_InventarisItemCoaMappingM_ItemID
|
|
||||||
AND M_InventarisItemCoaMappingIsActive = 'Y'
|
|
||||||
LEFT JOIN coa AS coaInv
|
|
||||||
ON M_InventarisItemCoaMappingCoaInventarisID = coaInv.coaID
|
|
||||||
LEFT JOIN coa AS coaHtg
|
|
||||||
ON M_InventarisItemCoaMappingCoaHutangID = coaHtg.coaID
|
|
||||||
LEFT JOIN coa AS coaBbn
|
|
||||||
ON M_InventarisItemCoaMappingCoaBebanPenyusutanID = coaBbn.coaID
|
|
||||||
LEFT JOIN coa AS coaAkm
|
|
||||||
ON M_InventarisItemCoaMappingCoaAkumulasiPenyusutanID = coaAkm.coaID
|
|
||||||
LEFT JOIN coa AS coaLab
|
|
||||||
ON M_InventarisItemCoaMappingCoaLabaPelepasanID = coaLab.coaID
|
|
||||||
LEFT JOIN coa AS coaRug
|
|
||||||
ON M_InventarisItemCoaMappingCoaRugiPelepasanID = coaRug.coaID
|
|
||||||
WHERE M_ItemItem_CategoryID = 2
|
|
||||||
AND M_ItemM_InventarisGolID = ?
|
|
||||||
AND M_ItemIsActive = 'Y'";
|
|
||||||
$que = $this->db->query($sql, [
|
|
||||||
$para['golID']
|
|
||||||
]);
|
|
||||||
if (!$que) {
|
|
||||||
throw new Exception('failed to query data inventaris gol', 1);
|
|
||||||
}
|
|
||||||
$data = $que->result_array();
|
|
||||||
|
|
||||||
$output = [
|
|
||||||
'records' => $data,
|
|
||||||
'total' => count($data)
|
|
||||||
];
|
|
||||||
|
|
||||||
$this->sys_ok($output);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$msg = '[Error] ' . $e->getMessage();
|
|
||||||
$code = $e->getCode();
|
|
||||||
if ($code == 0) {
|
|
||||||
$this->sys_error($msg);
|
|
||||||
} else {
|
|
||||||
$this->sys_error_db($msg);
|
|
||||||
}
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getInvItemCoaMapping()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if (!$this->isLogin) {
|
|
||||||
$this->sys_error("invalid token");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$para = $this->sys_input;
|
|
||||||
|
|
||||||
$sql = "SELECT
|
|
||||||
M_InventarisItemCoaMappingID,
|
|
||||||
M_InventarisItemCoaMappingM_ItemID,
|
|
||||||
M_InventarisItemCoaMappingCoaInventarisID,
|
|
||||||
M_InventarisItemCoaMappingCoaHutangID,
|
|
||||||
M_InventarisItemCoaMappingCoaPembelianID,
|
|
||||||
M_InventarisItemCoaMappingCoaBebanPenyusutanID,
|
|
||||||
M_InventarisItemCoaMappingCoaAkumulasiPenyusutanID,
|
|
||||||
M_InventarisItemCoaMappingCoaLabaPelepasanID,
|
|
||||||
M_InventarisItemCoaMappingCoaRugiPelepasanID,
|
|
||||||
M_InventarisItemCoaMappingCreatedUserID,
|
|
||||||
M_InventarisItemCoaMappingCreated,
|
|
||||||
M_InventarisItemCoaMappingLastUpdated
|
|
||||||
FROM m_inventaris_item_coa_mapping
|
|
||||||
WHERE M_InventarisItemCoaMappingIsActive = 'Y'
|
|
||||||
AND M_InventarisItemCoaMappingID = ?";
|
|
||||||
$query = $this->db->query($sql, [$para['M_InventarisItemCoaMappingID']]);
|
|
||||||
if (!$query) {
|
|
||||||
$this->sys_error_db("[Error] get data m_inventaris_item_coa_mapping");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
$data = $query->row_array();
|
|
||||||
|
|
||||||
$this->sys_ok($data);
|
|
||||||
} catch (Exception $exc) {
|
|
||||||
$msg = $exc->getMessage();
|
|
||||||
$this->sys_error($msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
## MUTATIONS ITEM ##
|
## MUTATIONS ITEM ##
|
||||||
public function createInvItemCoaMapping()
|
public function createInvItemCoaMapping() {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
if (!$this->isLogin) {
|
if (!$this->isLogin) {
|
||||||
$this->sys_error("invalid token");
|
$this->sys_error("invalid token");
|
||||||
@@ -533,15 +231,55 @@ class InventarisCoaMapping extends MY_Controller
|
|||||||
$insertID = $this->db->insert_id();
|
$insertID = $this->db->insert_id();
|
||||||
|
|
||||||
$this->db->trans_commit();
|
$this->db->trans_commit();
|
||||||
$this->sys_ok("[Success] insert coa item");
|
$this->sys_ok($insertID);
|
||||||
} catch (Exception $exc) {
|
} catch (Exception $exc) {
|
||||||
$msg = $exc->getMessage();
|
$msg = $exc->getMessage();
|
||||||
$this->sys_error($msg);
|
$this->sys_error($msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function editInvItemCoaMapping()
|
## QUERY ITEM ##
|
||||||
{
|
public function getInvItemCoaMapping() {
|
||||||
|
try {
|
||||||
|
if (!$this->isLogin) {
|
||||||
|
$this->sys_error("invalid token");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$para = $this->sys_input;
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
M_InventarisItemCoaMappingID,
|
||||||
|
M_InventarisItemCoaMappingM_ItemID,
|
||||||
|
M_InventarisItemCoaMappingCoaInventarisID,
|
||||||
|
M_InventarisItemCoaMappingCoaHutangID,
|
||||||
|
M_InventarisItemCoaMappingCoaPembelianID,
|
||||||
|
M_InventarisItemCoaMappingCoaBebanPenyusutanID,
|
||||||
|
M_InventarisItemCoaMappingCoaAkumulasiPenyusutanID,
|
||||||
|
M_InventarisItemCoaMappingCoaLabaPelepasanID,
|
||||||
|
M_InventarisItemCoaMappingCoaRugiPelepasanID,
|
||||||
|
M_InventarisItemCoaMappingCreatedUserID,
|
||||||
|
M_InventarisItemCoaMappingCreated,
|
||||||
|
M_InventarisItemCoaMappingLastUpdated
|
||||||
|
FROM m_inventaris_item_coa_mapping
|
||||||
|
WHERE M_InventarisItemCoaMappingIsActive = 'Y'
|
||||||
|
AND M_InventarisItemCoaMappingID = ?";
|
||||||
|
$query = $this->db->query($sql, [$para['M_InventarisItemCoaMappingID']]);
|
||||||
|
if (!$query) {
|
||||||
|
$this->sys_error_db("[Error] get data m_inventaris_item_coa_mapping");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$data = $query->row_array();
|
||||||
|
|
||||||
|
$this->sys_ok($data);
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$msg = $exc->getMessage();
|
||||||
|
$this->sys_error($msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## MUTATIONS ITEM ##
|
||||||
|
public function editInvItemCoaMapping() {
|
||||||
try {
|
try {
|
||||||
if (!$this->isLogin) {
|
if (!$this->isLogin) {
|
||||||
$this->sys_error("invalid token");
|
$this->sys_error("invalid token");
|
||||||
@@ -590,8 +328,7 @@ class InventarisCoaMapping extends MY_Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteInvItemCoaMapping()
|
public function deleteInvItemCoaMapping() {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
if (!$this->isLogin) {
|
if (!$this->isLogin) {
|
||||||
$this->sys_error("invalid token");
|
$this->sys_error("invalid token");
|
||||||
|
|||||||
@@ -496,7 +496,6 @@ class Fakturv4 extends MY_Controller
|
|||||||
ELSE ''
|
ELSE ''
|
||||||
END as WarehouseName,
|
END as WarehouseName,
|
||||||
ReceiveOrderPoID,
|
ReceiveOrderPoID,
|
||||||
ReceiveOrderPoTypePurchase,
|
|
||||||
PurchaseOrderItemCategoryID
|
PurchaseOrderItemCategoryID
|
||||||
FROM supplier_invoice
|
FROM supplier_invoice
|
||||||
JOIN supplier_invoice_detail ON SupplierInvoiceID = SupplierInvoiceDetailSupplierInvoiceID
|
JOIN supplier_invoice_detail ON SupplierInvoiceID = SupplierInvoiceDetailSupplierInvoiceID
|
||||||
@@ -589,11 +588,12 @@ class Fakturv4 extends MY_Controller
|
|||||||
'P'
|
'P'
|
||||||
) AS DiscountType,
|
) AS DiscountType,
|
||||||
SupplierInvoiceReceiveOrderPoID,
|
SupplierInvoiceReceiveOrderPoID,
|
||||||
ReceiveOrderPoNumber,
|
ReceiveOrderPoNumber
|
||||||
ReceiveOrderPoTypePurchase AS typePurchase
|
|
||||||
FROM supplier_invoice
|
FROM supplier_invoice
|
||||||
JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
||||||
JOIN receive_order_po ON ReceiveOrderPoID = SupplierInvoiceReceiveOrderPoID
|
JOIN receive_order_po ON ReceiveOrderPoID = SupplierInvoiceReceiveOrderPoID
|
||||||
|
-- JOIN purchase_order ON SupplierInvoicePurchaseOrderID = PurchaseOrderID
|
||||||
|
-- AND PurchaseOrderIsActive = 'Y'
|
||||||
WHERE SupplierInvoiceIsActive = 'Y'
|
WHERE SupplierInvoiceIsActive = 'Y'
|
||||||
AND SupplierInvoiceID = ?";
|
AND SupplierInvoiceID = ?";
|
||||||
$que = $this->db->query($sql, $para['SInvoiceID']);
|
$que = $this->db->query($sql, $para['SInvoiceID']);
|
||||||
@@ -601,7 +601,6 @@ class Fakturv4 extends MY_Controller
|
|||||||
$this->sys_error_db('[Error] get detail data invoice');
|
$this->sys_error_db('[Error] get detail data invoice');
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$data = $que->row_array();
|
|
||||||
|
|
||||||
$sqldet = "SELECT
|
$sqldet = "SELECT
|
||||||
SupplierInvoiceDetailID,
|
SupplierInvoiceDetailID,
|
||||||
@@ -637,30 +636,7 @@ class Fakturv4 extends MY_Controller
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($data['typePurchase']) && $data['typePurchase'] == 'aset') {
|
$data = $que->result_array()[0];
|
||||||
$sql_dp = "SELECT
|
|
||||||
IFNULL(SupplierDownpaymentAmount, 0) AS dp_amount
|
|
||||||
FROM supplier_invoice
|
|
||||||
JOIN receive_order_po
|
|
||||||
ON ReceiveOrderPoID = SupplierInvoiceReceiveOrderPoID
|
|
||||||
JOIN purchase_order_asset_contract
|
|
||||||
ON PurchaseOrderAssetContractReceiveOrderPoID = ReceiveOrderPoID
|
|
||||||
AND PurchaseOrderAssetContractIsActive = 'Y'
|
|
||||||
JOIN supplier_downpayment
|
|
||||||
ON SupplierDownpaymentPurchasOrderID = PurchaseOrderAssetContractPurchaseOrderID
|
|
||||||
AND SupplierDownpaymentIsActive = 'Y'
|
|
||||||
WHERE SupplierInvoiceID = ?";
|
|
||||||
$que_dp = $this->db->query($sql_dp, [
|
|
||||||
$para['SInvoiceID']
|
|
||||||
]);
|
|
||||||
if (!$que_dp) {
|
|
||||||
$this->sys_error_db("[Error] get info contract asset");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
$dp_amount = $que_dp->row_array()['dp_amount'];
|
|
||||||
$data['dp_amount'] = $dp_amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['detail'] = $quedet->result_array();
|
$data['detail'] = $quedet->result_array();
|
||||||
|
|
||||||
$result = $data;
|
$result = $data;
|
||||||
@@ -1341,8 +1317,7 @@ class Fakturv4 extends MY_Controller
|
|||||||
supplier_invoice_detail.*,
|
supplier_invoice_detail.*,
|
||||||
ReceiveOrderPoNumber,
|
ReceiveOrderPoNumber,
|
||||||
ReceiveOrderPoM_BranchCode,
|
ReceiveOrderPoM_BranchCode,
|
||||||
ReceiveOrderPoS_RegionalID,
|
ReceiveOrderPoS_RegionalID
|
||||||
ReceiveOrderPoTypePurchase AS typePurchase
|
|
||||||
FROM supplier_invoice
|
FROM supplier_invoice
|
||||||
JOIN supplier_invoice_detail ON SupplierInvoiceDetailSupplierInvoiceID = SupplierInvoiceID
|
JOIN supplier_invoice_detail ON SupplierInvoiceDetailSupplierInvoiceID = SupplierInvoiceID
|
||||||
AND SupplierInvoiceDetailIsActive = 'Y'
|
AND SupplierInvoiceDetailIsActive = 'Y'
|
||||||
@@ -1478,6 +1453,7 @@ class Fakturv4 extends MY_Controller
|
|||||||
$coapph = $quepph->result_array()[0];
|
$coapph = $quepph->result_array()[0];
|
||||||
|
|
||||||
$pphval = doubleval($invoice[0]['SupplierInvoiceTaxAmountPph']);
|
$pphval = doubleval($invoice[0]['SupplierInvoiceTaxAmountPph']);
|
||||||
|
|
||||||
if ($pphval > 0.00) {
|
if ($pphval > 0.00) {
|
||||||
$insertpph = $this->InsertJurnalTx(
|
$insertpph = $this->InsertJurnalTx(
|
||||||
$jurnalID,
|
$jurnalID,
|
||||||
@@ -1489,22 +1465,22 @@ class Fakturv4 extends MY_Controller
|
|||||||
);
|
);
|
||||||
if (!$insertpph['status']) {
|
if (!$insertpph['status']) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
$this->sys_error_db($insertpph['msg']);
|
$this->sys_error_db($insertpajak['msg']);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# insert shipping cost ke jurnal #
|
# insert shipping cost ke jurnal #
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
if ($ship_cost > 0.00) {
|
$queryshipcost = $this->db->query($sqlcoa, ['5320700001']);
|
||||||
$queryshipcost = $this->db->query($sqlcoa, ['5320700001']);
|
if (!$queryshipcost) {
|
||||||
if (!$queryshipcost) {
|
$this->db->trans_rollback();
|
||||||
$this->db->trans_rollback();
|
$this->sys_error_db("[Error] get coa cost ");
|
||||||
$this->sys_error_db("[Error] get coa cost ");
|
exit;
|
||||||
exit;
|
}
|
||||||
}
|
$coashipcost = $queryshipcost->result_array()[0];
|
||||||
$coashipcost = $queryshipcost->result_array()[0];
|
|
||||||
|
|
||||||
|
if ($ship_cost > 0.00) {
|
||||||
$insertcost = $this->InsertJurnalTx(
|
$insertcost = $this->InsertJurnalTx(
|
||||||
$jurnalID,
|
$jurnalID,
|
||||||
$coashipcost['coaID'],
|
$coashipcost['coaID'],
|
||||||
@@ -1520,63 +1496,6 @@ class Fakturv4 extends MY_Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Insert jurnal tx for down payment asset */
|
|
||||||
// ----------------------------------------------------------------------------------------
|
|
||||||
if (isset($invoice[0]['typePurchase']) && $invoice[0]['typePurchase'] == 'aset') {
|
|
||||||
$sql_dpasset = "SELECT
|
|
||||||
PurchaseOrderAssetContractID,
|
|
||||||
PurchaseOrderAssetContractName,
|
|
||||||
SupplierDownpaymentAmount,
|
|
||||||
coaID,
|
|
||||||
coaDescription
|
|
||||||
FROM purchase_order_asset_contract
|
|
||||||
JOIN purchase_order ON PurchaseOrderID = PurchaseOrderAssetContractPurchaseOrderID
|
|
||||||
JOIN supplier_downpayment
|
|
||||||
ON SupplierDownpaymentPurchasOrderID = PurchaseOrderID
|
|
||||||
AND SupplierDownpaymentIsActive = 'Y'
|
|
||||||
JOIN purchase_order_detail
|
|
||||||
ON PurchaseOrderID = PurchaseOrderDetailPurchaseOrderID
|
|
||||||
AND PurchaseOrderDetailIsActive = 'Y'
|
|
||||||
JOIN m_item ON M_ItemID = PurchaseOrderDetailItemID
|
|
||||||
AND M_ItemItem_CategoryID = 3
|
|
||||||
JOIN fa_class ON Fa_ClassID = M_ItemFa_ClassID
|
|
||||||
AND Fa_ClassIsActive = 'Y'
|
|
||||||
JOIN coa ON coaID = Fa_ClassDownPaymentCoaID
|
|
||||||
AND coaIsActive = 'Y'
|
|
||||||
WHERE PurchaseOrderAssetContractReceiveOrderPoID = ?
|
|
||||||
AND PurchaseOrderAssetContractIsActive = 'Y'
|
|
||||||
LIMIT 1";
|
|
||||||
$que_dpasset = $this->db->query($sql_dpasset, [
|
|
||||||
$invoice[0]['SupplierInvoiceReceiveOrderPoID']
|
|
||||||
]);
|
|
||||||
if (!$que_dpasset) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("[Error] query dp asset not error");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
$dpasset_coa = $que_dpasset->row_array();
|
|
||||||
if (!empty($dpasset_coa)) {
|
|
||||||
$totalDP = round($dpasset_coa['SupplierDownpaymentAmount'], 2);
|
|
||||||
if ($totalDP > 0) {
|
|
||||||
$insert_dp = $this->InsertJurnalTx(
|
|
||||||
$jurnalID,
|
|
||||||
$dpasset_coa['coaID'],
|
|
||||||
$dpasset_coa['coaDescription'],
|
|
||||||
$user['M_UserID'],
|
|
||||||
0,
|
|
||||||
$totalDP
|
|
||||||
);
|
|
||||||
if (!$insert_dp['status']) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db($insert_dp['msg']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$invoice = $this->CalcProrateDownPaymentAsset($invoice, $totalDP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// insert jurnal tx hutang per item (kredit)
|
// insert jurnal tx hutang per item (kredit)
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
foreach ($invoice as $key => $inv) {
|
foreach ($invoice as $key => $inv) {
|
||||||
@@ -1684,20 +1603,52 @@ class Fakturv4 extends MY_Controller
|
|||||||
$this->sys_error_db($status['msg']);
|
$this->sys_error_db($status['msg']);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
} else if ($item['M_ItemItem_CategoryID'] == '3') {
|
} else if ($item['M_ItemItem_CategoryID'] == '3' && !empty($item['M_ItemFa_ClassID'])) {
|
||||||
$this->InsertJurnalTxAsset($jurnalID, $item['M_ItemID'], $inv, $user['M_UserID']);
|
$sqlsgp = "SELECT * FROM fa_class WHERE Fa_ClassID = ? AND Fa_ClassIsActive = 'Y'";
|
||||||
|
$quesgp = $this->db->query($sqlsgp, [$item['M_ItemFa_ClassID']]);
|
||||||
|
if (!$quesgp) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] get map_nat_subgroup");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$itemGroup = $quesgp->row_array();
|
||||||
|
|
||||||
|
if (empty($itemGroup)) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] fa class item tidak ditemukan / belum dimapping");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$price = (doubleval($inv['SupplierInvoiceDetailTotal']) - doubleval($inv['SupplierInvoiceDetailDiscountPoProrata']));
|
||||||
|
// $taxPPH = doubleval($inv['SupplierInvoiceTaxPercentPph']) * $price / 100;
|
||||||
|
$taxPPN = doubleval($inv['SupplierInvoiceTaxPercentPpn']) * $price / 100;
|
||||||
|
|
||||||
|
$kredit = round($price + $taxPPN, 2);
|
||||||
|
|
||||||
|
$status = $this->InsertJurnalTx(
|
||||||
|
$jurnalID,
|
||||||
|
$itemGroup['Fa_ClassCoaID'],
|
||||||
|
$itemGroup['Fa_ClassCoaDesc'],
|
||||||
|
$user['M_UserID'],
|
||||||
|
0,
|
||||||
|
$kredit
|
||||||
|
);
|
||||||
|
if (!$status) {
|
||||||
|
$this->sys_error_db($status['msg']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
} else if ($item['M_ItemItem_CategoryID'] == '4') {
|
} else if ($item['M_ItemItem_CategoryID'] == '4') {
|
||||||
$this->InsertJurnalTxJasa($jurnalID, $item['M_ItemID'], $inv, $user['M_UserID']);
|
$this->InsertJurnalTxJasa($jurnalID, $item['M_ItemID'], $inv, $user['M_UserID']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sqlinvgr = "INSERT INTO jurnal_addon (
|
$sqlinvgr = "INSERT INTO jurnal_addon (
|
||||||
jurnalAddOnJurnalID,
|
jurnalAddOnJurnalID,
|
||||||
jurnalAddOnCode,
|
jurnalAddOnCode,
|
||||||
jurnalAddOnValue,
|
jurnalAddOnValue,
|
||||||
jurnalAddOnCreated,
|
jurnalAddOnCreated,
|
||||||
jurnalAddOnCreatedUserID
|
jurnalAddOnCreatedUserID
|
||||||
) VALUES (?,?,?,NOW(),?)";
|
) VALUES (?,?,?,NOW(),?)";
|
||||||
$queinvgr = $this->db->query($sqlinvgr, [
|
$queinvgr = $this->db->query($sqlinvgr, [
|
||||||
$jurnalID,
|
$jurnalID,
|
||||||
'INVGR',
|
'INVGR',
|
||||||
@@ -1723,13 +1674,13 @@ class Fakturv4 extends MY_Controller
|
|||||||
private function InsertJurnalTxJasa($jurnalID, $itemid, $invoice, $userid)
|
private function InsertJurnalTxJasa($jurnalID, $itemid, $invoice, $userid)
|
||||||
{
|
{
|
||||||
$sql_coa = "SELECT
|
$sql_coa = "SELECT
|
||||||
JasaCoaMapHutangCoaID,
|
JasaCoaMapHutangCoaID,
|
||||||
JasaCoaMapHutangCoaNo,
|
JasaCoaMapHutangCoaNo,
|
||||||
JasaCoaMapHutangCoaDesc
|
JasaCoaMapHutangCoaDesc
|
||||||
FROM jasa_coa_map
|
FROM jasa_coa_map
|
||||||
JOIN coa ON coaID = JasaCoaMapHutangCoaID
|
JOIN coa ON coaID = JasaCoaMapHutangCoaID
|
||||||
AND coaIsActive = 'Y'
|
AND coaIsActive = 'Y'
|
||||||
WHERE JasaCoaMapM_ItemID = ?";
|
WHERE JasaCoaMapM_ItemID = ?";
|
||||||
$que_coa = $this->db->query($sql_coa, [$itemid]);
|
$que_coa = $this->db->query($sql_coa, [$itemid]);
|
||||||
if (!$que_coa) {
|
if (!$que_coa) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
@@ -1766,93 +1717,6 @@ class Fakturv4 extends MY_Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function InsertJurnalTxAsset($jurnalID, $itemid, $invoice, $userid)
|
|
||||||
{
|
|
||||||
$sql_coa = "SELECT
|
|
||||||
Fa_ClassHutangCoaID,
|
|
||||||
Fa_ClassHutangCoaAccountNo,
|
|
||||||
Fa_ClassHutangCoaDesc
|
|
||||||
FROM m_item
|
|
||||||
JOIN fa_class ON Fa_ClassID = M_ItemFa_ClassID
|
|
||||||
WHERE M_ItemID = ?";
|
|
||||||
$que_coa = $this->db->query($sql_coa, $itemid);
|
|
||||||
if (!$que_coa) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("[Error] failed get coa hutang asset");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
$coaasset = $que_coa->row_array();
|
|
||||||
if ($que_coa->num_rows() <= 0) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("[Error] aset debt coa not found");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$invtotal = doubleval($invoice['SupplierInvoiceDetailTotal']);
|
|
||||||
$disprorata = doubleval($invoice['SupplierInvoiceDetailDiscountPoProrata']);
|
|
||||||
|
|
||||||
$price = $invtotal - $disprorata;
|
|
||||||
$taxPPN = doubleval($invoice['SupplierInvoiceTaxPercentPpn']) * $price / 100;
|
|
||||||
$kredit = round($price + $taxPPN, 2);
|
|
||||||
$finalValue = round($kredit - doubleval($invoice['dpReduction']), 2);
|
|
||||||
|
|
||||||
$insert = $this->InsertJurnalTx(
|
|
||||||
$jurnalID,
|
|
||||||
$coaasset['Fa_ClassHutangCoaID'],
|
|
||||||
$coaasset['Fa_ClassHutangCoaDesc'],
|
|
||||||
$userid,
|
|
||||||
0,
|
|
||||||
$finalValue
|
|
||||||
);
|
|
||||||
if (!$insert) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db($insert['msg']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function CalcProrateDownPaymentAsset($items, $dpAmount)
|
|
||||||
{
|
|
||||||
$totalKredit = 0;
|
|
||||||
foreach ($items as $key => $value) {
|
|
||||||
$invtotal = doubleval($value['SupplierInvoiceDetailTotal']);
|
|
||||||
$disprorata = doubleval($value['SupplierInvoiceDetailDiscountPoProrata']);
|
|
||||||
|
|
||||||
$price = $invtotal - $disprorata;
|
|
||||||
$taxPPN = doubleval($value['SupplierInvoiceTaxPercentPpn']) * $price / 100;
|
|
||||||
$kredit = round($price + $taxPPN, 2);
|
|
||||||
$totalKredit = $totalKredit + $kredit;
|
|
||||||
|
|
||||||
$items[$key]['kredit'] = $kredit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($totalKredit <= 0) {
|
|
||||||
foreach ($items as $key => $value) {
|
|
||||||
$items[$key]['dpReduction'] = 0;
|
|
||||||
}
|
|
||||||
return $items;
|
|
||||||
}
|
|
||||||
|
|
||||||
$runningReduction = 0;
|
|
||||||
end($items);
|
|
||||||
$lastKey = key($items);
|
|
||||||
reset($items);
|
|
||||||
|
|
||||||
foreach ($items as $key => $value) {
|
|
||||||
if ($key === $lastKey) {
|
|
||||||
$reduction = round($dpAmount - $runningReduction, 2);
|
|
||||||
} else {
|
|
||||||
$ratio = $value['kredit'] / $totalKredit;
|
|
||||||
$reduction = round($dpAmount * $ratio, 2);
|
|
||||||
$runningReduction += $reduction;
|
|
||||||
}
|
|
||||||
|
|
||||||
$items[$key]['dpReduction'] = $reduction;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $items;
|
|
||||||
}
|
|
||||||
|
|
||||||
function InsertJurnalTx($jurnalID, $coaID, $desc, $userID, $debit = 0, $kredit = 0): array
|
function InsertJurnalTx($jurnalID, $coaID, $desc, $userID, $debit = 0, $kredit = 0): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -66,40 +66,6 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getListGudang() {
|
|
||||||
try {
|
|
||||||
if (!$this->isLogin) {
|
|
||||||
$this->sys_error("invalid token");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = $this->sys_user;
|
|
||||||
$para = $this->sys_input;
|
|
||||||
|
|
||||||
$sql = "SELECT
|
|
||||||
WarehouseID,
|
|
||||||
WarehouseCode,
|
|
||||||
WarehouseName
|
|
||||||
FROM warehouse
|
|
||||||
WHERE WarehouseIsActive = 'Y'
|
|
||||||
AND WarehouseS_RegionalID = ?
|
|
||||||
AND WarehouseM_BranchID = ?
|
|
||||||
AND WarehouseIsTransit = 'N'";
|
|
||||||
$que = $this->db->query($sql, [
|
|
||||||
$user['S_RegionalID'], $para['M_BranchID']
|
|
||||||
]);
|
|
||||||
if (!$que) {
|
|
||||||
$this->sys_error_db("[Error] failed get list gudang");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = $que->result_array();
|
|
||||||
$this->sys_ok($data);
|
|
||||||
} catch (Exception $exc) {
|
|
||||||
$this->sys_error($exc->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function searchRequestAset() {
|
public function searchRequestAset() {
|
||||||
try {
|
try {
|
||||||
if (!$this->isLogin) {
|
if (!$this->isLogin) {
|
||||||
@@ -211,50 +177,32 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sql_base = "SELECT
|
$sql_base = "SELECT
|
||||||
PurchaseOrderID,
|
PurchaseOrderID,
|
||||||
PurchaseOrderDate,
|
PurchaseOrderDate,
|
||||||
PurchaseOrderNote,
|
PurchaseOrderNote,
|
||||||
PurchaseOrderNumber,
|
PurchaseOrderNumber,
|
||||||
PurchaseOrderStatus,
|
PurchaseOrderStatus,
|
||||||
PurchaseOrderRefNumber,
|
PurchaseOrderRefNumber,
|
||||||
PurchaseOrderGrandTotal,
|
PurchaseOrderGrandTotal,
|
||||||
PurchaseOrderS_RegionalID,
|
PurchaseOrderS_RegionalID,
|
||||||
PurchaseOrderApprovedManagerUserID AS verifiedby,
|
PurchaseOrderApprovedManagerUserID AS verifiedby,
|
||||||
IFNULL(PurchaseOrderApprovedUserID, 0) AS approvedby,
|
IFNULL(PurchaseOrderApprovedUserID, 0) AS approvedby,
|
||||||
PurchaseOrderAssetContractID AS contractID,
|
PurchaseOrderAssetContractID,
|
||||||
PurchaseOrderAssetContractName AS contractName,
|
PurchaseOrderAssetContractName AS contractName,
|
||||||
PurchaseOrderAssetContractDate AS contractDate,
|
PurchaseOrderAssetContractStartDate AS contractStart,
|
||||||
PurchaseOrderAssetContractStartDate AS contractStart,
|
PurchaseOrderAssetContractEndDate AS contractEnd,
|
||||||
PurchaseOrderAssetContractEndDate AS contractEnd,
|
SupplierID,
|
||||||
IFNULL(attach.AttachmentCount, 0) AS AttachmentCount,
|
SupplierName
|
||||||
SupplierID,
|
FROM purchase_order
|
||||||
SupplierName,
|
JOIN supplier ON SupplierID = PurchaseOrderSupplierID
|
||||||
SupplierDownpaymentID
|
JOIN purchase_order_asset_contract
|
||||||
FROM purchase_order
|
ON PurchaseOrderAssetContractPurchaseOrderID = PurchaseOrderID
|
||||||
JOIN supplier ON SupplierID = PurchaseOrderSupplierID
|
WHERE PurchaseOrderIsActive = 'Y'
|
||||||
JOIN purchase_order_asset_contract
|
AND PurchaseOrderItemCategoryID = '3'
|
||||||
ON PurchaseOrderAssetContractPurchaseOrderID = PurchaseOrderID
|
AND PurchaseOrderS_RegionalID = ?
|
||||||
LEFT JOIN supplier_downpayment
|
AND PurchaseOrderDate BETWEEN DATE(?) AND DATE(?)
|
||||||
ON SupplierDownpaymentPurchasOrderID = PurchaseOrderID
|
AND (PurchaseOrderStatus = ? OR 'All' = ?)
|
||||||
AND SupplierDownpaymentIsActive = 'Y'
|
AND PurchaseOrderNumber LIKE ?";
|
||||||
LEFT JOIN (
|
|
||||||
SELECT
|
|
||||||
ContractAssetAttachmentPurchaseOrderID,
|
|
||||||
ContractAssetAttachmentPurchaseOrderAssetContractID,
|
|
||||||
COUNT(*) AS AttachmentCount
|
|
||||||
FROM contract_asset_attachment
|
|
||||||
WHERE ContractAssetAttachmentIsActive = 'Y'
|
|
||||||
GROUP BY
|
|
||||||
ContractAssetAttachmentPurchaseOrderID,
|
|
||||||
ContractAssetAttachmentPurchaseOrderAssetContractID
|
|
||||||
) attach ON attach.ContractAssetAttachmentPurchaseOrderID = PurchaseOrderID
|
|
||||||
AND attach.ContractAssetAttachmentPurchaseOrderAssetContractID = PurchaseOrderAssetContractID
|
|
||||||
WHERE PurchaseOrderIsActive = 'Y'
|
|
||||||
AND PurchaseOrderItemCategoryID = '3'
|
|
||||||
AND PurchaseOrderS_RegionalID = ?
|
|
||||||
AND PurchaseOrderDate BETWEEN DATE(?) AND DATE(?)
|
|
||||||
AND (PurchaseOrderStatus = ? OR 'All' = ?)
|
|
||||||
AND PurchaseOrderNumber LIKE ?";
|
|
||||||
|
|
||||||
$limit = 10;
|
$limit = 10;
|
||||||
$offset = 0;
|
$offset = 0;
|
||||||
@@ -340,29 +288,29 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
|
|
||||||
# get data from purchase order detail #
|
# get data from purchase order detail #
|
||||||
$sql_detail = "SELECT
|
$sql_detail = "SELECT
|
||||||
PurchaseOrderID,
|
PurchaseOrderID,
|
||||||
PurchaseRequestID,
|
PurchaseRequestID,
|
||||||
PurchaseRequestNumber,
|
PurchaseRequestNumber,
|
||||||
PurchaseOrderDetailPurchaseSummaryID AS PurchaseOrderSummaryID,
|
PurchaseOrderDetailPurchaseSummaryID AS PurchaseOrderSummaryID,
|
||||||
PurchaseOrderDetailPurchaseRequestDetailID AS PurchaseRequestDetailID,
|
PurchaseOrderDetailPurchaseRequestDetailID AS PurchaseRequestDetailID,
|
||||||
PurchaseOrderDetailPurchaseRequestFlagID AS PurchaseRequestFlagID,
|
PurchaseOrderDetailPurchaseRequestFlagID AS PurchaseRequestFlagID,
|
||||||
PurchaseOrderDetailRequestQty AS OriginalQty,
|
PurchaseOrderDetailRequestQty AS OriginalQty,
|
||||||
PurchaseOrderDetailQty AS RequestQty,
|
PurchaseOrderDetailQty AS RequestQty,
|
||||||
PurchaseOrderDetailPrice AS SupplierPrice,
|
PurchaseOrderDetailPrice AS SupplierPrice,
|
||||||
PurchaseOrderDetailTotal,
|
PurchaseOrderDetailTotal,
|
||||||
PurchaseOrderDetailItemID AS M_ItemID,
|
PurchaseOrderDetailItemID AS M_ItemID,
|
||||||
M_ItemCode,
|
M_ItemCode,
|
||||||
M_ItemDesc,
|
M_ItemDesc,
|
||||||
PurchaseOrderDetailItemUnitID AS ItemUnitID,
|
PurchaseOrderDetailItemUnitID AS ItemUnitID,
|
||||||
ItemUnitName
|
ItemUnitName
|
||||||
FROM purchase_order
|
FROM purchase_order
|
||||||
JOIN purchase_order_detail ON PurchaseOrderDetailPurchaseOrderID = PurchaseOrderID
|
JOIN purchase_order_detail ON PurchaseOrderDetailPurchaseOrderID = PurchaseOrderID
|
||||||
AND PurchaseOrderDetailIsActive = 'Y'
|
AND PurchaseOrderDetailIsActive = 'Y'
|
||||||
JOIN purchase_request ON PurchaseRequestID = PurchaseOrderDetailPurchaseRequestID
|
JOIN purchase_request ON PurchaseRequestID = PurchaseOrderDetailPurchaseRequestID
|
||||||
JOIN m_item ON M_ItemID = PurchaseOrderDetailItemID
|
JOIN m_item ON M_ItemID = PurchaseOrderDetailItemID
|
||||||
JOIN itemunit ON ItemUnitID = PurchaseOrderDetailItemUnitID
|
JOIN itemunit ON ItemUnitID = PurchaseOrderDetailItemUnitID
|
||||||
WHERE PurchaseOrderDetailIsActive = 'Y'
|
WHERE PurchaseOrderDetailIsActive = 'Y'
|
||||||
AND PurchaseOrderID = ?";
|
AND PurchaseOrderID = ?";
|
||||||
$que_detail = $this->db->query($sql_detail, [$para['poID']]);
|
$que_detail = $this->db->query($sql_detail, [$para['poID']]);
|
||||||
if (!$que_detail) {
|
if (!$que_detail) {
|
||||||
$this->sys_error_db("[Error] failed get data po detail asset");
|
$this->sys_error_db("[Error] failed get data po detail asset");
|
||||||
@@ -372,27 +320,27 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
|
|
||||||
# get data from purchase order summary #
|
# get data from purchase order summary #
|
||||||
$sql_sumry = "SELECT
|
$sql_sumry = "SELECT
|
||||||
PurchaseOrderID,
|
PurchaseOrderID,
|
||||||
PurchaseOrderSummaryID,
|
PurchaseOrderSummaryID,
|
||||||
PurchaseOrderSummaryQty AS RequestQty,
|
PurchaseOrderSummaryQty AS RequestQty,
|
||||||
PurchaseOrderSummaryPrice AS SupplierPrice,
|
PurchaseOrderSummaryPrice AS SupplierPrice,
|
||||||
PurchaseOrderSummaryDiscountRupiah AS DiskonRupiah,
|
PurchaseOrderSummaryDiscountRupiah AS DiskonRupiah,
|
||||||
PurchaseOrderSummaryDiscountPercent AS DiskonPercent,
|
PurchaseOrderSummaryDiscountPercent AS DiskonPercent,
|
||||||
PurchaseOrderSummaryDiscountAmount AS DiskonAmount,
|
PurchaseOrderSummaryDiscountAmount AS DiskonAmount,
|
||||||
PurchaseOrderSummaryDiscountType AS DiskonType,
|
PurchaseOrderSummaryDiscountType AS DiskonType,
|
||||||
(PurchaseOrderSummaryPrice - PurchaseOrderSummaryDiscountAmount) AS EndPrice,
|
(PurchaseOrderSummaryPrice - PurchaseOrderSummaryDiscountAmount) AS EndPrice,
|
||||||
PurchaseOrderSummaryTotal AS TempTotal,
|
PurchaseOrderSummaryTotal AS TempTotal,
|
||||||
PurchaseOrderSummaryItemID AS M_ItemID,
|
PurchaseOrderSummaryItemID AS M_ItemID,
|
||||||
M_ItemCode,
|
M_ItemCode,
|
||||||
M_ItemDesc,
|
M_ItemDesc,
|
||||||
PurchaseOrderSummaryItemUnitID AS ItemUnitID,
|
PurchaseOrderSummaryItemUnitID AS ItemUnitID,
|
||||||
ItemUnitName
|
ItemUnitName
|
||||||
FROM purchase_order
|
FROM purchase_order
|
||||||
JOIN purchase_order_summary ON PurchaseOrderSummaryPurchaseOrderID = PurchaseOrderID
|
JOIN purchase_order_summary ON PurchaseOrderSummaryPurchaseOrderID = PurchaseOrderID
|
||||||
JOIN m_item ON M_ItemID = PurchaseOrderSummaryItemID
|
JOIN m_item ON M_ItemID = PurchaseOrderSummaryItemID
|
||||||
JOIN itemunit ON ItemUnitID = PurchaseOrderSummaryItemUnitID
|
JOIN itemunit ON ItemUnitID = PurchaseOrderSummaryItemUnitID
|
||||||
WHERE PurchaseOrderSummaryIsActive = 'Y'
|
WHERE PurchaseOrderSummaryIsActive = 'Y'
|
||||||
AND PurchaseOrderID = ?";
|
AND PurchaseOrderID = ?";
|
||||||
$que_sumry = $this->db->query($sql_sumry, [$para['poID']]);
|
$que_sumry = $this->db->query($sql_sumry, [$para['poID']]);
|
||||||
if (!$que_sumry) {
|
if (!$que_sumry) {
|
||||||
$this->sys_error_db("[Error] failed get data po summary asset");
|
$this->sys_error_db("[Error] failed get data po summary asset");
|
||||||
@@ -402,59 +350,52 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
|
|
||||||
# get data from purchase order #
|
# get data from purchase order #
|
||||||
$sql_poasset = "SELECT
|
$sql_poasset = "SELECT
|
||||||
PurchaseOrderID,
|
PurchaseOrderID,
|
||||||
PurchaseOrderDate AS podate,
|
PurchaseOrderDate AS podate,
|
||||||
PurchaseOrderNote AS catatan,
|
PurchaseOrderNote AS catatan,
|
||||||
PurchaseOrderNumber,
|
PurchaseOrderNumber,
|
||||||
PurchaseOrderStatus,
|
PurchaseOrderStatus,
|
||||||
PurchaseOrderRefNumber AS reference,
|
PurchaseOrderRefNumber AS reference,
|
||||||
PurchaseOrderGrandTotal AS grandtotal,
|
PurchaseOrderGrandTotal AS grandtotal,
|
||||||
CASE
|
CASE
|
||||||
WHEN PurchaseOrderTaxPpnType = 'P' THEN 'percent'
|
WHEN PurchaseOrderTaxPpnType = 'P' THEN 'percent'
|
||||||
ELSE 'nominal'
|
ELSE 'absolute'
|
||||||
END AS typepajak,
|
END AS typepajak,
|
||||||
CASE
|
CASE
|
||||||
WHEN PurchaseOrderTaxPpnType = 'P' THEN PurchaseOrderTaxPercentPpn
|
WHEN PurchaseOrderTaxPpnType = 'P' THEN PurchaseOrderTaxPercentPpn
|
||||||
ELSE PurchaseOrderTaxAmountPpn
|
ELSE PurchaseOrderTaxAmountPpn
|
||||||
END AS valuepajak,
|
END AS valuepajak,
|
||||||
CASE
|
CASE
|
||||||
WHEN PurchaseOrderDiscountPercent > 0.00 THEN 'percent'
|
WHEN PurchaseOrderDiscountPercent > 0.00 THEN 'percent'
|
||||||
ELSE 'nominal'
|
ELSE 'absolute'
|
||||||
END AS typediskon,
|
END AS typediskon,
|
||||||
CASE
|
CASE
|
||||||
WHEN PurchaseOrderDiscountPercent > 0.00 THEN PurchaseOrderDiscountPercent
|
WHEN PurchaseOrderDiscountPercent > 0.00 THEN PurchaseOrderDiscountPercent
|
||||||
ELSE PurchaseOrderDiscountAmount
|
ELSE PurchaseOrderDiscountAmount
|
||||||
END AS valuediskon,
|
END AS valuediskon,
|
||||||
PurchaseOrderSubTotal AS subtotal,
|
PurchaseOrderSubTotal AS subtotal,
|
||||||
PurchaseOrderGrandTotal AS grandtotal,
|
PurchaseOrderGrandTotal AS grandtotal,
|
||||||
SupplierID AS supplierID,
|
SupplierID AS supplierID,
|
||||||
SupplierName,
|
SupplierName,
|
||||||
WarehouseID AS gudangID,
|
PurchaseOrderAssetContractID,
|
||||||
WarehouseM_BranchID AS branchID,
|
PurchaseOrderAssetContractTAssetAttachmentID AS assetAttachmentID,
|
||||||
PurchaseOrderAssetContractID,
|
PurchaseOrderAssetContractName AS contractName,
|
||||||
PurchaseOrderAssetContractTAssetAttachmentID AS assetAttachmentID,
|
PurchaseOrderAssetContractDate AS contractDate,
|
||||||
PurchaseOrderAssetContractName AS contractName,
|
PurchaseOrderAssetContractStartDate AS contractStart,
|
||||||
PurchaseOrderAssetContractDate AS contractDate,
|
PurchaseOrderAssetContractEndDate AS contractEnd,
|
||||||
PurchaseOrderAssetContractStartDate AS contractStart,
|
PurchaseOrderAssetContractDuration AS contractDuration,
|
||||||
PurchaseOrderAssetContractEndDate AS contractEnd,
|
PurchaseOrderAssetContractInstallmentNumber AS installmentNumber,
|
||||||
PurchaseOrderAssetContractDuration AS contractDuration,
|
PurchaseOrderAssetContractInstallmentDate AS installmentDate,
|
||||||
PurchaseOrderAssetContractInstallmentNumber AS installmentNumber,
|
PurchaseOrderAssetContractInstallmentPayAmount AS installmentPayAmount,
|
||||||
PurchaseOrderAssetContractInstallmentDate AS installmentDate,
|
PurchaseOrderAssetContractInstallmentDownPaymentType AS installmentDownPaymentType,
|
||||||
PurchaseOrderAssetContractInstallmentPayAmount AS installmentPayAmount,
|
PurchaseOrderAssetContractInstallmentDownPayment AS installmentDownPayment,
|
||||||
PurchaseOrderAssetContractInstallmentDownPaymentType AS installmentDownPaymentType,
|
PurchaseOrderApprovedManagerUserID AS verifiedby
|
||||||
PurchaseOrderAssetContractInstallmentDownPayment AS installmentDownPayment,
|
FROM purchase_order
|
||||||
PurchaseOrderApprovedManagerUserID AS verifiedby,
|
JOIN supplier ON SupplierID = PurchaseOrderSupplierID
|
||||||
SupplierDownpaymentID
|
JOIN purchase_order_asset_contract
|
||||||
FROM purchase_order
|
ON PurchaseOrderAssetContractPurchaseOrderID = PurchaseOrderID
|
||||||
JOIN supplier ON SupplierID = PurchaseOrderSupplierID
|
WHERE PurchaseOrderIsActive = 'Y'
|
||||||
JOIN warehouse ON WarehouseID = PurchaseOrderWarehouseID
|
AND PurchaseOrderID = ?";
|
||||||
JOIN purchase_order_asset_contract
|
|
||||||
ON PurchaseOrderAssetContractPurchaseOrderID = PurchaseOrderID
|
|
||||||
LEFT JOIN supplier_downpayment
|
|
||||||
ON SupplierDownpaymentPurchasOrderID = PurchaseOrderID
|
|
||||||
AND SupplierDownpaymentIsActive = 'Y'
|
|
||||||
WHERE PurchaseOrderIsActive = 'Y'
|
|
||||||
AND PurchaseOrderID = ?";
|
|
||||||
$que_poasset = $this->db->query($sql_poasset, [$para['poID']]);
|
$que_poasset = $this->db->query($sql_poasset, [$para['poID']]);
|
||||||
if (!$que_poasset) {
|
if (!$que_poasset) {
|
||||||
$this->sys_error_db("[Error] failed get data from purchase order");
|
$this->sys_error_db("[Error] failed get data from purchase order");
|
||||||
@@ -485,7 +426,6 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$subtotal = floatval($datapo['subtotal']);
|
$subtotal = floatval($datapo['subtotal']);
|
||||||
$downpayment = floatval($datapo['installmentDownPayment']);
|
|
||||||
$grandtotal = floatval($datapo['grandtotal']);
|
$grandtotal = floatval($datapo['grandtotal']);
|
||||||
|
|
||||||
$valuediskon = floatval($datapo['valuediskon']);
|
$valuediskon = floatval($datapo['valuediskon']);
|
||||||
@@ -503,11 +443,8 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
"subtotal" => $subtotal,
|
"subtotal" => $subtotal,
|
||||||
"diskon" => $valuediskon,
|
"diskon" => $valuediskon,
|
||||||
"pajak" => $valuepajak,
|
"pajak" => $valuepajak,
|
||||||
"downpayment" => $downpayment,
|
|
||||||
"total_before_downpayment" => $downpayment + $grandtotal,
|
|
||||||
"total" => $grandtotal
|
"total" => $grandtotal
|
||||||
];
|
];
|
||||||
|
|
||||||
/* map summary to purchase order */
|
/* map summary to purchase order */
|
||||||
$datapo['valuepajak'] = floatval($datapo['valuepajak']);
|
$datapo['valuepajak'] = floatval($datapo['valuepajak']);
|
||||||
$datapo['valuediskon'] = floatval($datapo['valuediskon']);
|
$datapo['valuediskon'] = floatval($datapo['valuediskon']);
|
||||||
@@ -600,34 +537,30 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
$summary_subtotal = floatval($para['summary']['subtotal']);
|
$summary_subtotal = floatval($para['summary']['subtotal']);
|
||||||
$summary_diskon = floatval($para['summary']['diskon']);
|
$summary_diskon = floatval($para['summary']['diskon']);
|
||||||
$summary_pajak = floatval($para['summary']['pajak']);
|
$summary_pajak = floatval($para['summary']['pajak']);
|
||||||
$summary_downpayment = floatval($para['summary']['downpayment']);
|
|
||||||
$summary_total = floatval($para['summary']['total']);
|
$summary_total = floatval($para['summary']['total']);
|
||||||
|
|
||||||
$sql_po = "INSERT INTO purchase_order (
|
$sql_po = "INSERT INTO purchase_order (
|
||||||
PurchaseOrderNumber,
|
PurchaseOrderNumber,
|
||||||
PurchaseOrderItemCategoryID, -- '3' for asset
|
PurchaseOrderItemCategoryID, -- '3' for asset
|
||||||
PurchaseOrderDate,
|
PurchaseOrderDate,
|
||||||
PurchaseOrderRefNumber,
|
PurchaseOrderRefNumber,
|
||||||
PurchaseOrderSupplierID,
|
PurchaseOrderSupplierID,
|
||||||
PurchaseOrderS_RegionalID,
|
PurchaseOrderS_RegionalID,
|
||||||
PurchaseOrderTaxPpnType,
|
PurchaseOrderTaxPpnType,
|
||||||
PurchaseOrderTaxPercentPpn,
|
PurchaseOrderTaxPercentPpn,
|
||||||
PurchaseOrderDiscountPercent,
|
PurchaseOrderDiscountPercent,
|
||||||
PurchaseOrderDiscountAmount,
|
PurchaseOrderDiscountAmount,
|
||||||
PurchaseOrderWarehouseType,
|
PurchaseOrderNote,
|
||||||
PurchaseOrderWarehouseID,
|
PurchaseOrderSubTotal,
|
||||||
PurchaseOrderNote,
|
PurchaseOrderTaxAmountPpn,
|
||||||
PurchaseOrderSubTotal,
|
PurchaseOrderGrandTotal,
|
||||||
PurchaseOrderTaxAmountPpn,
|
PurchaseOrderUserID,
|
||||||
PurchaseOrderGrandTotal,
|
PurchaseOrderCreated
|
||||||
PurchaseOrderUserID,
|
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())";
|
||||||
PurchaseOrderCreated
|
|
||||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())";
|
|
||||||
$que_po = $this->db->query($sql_po, [
|
$que_po = $this->db->query($sql_po, [
|
||||||
$numpd, '3', $para['podate'], $para['reference'], $para['supplierID'],
|
$numpd, '3', $para['podate'], $para['reference'], $para['supplierID'],
|
||||||
$user['S_RegionalID'], $taxtype, $taxpercent, $discpercent, $summary_diskon,
|
$user['S_RegionalID'], $taxtype, $taxpercent, $discpercent, $summary_diskon,
|
||||||
'single', $para['gudangID'], $para['catatan'], $summary_subtotal,
|
$para['catatan'], $summary_subtotal, $summary_pajak, $summary_total, $user['M_UserID']
|
||||||
$summary_pajak, $summary_total, $user['M_UserID']
|
|
||||||
]);
|
]);
|
||||||
if (!$que_po) {
|
if (!$que_po) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
@@ -649,19 +582,19 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sql_summary = "INSERT INTO purchase_order_summary (
|
$sql_summary = "INSERT INTO purchase_order_summary (
|
||||||
PurchaseOrderSummaryPurchaseOrderID,
|
PurchaseOrderSummaryPurchaseOrderID,
|
||||||
PurchaseOrderSummaryItemID,
|
PurchaseOrderSummaryItemID,
|
||||||
PurchaseOrderSummaryItemUnitID,
|
PurchaseOrderSummaryItemUnitID,
|
||||||
PurchaseOrderSummaryQty,
|
PurchaseOrderSummaryQty,
|
||||||
PurchaseOrderSummaryPrice,
|
PurchaseOrderSummaryPrice,
|
||||||
PurchaseOrderSummaryTotal,
|
PurchaseOrderSummaryTotal,
|
||||||
PurchaseOrderSummaryDiscountRupiah,
|
PurchaseOrderSummaryDiscountRupiah,
|
||||||
PurchaseOrderSummaryDiscountPercent,
|
PurchaseOrderSummaryDiscountPercent,
|
||||||
PurchaseOrderSummaryDiscountAmount,
|
PurchaseOrderSummaryDiscountAmount,
|
||||||
PurchaseOrderSummaryDiscountType,
|
PurchaseOrderSummaryDiscountType,
|
||||||
PurchaseOrderSummaryCreatedUserID,
|
PurchaseOrderSummaryCreatedUserID,
|
||||||
PurchaseOrderSummaryCreated
|
PurchaseOrderSummaryCreated
|
||||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,NOW())";
|
) VALUES (?,?,?,?,?,?,?,?,?,?,?,NOW())";
|
||||||
$que_summary = $this->db->query($sql_summary, [
|
$que_summary = $this->db->query($sql_summary, [
|
||||||
$PurchaseOrderID, $obj['M_ItemID'], $obj['ItemUnitID'],
|
$PurchaseOrderID, $obj['M_ItemID'], $obj['ItemUnitID'],
|
||||||
$obj['RequestQty'], $obj['SupplierPrice'], $obj['TempTotal'],
|
$obj['RequestQty'], $obj['SupplierPrice'], $obj['TempTotal'],
|
||||||
@@ -689,27 +622,26 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
$total = floatval($obj['SupplierPrice']) * floatval($obj['RequestQty']);
|
$total = floatval($obj['SupplierPrice']) * floatval($obj['RequestQty']);
|
||||||
|
|
||||||
$sql_detail = "INSERT INTO purchase_order_detail (
|
$sql_detail = "INSERT INTO purchase_order_detail (
|
||||||
PurchaseOrderDetailPurchaseOrderID,
|
PurchaseOrderDetailPurchaseOrderID,
|
||||||
PurchaseOrderDetailPurchaseSummaryID,
|
PurchaseOrderDetailPurchaseSummaryID,
|
||||||
PurchaseOrderDetailPurchaseRequestID,
|
PurchaseOrderDetailPurchaseRequestID,
|
||||||
PurchaseOrderDetailPurchaseRequestDetailID,
|
PurchaseOrderDetailPurchaseRequestDetailID,
|
||||||
PurchaseOrderDetailPurchaseRequestFlagID,
|
PurchaseOrderDetailPurchaseRequestFlagID,
|
||||||
PurchaseOrderDetailItemID,
|
PurchaseOrderDetailItemID,
|
||||||
PurchaseOrderDetailItemUnitID,
|
PurchaseOrderDetailItemUnitID,
|
||||||
PurchaseOrderDetailRequestQty,
|
PurchaseOrderDetailRequestQty,
|
||||||
PurchaseOrderDetailQty,
|
PurchaseOrderDetailQty,
|
||||||
PurchaseOrderDetailPrice,
|
PurchaseOrderDetailPrice,
|
||||||
PurchaseOrderDetailTotal,
|
PurchaseOrderDetailTotal,
|
||||||
PurchaseOrderDetailWarehouseID,
|
PurchaseOrderDetailUserID,
|
||||||
PurchaseOrderDetailUserID,
|
PurchaseOrderDetailCreatedUserID,
|
||||||
PurchaseOrderDetailCreatedUserID,
|
PurchaseOrderDetailCreated
|
||||||
PurchaseOrderDetailCreated
|
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())";
|
||||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())";
|
|
||||||
$que_detail = $this->db->query($sql_detail, [
|
$que_detail = $this->db->query($sql_detail, [
|
||||||
$PurchaseOrderID, $obj['PurchaseSummaryID'], $obj['PurchaseRequestID'],
|
$PurchaseOrderID, $obj['PurchaseSummaryID'], $obj['PurchaseRequestID'],
|
||||||
$obj['PurchaseRequestDetailID'], $obj['PurchaseRequestFlagID'],
|
$obj['PurchaseRequestDetailID'], $obj['PurchaseRequestFlagID'],
|
||||||
$obj['M_ItemID'], $obj['ItemUnitID'], $obj['OriginalQty'], $obj['RequestQty'],
|
$obj['M_ItemID'], $obj['ItemUnitID'], $obj['OriginalQty'], $obj['RequestQty'],
|
||||||
$obj['SupplierPrice'], $total, $para['gudangID'], $user['M_UserID'], $user['M_UserID']
|
$obj['SupplierPrice'], $total, $user['M_UserID'], $user['M_UserID']
|
||||||
]);
|
]);
|
||||||
if (!$que_detail) {
|
if (!$que_detail) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
@@ -719,8 +651,8 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
|
|
||||||
/* purchase request update flag */
|
/* purchase request update flag */
|
||||||
$sql_flag = "UPDATE purchase_request_flag SET
|
$sql_flag = "UPDATE purchase_request_flag SET
|
||||||
PurchaseRequestFlagQtyProses = ?
|
PurchaseRequestFlagQtyProses = ?
|
||||||
WHERE PurchaseRequestFlagID = ?";
|
WHERE PurchaseRequestFlagID = ?";
|
||||||
$que_flag = $this->db->query($sql_flag, [
|
$que_flag = $this->db->query($sql_flag, [
|
||||||
$obj['RequestQty'], $obj['PurchaseRequestFlagID']
|
$obj['RequestQty'], $obj['PurchaseRequestFlagID']
|
||||||
]);
|
]);
|
||||||
@@ -733,23 +665,23 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
|
|
||||||
# INSERT into table purchase_order_asset_contract #
|
# INSERT into table purchase_order_asset_contract #
|
||||||
$sql_contract = "INSERT INTO purchase_order_asset_contract (
|
$sql_contract = "INSERT INTO purchase_order_asset_contract (
|
||||||
PurchaseOrderAssetContractPurchaseOrderID,
|
PurchaseOrderAssetContractPurchaseOrderID,
|
||||||
PurchaseOrderAssetContractTAssetAttachmentID,
|
PurchaseOrderAssetContractTAssetAttachmentID,
|
||||||
PurchaseOrderAssetContractName,
|
PurchaseOrderAssetContractName,
|
||||||
PurchaseOrderAssetContractDate,
|
PurchaseOrderAssetContractDate,
|
||||||
PurchaseOrderAssetContractStartDate,
|
PurchaseOrderAssetContractStartDate,
|
||||||
PurchaseOrderAssetContractEndDate,
|
PurchaseOrderAssetContractEndDate,
|
||||||
PurchaseOrderAssetContractDuration,
|
PurchaseOrderAssetContractDuration,
|
||||||
PurchaseOrderAssetContractInstallmentNumber,
|
PurchaseOrderAssetContractInstallmentNumber,
|
||||||
PurchaseOrderAssetContractInstallmentDate,
|
PurchaseOrderAssetContractInstallmentDate,
|
||||||
PurchaseOrderAssetContractInstallmentPayAmount,
|
PurchaseOrderAssetContractInstallmentPayAmount,
|
||||||
PurchaseOrderAssetContractInstallmentDownPaymentType,
|
PurchaseOrderAssetContractInstallmentDownPaymentType,
|
||||||
PurchaseOrderAssetContractInstallmentDownPayment,
|
PurchaseOrderAssetContractInstallmentDownPayment,
|
||||||
PurchaseOrderAssetContractCreatedUserID,
|
PurchaseOrderAssetContractCreatedUserID,
|
||||||
PurchaseOrderAssetContractCreated,
|
PurchaseOrderAssetContractCreated,
|
||||||
PurchaseOrderAssetContractLastUpdated,
|
PurchaseOrderAssetContractLastUpdated,
|
||||||
PurchaseOrderAssetContractIsActive
|
PurchaseOrderAssetContractIsActive
|
||||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,NOW(),NOW(),'Y')";
|
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,NOW(),NOW(),'Y')";
|
||||||
$que_contract = $this->db->query($sql_contract, [
|
$que_contract = $this->db->query($sql_contract, [
|
||||||
$PurchaseOrderID,
|
$PurchaseOrderID,
|
||||||
$para['assetAttachmentID'],
|
$para['assetAttachmentID'],
|
||||||
@@ -771,33 +703,6 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
# INSERT into table supplier_downpayment #
|
|
||||||
$sql_dp = "INSERT INTO supplier_downpayment (
|
|
||||||
SupplierDownpaymentPurchasOrderID,
|
|
||||||
SupplierDownpaymentSupplierID,
|
|
||||||
SupplierDownpaymentAmount,
|
|
||||||
SupplierDownpaymentDate,
|
|
||||||
SupplierDownpaymentDueDate,
|
|
||||||
SupplierDownpaymentStatus,
|
|
||||||
SupplierDownpaymentCreatedUserID,
|
|
||||||
SupplierDownpaymentLastUpdatedUserID
|
|
||||||
) VALUES (?,?,?,?,?,?,?,?)";
|
|
||||||
$que_dp = $this->db->query($sql_dp, [
|
|
||||||
$PurchaseOrderID,
|
|
||||||
$para['supplierID'],
|
|
||||||
$summary_downpayment ?: 0.00,
|
|
||||||
$para['contractStart'],
|
|
||||||
$para['contractStart'],
|
|
||||||
'Draft',
|
|
||||||
$user['M_UserID'],
|
|
||||||
$user['M_UserID']
|
|
||||||
]);
|
|
||||||
if (!$que_dp) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("[Error] failed insert supplier downpayment");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->insertLog(
|
$this->insertLog(
|
||||||
$PurchaseOrderID, 'CREATE', $para, '',
|
$PurchaseOrderID, 'CREATE', $para, '',
|
||||||
[], $user['M_UserID'], 'create purchase order asset'
|
[], $user['M_UserID'], 'create purchase order asset'
|
||||||
@@ -839,7 +744,6 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
$summary_subtotal = floatval($para['summary']['subtotal']);
|
$summary_subtotal = floatval($para['summary']['subtotal']);
|
||||||
$summary_diskon = floatval($para['summary']['diskon']);
|
$summary_diskon = floatval($para['summary']['diskon']);
|
||||||
$summary_pajak = floatval($para['summary']['pajak']);
|
$summary_pajak = floatval($para['summary']['pajak']);
|
||||||
$summary_downpayment = floatval($para['summary']['downpayment']);
|
|
||||||
$summary_total = floatval($para['summary']['total']);
|
$summary_total = floatval($para['summary']['total']);
|
||||||
|
|
||||||
# update po header #
|
# update po header #
|
||||||
@@ -852,8 +756,6 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
PurchaseOrderTaxPercentPpn = ?,
|
PurchaseOrderTaxPercentPpn = ?,
|
||||||
PurchaseOrderDiscountPercent = ?,
|
PurchaseOrderDiscountPercent = ?,
|
||||||
PurchaseOrderDiscountAmount = ?,
|
PurchaseOrderDiscountAmount = ?,
|
||||||
PurchaseOrderWarehouseType = ?,
|
|
||||||
PurchaseOrderWarehouseID = ?,
|
|
||||||
PurchaseOrderNote = ?,
|
PurchaseOrderNote = ?,
|
||||||
PurchaseOrderSubTotal = ?,
|
PurchaseOrderSubTotal = ?,
|
||||||
PurchaseOrderTaxAmountPpn = ?,
|
PurchaseOrderTaxAmountPpn = ?,
|
||||||
@@ -863,8 +765,8 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
AND PurchaseOrderIsActive = 'Y'";
|
AND PurchaseOrderIsActive = 'Y'";
|
||||||
$que_po = $this->db->query($sql_po, [
|
$que_po = $this->db->query($sql_po, [
|
||||||
$para['podate'], $para['reference'], $para['supplierID'], $user['S_RegionalID'],
|
$para['podate'], $para['reference'], $para['supplierID'], $user['S_RegionalID'],
|
||||||
$taxtype, $taxpercent, $discpercent, $summary_diskon, 'single', $para['gudangID'],
|
$taxtype, $taxpercent, $discpercent, $summary_diskon, $para['catatan'],
|
||||||
$para['catatan'], $summary_subtotal, $summary_pajak, $summary_total, $para['PurchaseOrderID']
|
$summary_subtotal, $summary_pajak, $summary_total, $para['PurchaseOrderID']
|
||||||
]);
|
]);
|
||||||
if (!$que_po) {
|
if (!$que_po) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
@@ -874,20 +776,20 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
|
|
||||||
# update purchase_order_asset_contract #
|
# update purchase_order_asset_contract #
|
||||||
$sql_contract = "UPDATE purchase_order_asset_contract SET
|
$sql_contract = "UPDATE purchase_order_asset_contract SET
|
||||||
PurchaseOrderAssetContractTAssetAttachmentID = ?,
|
PurchaseOrderAssetContractTAssetAttachmentID = ?,
|
||||||
PurchaseOrderAssetContractName = ?,
|
PurchaseOrderAssetContractName = ?,
|
||||||
PurchaseOrderAssetContractDate = ?,
|
PurchaseOrderAssetContractDate = ?,
|
||||||
PurchaseOrderAssetContractStartDate = ?,
|
PurchaseOrderAssetContractStartDate = ?,
|
||||||
PurchaseOrderAssetContractEndDate = ?,
|
PurchaseOrderAssetContractEndDate = ?,
|
||||||
PurchaseOrderAssetContractDuration = ?,
|
PurchaseOrderAssetContractDuration = ?,
|
||||||
PurchaseOrderAssetContractInstallmentNumber = ?,
|
PurchaseOrderAssetContractInstallmentNumber = ?,
|
||||||
PurchaseOrderAssetContractInstallmentDate = ?,
|
PurchaseOrderAssetContractInstallmentDate = ?,
|
||||||
PurchaseOrderAssetContractInstallmentPayAmount = ?,
|
PurchaseOrderAssetContractInstallmentPayAmount = ?,
|
||||||
PurchaseOrderAssetContractInstallmentDownPaymentType = ?,
|
PurchaseOrderAssetContractInstallmentDownPaymentType = ?,
|
||||||
PurchaseOrderAssetContractInstallmentDownPayment = ?,
|
PurchaseOrderAssetContractInstallmentDownPayment = ?,
|
||||||
PurchaseOrderAssetContractLastUpdated = NOW()
|
PurchaseOrderAssetContractLastUpdated = NOW()
|
||||||
WHERE PurchaseOrderAssetContractID = ?
|
WHERE PurchaseOrderAssetContractID = ?
|
||||||
AND PurchaseOrderAssetContractIsActive = 'Y'";
|
AND PurchaseOrderAssetContractIsActive = 'Y'";
|
||||||
$que_contract = $this->db->query($sql_contract, [
|
$que_contract = $this->db->query($sql_contract, [
|
||||||
$para['assetAttachmentID'],
|
$para['assetAttachmentID'],
|
||||||
$para['contractName'],
|
$para['contractName'],
|
||||||
@@ -908,34 +810,11 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
## UPDATE existing downpayment ##
|
|
||||||
$sql = "UPDATE supplier_downpayment SET
|
|
||||||
SupplierDownpaymentAmount = ?,
|
|
||||||
SupplierDownpaymentDate = ?,
|
|
||||||
SupplierDownpaymentDueDate = ?,
|
|
||||||
SupplierDownpaymentStatus = ?,
|
|
||||||
SupplierDownpaymentLastUpdatedUserID = ?
|
|
||||||
WHERE SupplierDownpaymentID = ?
|
|
||||||
AND SupplierDownpaymentIsActive = 'Y'";
|
|
||||||
$que = $this->db->query($sql, [
|
|
||||||
$summary_downpayment ?: 0.00,
|
|
||||||
$para['contractStart'],
|
|
||||||
$para['contractStart'],
|
|
||||||
'Draft',
|
|
||||||
$user['M_UserID'],
|
|
||||||
$para['SupplierDownpaymentID']
|
|
||||||
]);
|
|
||||||
if (!$que) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("[Error] failed update supplier downpayment");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
# update status old po summary isActive to 'N' #
|
# update status old po summary isActive to 'N' #
|
||||||
$sql_active = "UPDATE purchase_order_summary SET
|
$sql_active = "UPDATE purchase_order_summary SET
|
||||||
PurchaseOrderSummaryIsActive = 'N'
|
PurchaseOrderSummaryIsActive = 'N'
|
||||||
WHERE PurchaseOrderSummaryPurchaseOrderID = ?
|
WHERE PurchaseOrderSummaryPurchaseOrderID = ?
|
||||||
AND PurchaseOrderSummaryIsActive = 'Y'";
|
AND PurchaseOrderSummaryIsActive = 'Y'";
|
||||||
$que_active = $this->db->query($sql_active, [$para['PurchaseOrderID']]);
|
$que_active = $this->db->query($sql_active, [$para['PurchaseOrderID']]);
|
||||||
if (!$que_active) {
|
if (!$que_active) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
@@ -956,19 +835,19 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sql_summary = "INSERT INTO purchase_order_summary (
|
$sql_summary = "INSERT INTO purchase_order_summary (
|
||||||
PurchaseOrderSummaryPurchaseOrderID,
|
PurchaseOrderSummaryPurchaseOrderID,
|
||||||
PurchaseOrderSummaryItemID,
|
PurchaseOrderSummaryItemID,
|
||||||
PurchaseOrderSummaryItemUnitID,
|
PurchaseOrderSummaryItemUnitID,
|
||||||
PurchaseOrderSummaryQty,
|
PurchaseOrderSummaryQty,
|
||||||
PurchaseOrderSummaryPrice,
|
PurchaseOrderSummaryPrice,
|
||||||
PurchaseOrderSummaryTotal,
|
PurchaseOrderSummaryTotal,
|
||||||
PurchaseOrderSummaryDiscountRupiah,
|
PurchaseOrderSummaryDiscountRupiah,
|
||||||
PurchaseOrderSummaryDiscountPercent,
|
PurchaseOrderSummaryDiscountPercent,
|
||||||
PurchaseOrderSummaryDiscountAmount,
|
PurchaseOrderSummaryDiscountAmount,
|
||||||
PurchaseOrderSummaryDiscountType,
|
PurchaseOrderSummaryDiscountType,
|
||||||
PurchaseOrderSummaryCreatedUserID,
|
PurchaseOrderSummaryCreatedUserID,
|
||||||
PurchaseOrderSummaryCreated
|
PurchaseOrderSummaryCreated
|
||||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,NOW())";
|
) VALUES (?,?,?,?,?,?,?,?,?,?,?,NOW())";
|
||||||
$que_summary = $this->db->query($sql_summary, [
|
$que_summary = $this->db->query($sql_summary, [
|
||||||
$para['PurchaseOrderID'], $obj['M_ItemID'], $obj['ItemUnitID'],
|
$para['PurchaseOrderID'], $obj['M_ItemID'], $obj['ItemUnitID'],
|
||||||
$obj['RequestQty'], $obj['SupplierPrice'], $obj['TempTotal'],
|
$obj['RequestQty'], $obj['SupplierPrice'], $obj['TempTotal'],
|
||||||
@@ -990,9 +869,9 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
|
|
||||||
# update status po detail isActive to 'N' #
|
# update status po detail isActive to 'N' #
|
||||||
$sql_active = "UPDATE purchase_order_detail SET
|
$sql_active = "UPDATE purchase_order_detail SET
|
||||||
PurchaseOrderDetailIsActive = 'N'
|
PurchaseOrderDetailIsActive = 'N'
|
||||||
WHERE PurchaseOrderDetailPurchaseOrderID = ?
|
WHERE PurchaseOrderDetailPurchaseOrderID = ?
|
||||||
AND PurchaseOrderDetailIsActive = 'Y'";
|
AND PurchaseOrderDetailIsActive = 'Y'";
|
||||||
$que_active = $this->db->query($sql_active, [$para['PurchaseOrderID']]);
|
$que_active = $this->db->query($sql_active, [$para['PurchaseOrderID']]);
|
||||||
if (!$que_active) {
|
if (!$que_active) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
@@ -1005,27 +884,26 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
$total = floatval($obj['SupplierPrice']) * floatval($obj['RequestQty']);
|
$total = floatval($obj['SupplierPrice']) * floatval($obj['RequestQty']);
|
||||||
|
|
||||||
$sql_detail = "INSERT INTO purchase_order_detail (
|
$sql_detail = "INSERT INTO purchase_order_detail (
|
||||||
PurchaseOrderDetailPurchaseOrderID,
|
PurchaseOrderDetailPurchaseOrderID,
|
||||||
PurchaseOrderDetailPurchaseSummaryID,
|
PurchaseOrderDetailPurchaseSummaryID,
|
||||||
PurchaseOrderDetailPurchaseRequestID,
|
PurchaseOrderDetailPurchaseRequestID,
|
||||||
PurchaseOrderDetailPurchaseRequestDetailID,
|
PurchaseOrderDetailPurchaseRequestDetailID,
|
||||||
PurchaseOrderDetailPurchaseRequestFlagID,
|
PurchaseOrderDetailPurchaseRequestFlagID,
|
||||||
PurchaseOrderDetailItemID,
|
PurchaseOrderDetailItemID,
|
||||||
PurchaseOrderDetailItemUnitID,
|
PurchaseOrderDetailItemUnitID,
|
||||||
PurchaseOrderDetailRequestQty,
|
PurchaseOrderDetailRequestQty,
|
||||||
PurchaseOrderDetailQty,
|
PurchaseOrderDetailQty,
|
||||||
PurchaseOrderDetailPrice,
|
PurchaseOrderDetailPrice,
|
||||||
PurchaseOrderDetailTotal,
|
PurchaseOrderDetailTotal,
|
||||||
PurchaseOrderDetailWarehouseID,
|
PurchaseOrderDetailUserID,
|
||||||
PurchaseOrderDetailUserID,
|
PurchaseOrderDetailCreatedUserID,
|
||||||
PurchaseOrderDetailCreatedUserID,
|
PurchaseOrderDetailCreated
|
||||||
PurchaseOrderDetailCreated
|
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())";
|
||||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())";
|
|
||||||
$que_detail = $this->db->query($sql_detail, [
|
$que_detail = $this->db->query($sql_detail, [
|
||||||
$para['PurchaseOrderID'], $obj['PurchaseSummaryID'], $obj['PurchaseRequestID'],
|
$para['PurchaseOrderID'], $obj['PurchaseSummaryID'], $obj['PurchaseRequestID'],
|
||||||
$obj['PurchaseRequestDetailID'], $obj['PurchaseRequestFlagID'],
|
$obj['PurchaseRequestDetailID'], $obj['PurchaseRequestFlagID'],
|
||||||
$obj['M_ItemID'], $obj['ItemUnitID'], $obj['OriginalQty'], $obj['RequestQty'],
|
$obj['M_ItemID'], $obj['ItemUnitID'], $obj['OriginalQty'], $obj['RequestQty'],
|
||||||
$obj['SupplierPrice'], $total, $para['gudangID'], $user['M_UserID'], $user['M_UserID']
|
$obj['SupplierPrice'], $total, $user['M_UserID'], $user['M_UserID']
|
||||||
]);
|
]);
|
||||||
if (!$que_detail) {
|
if (!$que_detail) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
@@ -1034,8 +912,8 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sql_flag = "UPDATE purchase_request_flag SET
|
$sql_flag = "UPDATE purchase_request_flag SET
|
||||||
PurchaseRequestFlagQtyProses = ?
|
PurchaseRequestFlagQtyProses = ?
|
||||||
WHERE PurchaseRequestFlagID = ?";
|
WHERE PurchaseRequestFlagID = ?";
|
||||||
$que_flag = $this->db->query($sql_flag, [
|
$que_flag = $this->db->query($sql_flag, [
|
||||||
$obj['RequestQty'], $obj['PurchaseRequestFlagID']
|
$obj['RequestQty'], $obj['PurchaseRequestFlagID']
|
||||||
]);
|
]);
|
||||||
@@ -1070,11 +948,11 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
$user = $this->sys_user;
|
$user = $this->sys_user;
|
||||||
|
|
||||||
$sql_detail = "SELECT
|
$sql_detail = "SELECT
|
||||||
PurchaseOrderDetailPurchaseRequestFlagID,
|
PurchaseOrderDetailPurchaseRequestFlagID,
|
||||||
PurchaseOrderDetailQty
|
PurchaseOrderDetailQty
|
||||||
FROM purchase_order_detail
|
FROM purchase_order_detail
|
||||||
WHERE PurchaseOrderDetailPurchaseOrderID = ?
|
WHERE PurchaseOrderDetailPurchaseOrderID = ?
|
||||||
AND PurchaseOrderDetailIsActive = 'Y'";
|
AND PurchaseOrderDetailIsActive = 'Y'";
|
||||||
$que_detail = $this->db->query($sql_detail, [$para['poID']]);
|
$que_detail = $this->db->query($sql_detail, [$para['poID']]);
|
||||||
if (!$que_detail) {
|
if (!$que_detail) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
@@ -1086,8 +964,8 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
/* reduce qty process in purchase order flag */
|
/* reduce qty process in purchase order flag */
|
||||||
foreach ($asset_detail as $key => $obj) {
|
foreach ($asset_detail as $key => $obj) {
|
||||||
$sql_updateflag = "UPDATE purchase_request_flag SET
|
$sql_updateflag = "UPDATE purchase_request_flag SET
|
||||||
PurchaseRequestFlagQtyProses = PurchaseRequestFlagQtyProses - ?
|
PurchaseRequestFlagQtyProses = PurchaseRequestFlagQtyProses - ?
|
||||||
WHERE PurchaseRequestFlagID = ?";
|
WHERE PurchaseRequestFlagID = ?";
|
||||||
$que_updateflag = $this->db->query($sql_updateflag, [
|
$que_updateflag = $this->db->query($sql_updateflag, [
|
||||||
$obj['PurchaseOrderDetailQty'],
|
$obj['PurchaseOrderDetailQty'],
|
||||||
$obj['PurchaseOrderDetailPurchaseRequestFlagID']
|
$obj['PurchaseOrderDetailPurchaseRequestFlagID']
|
||||||
@@ -1101,10 +979,10 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
|
|
||||||
/* soft delete purchase order detail */
|
/* soft delete purchase order detail */
|
||||||
$sql_deldetail = "UPDATE purchase_order_detail SET
|
$sql_deldetail = "UPDATE purchase_order_detail SET
|
||||||
PurchaseOrderDetailIsActive = 'N',
|
PurchaseOrderDetailIsActive = 'N',
|
||||||
PurchaseOrderDetailDeleted = NOW(),
|
PurchaseOrderDetailDeleted = NOW(),
|
||||||
PurchaseOrderDetailDeletedUserID = ?
|
PurchaseOrderDetailDeletedUserID = ?
|
||||||
WHERE PurchaseOrderDetailPurchaseOrderID = ?";
|
WHERE PurchaseOrderDetailPurchaseOrderID = ?";
|
||||||
$que_deldetail = $this->db->query($sql_deldetail, [
|
$que_deldetail = $this->db->query($sql_deldetail, [
|
||||||
$user['M_UserID'], $para['poID']
|
$user['M_UserID'], $para['poID']
|
||||||
]);
|
]);
|
||||||
@@ -1116,10 +994,10 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
|
|
||||||
/* soft delete purchase order summary */
|
/* soft delete purchase order summary */
|
||||||
$sql_delsummary = "UPDATE purchase_order_summary SET
|
$sql_delsummary = "UPDATE purchase_order_summary SET
|
||||||
PurchaseOrderSummaryIsActive = 'N',
|
PurchaseOrderSummaryIsActive = 'N',
|
||||||
PurchaseOrderSummaryDeleted = NOW(),
|
PurchaseOrderSummaryDeleted = NOW(),
|
||||||
PurchaseOrderSummaryDeletedUserID = ?
|
PurchaseOrderSummaryDeletedUserID = ?
|
||||||
WHERE PurchaseOrderSummaryPurchaseOrderID = ?";
|
WHERE PurchaseOrderSummaryPurchaseOrderID = ?";
|
||||||
$que_delsummary = $this->db->query($sql_delsummary, [
|
$que_delsummary = $this->db->query($sql_delsummary, [
|
||||||
$user['M_UserID'], $para['poID']
|
$user['M_UserID'], $para['poID']
|
||||||
]);
|
]);
|
||||||
@@ -1131,10 +1009,10 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
|
|
||||||
/* soft delete purchase_order_asset_contract */
|
/* soft delete purchase_order_asset_contract */
|
||||||
$sql_delcontract = "UPDATE purchase_order_asset_contract SET
|
$sql_delcontract = "UPDATE purchase_order_asset_contract SET
|
||||||
PurchaseOrderAssetContractIsActive = 'N',
|
PurchaseOrderAssetContractIsActive = 'N',
|
||||||
PurchaseOrderAssetContractLastUpdated = NOW()
|
PurchaseOrderAssetContractLastUpdated = NOW()
|
||||||
WHERE PurchaseOrderAssetContractID = ?
|
WHERE PurchaseOrderAssetContractID = ?
|
||||||
AND PurchaseOrderAssetContractPurchaseOrderID = ?";
|
AND PurchaseOrderAssetContractPurchaseOrderID = ?";
|
||||||
$que_delcontract = $this->db->query($sql_delcontract, [
|
$que_delcontract = $this->db->query($sql_delcontract, [
|
||||||
$para['contractID'], $para['poID']
|
$para['contractID'], $para['poID']
|
||||||
]);
|
]);
|
||||||
@@ -1144,40 +1022,12 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql_delattac = "UPDATE contract_asset_attachment SET
|
|
||||||
ContractAssetAttachmentIsActive = 'N'
|
|
||||||
WHERE ContractAssetAttachmentPurchaseOrderAssetContractID = ?
|
|
||||||
AND ContractAssetAttachmentPurchaseOrderID = ?";
|
|
||||||
$que_delattac = $this->db->query($sql_delattac, [
|
|
||||||
$para['contractID'], $para['poID']
|
|
||||||
]);
|
|
||||||
if (!$que_delattac) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("[Error] failed soft delete data attachment");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* soft delete supplier_downpayment */
|
|
||||||
$sql_deldp = "UPDATE supplier_downpayment SET
|
|
||||||
SupplierDownpaymentIsActive = 'N',
|
|
||||||
SupplierDownpaymentLastUpdatedUserID = ?
|
|
||||||
WHERE SupplierDownpaymentID = ?
|
|
||||||
AND SupplierDownpaymentIsActive = 'Y'";
|
|
||||||
$que_deldp = $this->db->query($sql_deldp, [
|
|
||||||
$user['M_UserID'], $para['SupplierDownpaymentID']
|
|
||||||
]);
|
|
||||||
if (!$que_deldp) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("[Error] failed soft delete supplier downpayment");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* soft delete purchase order */
|
/* soft delete purchase order */
|
||||||
$sql_delorder = "UPDATE purchase_order SET
|
$sql_delorder = "UPDATE purchase_order SET
|
||||||
PurchaseOrderIsActive = 'N',
|
PurchaseOrderIsActive = 'N',
|
||||||
PurchaseOrderDeleted = NOW(),
|
PurchaseOrderDeleted = NOW(),
|
||||||
PurchaseOrderDeletedUserID = ?
|
PurchaseOrderDeletedUserID = ?
|
||||||
WHERE PurchaseOrderID = ?";
|
WHERE PurchaseOrderID = ?";
|
||||||
$que_delorder = $this->db->query($sql_delorder, [
|
$que_delorder = $this->db->query($sql_delorder, [
|
||||||
$user['M_UserID'], $para['poID']
|
$user['M_UserID'], $para['poID']
|
||||||
]);
|
]);
|
||||||
@@ -1244,32 +1094,16 @@ class PurchaseOrderAset extends MY_Controller {
|
|||||||
ContractAssetAttachmentPurchaseOrderAssetContractID,
|
ContractAssetAttachmentPurchaseOrderAssetContractID,
|
||||||
ContractAssetAttachmentPurchaseOrderID,
|
ContractAssetAttachmentPurchaseOrderID,
|
||||||
ContractAssetAttachmentFileName,
|
ContractAssetAttachmentFileName,
|
||||||
ContractAssetAttachmentDate,
|
|
||||||
ContractAssetAttachmentCreated
|
ContractAssetAttachmentCreated
|
||||||
) VALUES (?,?,?,?,NOW())";
|
) VALUES (?,?,?,NOW())";
|
||||||
$que_insert = $this->db->query($sql_insert, [
|
$que_insert = $this->db->query($sql_insert, [
|
||||||
$para['contractID'], $para['poID'],
|
$para['contractID'], $para['poID'], $filename
|
||||||
$filename, $para['contractDate']
|
|
||||||
]);
|
]);
|
||||||
if (!$que_insert) {
|
if (!$que_insert) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
$this->sys_error_db("[Error] failed insert attachment table contract asset attachment");
|
$this->sys_error_db("[Error] failed insert attachment table contract asset attachment");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$attachmentID = $this->db->insert_id();
|
|
||||||
|
|
||||||
$sql_contract = "UPDATE purchase_order_asset_contract SET
|
|
||||||
PurchaseOrderAssetContractTAssetAttachmentID = ?
|
|
||||||
WHERE PurchaseOrderAssetContractID = ?
|
|
||||||
AND PurchaseOrderAssetContractPurchaseOrderID = ?";
|
|
||||||
$que_contract = $this->db->query($sql_contract, [
|
|
||||||
$attachmentID, $para['contractID'], $para['poID']
|
|
||||||
]);
|
|
||||||
if (!$que_contract) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("[Error] failed update attachmentid into asset contract table");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$error = $this->upload->display_errors();
|
$error = $this->upload->display_errors();
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1705,38 +1705,22 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql_invcoa = "SELECT
|
$sql_coa_inv = "SELECT
|
||||||
COALESCE(
|
CoaMapInventarisCoaID,
|
||||||
i.M_InventarisItemCoaMappingID,
|
CoaMapInventarisCoaNo,
|
||||||
g.M_InventarisCoaMappingID
|
CoaMapInventarisCoaDesc
|
||||||
) AS MappingID,
|
FROM coa_map_inventaris
|
||||||
COALESCE(
|
WHERE CoaMapInventarisM_InventarisGolID = ?
|
||||||
i.M_InventarisItemCoaMappingCoaInventarisID,
|
AND CoaMapInventarisIsActive = 'Y'";
|
||||||
g.M_InventarisCoaMappingCoaInventarisID
|
$que_coa_inv = $this->db->query($sql_coa_inv, [$item_cek['M_ItemM_InventarisGolID']]);
|
||||||
) AS CoaInventarisID,
|
if (!$que_coa_inv) {
|
||||||
c.coaDescription AS CoaInventarisDesc
|
|
||||||
FROM (SELECT 1) AS inventory
|
|
||||||
LEFT JOIN m_inventaris_item_coa_mapping i
|
|
||||||
ON i.M_InventarisItemCoaMappingM_ItemID = ?
|
|
||||||
AND i.M_InventarisItemCoaMappingIsActive = 'Y'
|
|
||||||
LEFT JOIN m_inventaris_coa_mapping g
|
|
||||||
ON g.M_InventarisCoaMappingM_InventarisGolID = ?
|
|
||||||
AND g.M_InventarisCoaMappingIsActive = 'Y'
|
|
||||||
LEFT JOIN coa c
|
|
||||||
ON c.coaID = COALESCE(i.M_InventarisItemCoaMappingCoaInventarisID, g.M_InventarisCoaMappingCoaInventarisID)
|
|
||||||
AND c.coaIsActive = 'Y'";
|
|
||||||
$que_invcoa = $this->db->query($sql_invcoa, [
|
|
||||||
$item_cek['M_ItemID'],
|
|
||||||
$item_cek['M_ItemM_InventarisGolID']
|
|
||||||
]);
|
|
||||||
if (!$que_invcoa) {
|
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
$this->sys_error_db("[Error] failed to get coa biaya item inventaris");
|
$this->sys_error_db("[Error] failed to get coa biaya item inventaris");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$iteminv_coa = $que_invcoa->row_array();
|
$iteminv_coa = $que_coa_inv->row_array();
|
||||||
|
|
||||||
if (empty($iteminv_coa['CoaInventarisID'])) {
|
if (empty($iteminv_coa['CoaMapInventarisCoaID'])) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
$this->sys_error_db("[Error] coa gol inventaris not found");
|
$this->sys_error_db("[Error] coa gol inventaris not found");
|
||||||
exit;
|
exit;
|
||||||
@@ -1756,8 +1740,8 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
) VALUES (?,?,?,?,?,?)";
|
) VALUES (?,?,?,?,?,?)";
|
||||||
$que_tx_jurnal = $this->db->query($sql_tx_jurnal, [
|
$que_tx_jurnal = $this->db->query($sql_tx_jurnal, [
|
||||||
$jurnal_ID,
|
$jurnal_ID,
|
||||||
$iteminv_coa['CoaInventarisID'],
|
$iteminv_coa['CoaMapInventarisCoaID'],
|
||||||
$iteminv_coa['CoaInventarisDesc'],
|
$iteminv_coa['CoaMapInventarisCoaDesc'],
|
||||||
$debet,
|
$debet,
|
||||||
0,
|
0,
|
||||||
$user['M_UserID']
|
$user['M_UserID']
|
||||||
@@ -1770,7 +1754,7 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
}
|
}
|
||||||
$juranl_tx_ID = $this->db->insert_id();
|
$juranl_tx_ID = $this->db->insert_id();
|
||||||
$each_desc[] = "- Add detail Jurnal debet {$item_cek['M_ItemDesc']}
|
$each_desc[] = "- Add detail Jurnal debet {$item_cek['M_ItemDesc']}
|
||||||
{$iteminv_coa['CoaInventarisDesc']} sejumlah {$this->formatRupiah($debet)}";
|
{$iteminv_coa['CoaMapInventarisCoaDesc']} sejumlah {$this->formatRupiah($debet)}";
|
||||||
|
|
||||||
# INSERT JURNAL ADDON #
|
# INSERT JURNAL ADDON #
|
||||||
$sql_addon_jurnal = "INSERT INTO jurnal_addon (
|
$sql_addon_jurnal = "INSERT INTO jurnal_addon (
|
||||||
@@ -1960,6 +1944,20 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
$this->sys_error_db("[Error] insert update stock");
|
$this->sys_error_db("[Error] insert update stock");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// insert stockid barcode barang
|
||||||
|
// $sql_update_barcode = "UPDATE t_barcode_barang SET
|
||||||
|
// T_BarcodeBarangStockID = ?
|
||||||
|
// WHERE T_BarcodeBarangReceiveOrderPoDetailID = ?";
|
||||||
|
// $qry_update_barcode = $this->db->query($sql_update_barcode, [
|
||||||
|
// $stock_ID,
|
||||||
|
// $detail['ReceiveOrderPoDetailID']
|
||||||
|
// ]);
|
||||||
|
// if (!$qry_update_barcode) {
|
||||||
|
// $this->db->trans_rollback();
|
||||||
|
// $this->sys_error_db("[Error] update barcode stockID", $this->db);
|
||||||
|
// exit;
|
||||||
|
// }
|
||||||
} else {
|
} else {
|
||||||
$sql_insert_stock = "INSERT INTO stock (
|
$sql_insert_stock = "INSERT INTO stock (
|
||||||
StockWarehouseAlmariID,
|
StockWarehouseAlmariID,
|
||||||
@@ -1987,9 +1985,23 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$stock_ID = $this->db->insert_id();
|
$stockID = $this->db->insert_id();
|
||||||
$stock_qty_ori = 0;
|
$stock_qty_ori = 0;
|
||||||
$stock_qty_end = intval($batch['qty']);
|
$stock_qty_end = intval($batch['qty']);
|
||||||
|
|
||||||
|
// insert stockid barcode barang
|
||||||
|
// $sql_update_barcode = "UPDATE t_barcode_barang SET
|
||||||
|
// T_BarcodeBarangStockID = ?
|
||||||
|
// WHERE T_BarcodeBarangReceiveOrderPoDetailID = ?";
|
||||||
|
// $qry_update_barcode = $this->db->query($sql_update_barcode, [
|
||||||
|
// $stockID,
|
||||||
|
// $detail['ReceiveOrderPoDetailID']
|
||||||
|
// ]);
|
||||||
|
// if (!$qry_update_barcode) {
|
||||||
|
// $this->db->trans_rollback();
|
||||||
|
// $this->sys_error_db("[Error] update barcode stockID", $this->db);
|
||||||
|
// exit;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert stock card
|
// insert stock card
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,90 +0,0 @@
|
|||||||
@host = https://accone.aplikasi.web.id/one-api
|
|
||||||
@date = 2026-07-14
|
|
||||||
@coaBayarID = 1110100001
|
|
||||||
@coaHutangID = 2110100030
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# JurnalPiCicilanOrderAset — Contoh Pemanggilan Endpoint
|
|
||||||
# =============================================================================
|
|
||||||
# Urutan penggunaan yang disarankan:
|
|
||||||
# 1. ListEligiblePurchaseOrderAssetContracts → lihat kontrak yang akan diproses
|
|
||||||
# 2. GenerateJournalsFromContracts (dryRun=Y) → simulasi tanpa simpan ke DB
|
|
||||||
# 3. GenerateJournalsFromContracts (dryRun=N) → generate jurnal sesungguhnya
|
|
||||||
# 4. CreateJournal → buat jurnal manual 1 per 1
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
|
|
||||||
### 1. Lihat kontrak aset yang eligible untuk dibuatkan jurnal bulan ini
|
|
||||||
GET {{host}}/index.php/mockup/scheduler/JurnalPiCicilanOrderAset/ListEligiblePurchaseOrderAssetContracts
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"startDate": "2026-07-01",
|
|
||||||
"endDate": "2026-07-31"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
### 2. Simulasi generate jurnal (dryRun=Y) — tidak menyimpan ke database
|
|
||||||
POST {{host}}/index.php/mockup/scheduler/JurnalPiCicilanOrderAset/GenerateJournalsFromContracts
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"date" : "{{date}}",
|
|
||||||
"dryRun" : "Y"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
### 3. Generate jurnal untuk semua kontrak eligible bulan ini (sesungguhnya)
|
|
||||||
POST {{host}}/index.php/mockup/scheduler/JurnalPiCicilanOrderAset/GenerateJournalsFromContracts
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"date" : "{{date}}",
|
|
||||||
"dryRun" : "N"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
### 4. Generate jurnal untuk 1 kontrak tertentu saja (contractID=99)
|
|
||||||
POST {{host}}/index.php/mockup/scheduler/JurnalPiCicilanOrderAset/GenerateJournalsFromContracts
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"date" : "{{date}}",
|
|
||||||
"dryRun" : "Y",
|
|
||||||
"contractID" : 00
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
### 5. Buat jurnal manual (1 jurnal, input detail sendiri)
|
|
||||||
POST {{host}}/index.php/mockup/scheduler/JurnalPiCicilanOrderAset/CreateJournal
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"date" : "{{date}}",
|
|
||||||
"branchCode" : "BA",
|
|
||||||
"regionalID" : 8,
|
|
||||||
"branchCompanyID": 1,
|
|
||||||
"jurnalTypeID" : 11,
|
|
||||||
"title" : "Jurnal PI Cicilan Order Aset",
|
|
||||||
"description" : "Cicilan ke-1 dari 12 | Kontrak Kendaraan Operasional | Periode 2026-07",
|
|
||||||
"details" : [
|
|
||||||
{
|
|
||||||
"coaID" : {{coaHutangID}},
|
|
||||||
"description": "Hutang cicilan aset - Kendaraan Operasional",
|
|
||||||
"debit" : 15000000,
|
|
||||||
"credit" : 0,
|
|
||||||
"addonCode" : "PIINSTALMENT",
|
|
||||||
"addonValue" : "42",
|
|
||||||
"mItemID" : 123
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"coaID" : {{coaBayarID}},
|
|
||||||
"description": "Pembayaran cicilan aset - Kendaraan Operasional",
|
|
||||||
"debit" : 0,
|
|
||||||
"credit" : 15000000,
|
|
||||||
"addonCode" : "PIINSTALMENT",
|
|
||||||
"addonValue" : "42",
|
|
||||||
"mItemID" : 123
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,970 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JurnalPiCicilanOrderAset
|
|
||||||
*
|
|
||||||
* Controller scheduler untuk membuat jurnal akuntansi atas Purchase Invoice (PI)
|
|
||||||
* cicilan order aset secara otomatis.
|
|
||||||
*
|
|
||||||
* Alur bisnis proses:
|
|
||||||
* 1. Validasi parameter input (tanggal, branchCode, title, description, details)
|
|
||||||
* 2. Insert header jurnal ke tabel `jurnal`
|
|
||||||
* - Nomor jurnal di-generate via fn_numbering('J')
|
|
||||||
* - Tipe jurnal: PAYMENT
|
|
||||||
* - Berisi: title, description, tanggal, regionalID, kode cabang, branchCompanyID
|
|
||||||
* 3. Insert baris transaksi ke tabel `jurnal_tx` (untuk setiap baris cicilan)
|
|
||||||
* - Referensi ke jurnalID header
|
|
||||||
* - COA (Chart of Account) dan deskripsinya:
|
|
||||||
* * Sisi hutang cicilan → nilai DEBIT (diambil dari HutangCoaID di fa_class)
|
|
||||||
* * Sisi pembayaran cicilan → nilai KREDIT (diambil dari ItemCoaID di fa_class)
|
|
||||||
* 4. Insert data tambahan ke tabel `jurnal_addon` (jika ada addonValue atau mItemID)
|
|
||||||
* - Referensi ke jurnalID dan jurnalTxID
|
|
||||||
* - Berisi: addonCode (default: "PIINSTALMENT"), addonValue, mItemID
|
|
||||||
*
|
|
||||||
* Endpoint:
|
|
||||||
* POST /mockup/scheduler/JurnalPiCicilanOrderAset/CreateJournal
|
|
||||||
* POST /mockup/scheduler/JurnalPiCicilanOrderAset/GenerateJournalsFromContracts
|
|
||||||
* GET /mockup/scheduler/JurnalPiCicilanOrderAset/ListEligiblePurchaseOrderAssetContracts
|
|
||||||
*/
|
|
||||||
class JurnalPiCicilanOrderAset extends MY_Controller
|
|
||||||
{
|
|
||||||
var $db;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Endpoint default — menampilkan nama controller sebagai penanda aktif.
|
|
||||||
*/
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
echo "Jurnal PI Cicilan Order Aset";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Konstruktor — inisialisasi parent controller.
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CreateJournal — Membuat jurnal PI cicilan order aset.
|
|
||||||
*
|
|
||||||
* Proses bisnis:
|
|
||||||
* 1. Validasi semua parameter wajib: date, branchCode, title, description, details
|
|
||||||
* 2. Ambil periodeID dari tanggal transaksi (tabel periode)
|
|
||||||
* 3. Ambil regionalID dari branchCode (tabel m_branch)
|
|
||||||
* 4. Ambil branchCompanyID dari branchCode (tabel m_branch_companydetail)
|
|
||||||
* 5. Ambil jurnalTypeID dari kode tipe jurnal (default: "PAYMENT")
|
|
||||||
* 6. Generate nomor jurnal otomatis via fn_numbering('J')
|
|
||||||
* 7. Validasi balance: total debit harus sama dengan total credit
|
|
||||||
* 8. INSERT header jurnal ke tabel `jurnal`:
|
|
||||||
* - jurnalNo : nomor jurnal hasil generate
|
|
||||||
* - jurnalJurnalTypeID: tipe PAYMENT
|
|
||||||
* - jurnalTitle : judul jurnal
|
|
||||||
* - jurnalDescription: keterangan jurnal
|
|
||||||
* - jurnalDate : tanggal transaksi
|
|
||||||
* - JurnalS_RegionalID: ID regional cabang
|
|
||||||
* - jurnalM_BranchCode: kode cabang
|
|
||||||
* 9. Untuk setiap baris detail, INSERT ke `jurnal_tx`:
|
|
||||||
* - jurnalTxJurnalID : referensi ke header jurnal
|
|
||||||
* - jurnalTxCoaID : COA yang digunakan (hutang cicilan / kas/bank)
|
|
||||||
* - jurnalTxDescription: keterangan baris (nama cicilan/aset)
|
|
||||||
* - jurnalTxDebit : nilai hutang (sisi debit)
|
|
||||||
* - jurnalTxCredit : nilai bayar (sisi kredit)
|
|
||||||
* 10. Jika ada addonValue atau mItemID, INSERT ke `jurnal_addon`:
|
|
||||||
* - jurnalAddOnJurnalID : referensi ke header jurnal
|
|
||||||
* - jurnalAddOnJurnalTxID: referensi ke baris jurnal_tx
|
|
||||||
* - jurnalAddOnCode : kode addon (default: "PIINSTALMENT")
|
|
||||||
* - jurnalAddOnValue : nilai tambahan (misal: nomor PI/kontrak)
|
|
||||||
* - jurnalAddOnM_ItemID : ID item aset yang terkait
|
|
||||||
*
|
|
||||||
* Parameter (POST JSON):
|
|
||||||
* - date : Tanggal jurnal (YYYY-MM-DD). Default: hari ini.
|
|
||||||
* - branchCode : Kode cabang. WAJIB.
|
|
||||||
* - title : Judul jurnal. WAJIB.
|
|
||||||
* - description : Keterangan jurnal. WAJIB.
|
|
||||||
* - details : Array baris transaksi. WAJIB, minimal 1 baris.
|
|
||||||
* - coaID : ID Chart of Account. WAJIB per baris.
|
|
||||||
* - description : Keterangan baris.
|
|
||||||
* - debit : Nilai debit (hutang cicilan).
|
|
||||||
* - credit : Nilai kredit (pembayaran cicilan).
|
|
||||||
* - addonValue : (opsional) Nilai addon, misal nomor PI.
|
|
||||||
* - mItemID : (opsional) ID item aset.
|
|
||||||
* - addonCode : (opsional) Kode addon. Default: "PIINSTALMENT".
|
|
||||||
* - periodeID : (opsional) ID periode. Default: diambil dari tanggal.
|
|
||||||
* - regionalID : (opsional) ID regional. Default: diambil dari branchCode.
|
|
||||||
* - branchCompanyID: (opsional) ID branch company. Default: diambil dari branchCode.
|
|
||||||
* - jurnalTypeID : (opsional) ID tipe jurnal. Default: diambil dari jurnalTypeCode.
|
|
||||||
* - jurnalTypeCode: (opsional) Kode tipe jurnal. Default: "PAYMENT".
|
|
||||||
* - userID : ID user yang membuat jurnal.
|
|
||||||
*
|
|
||||||
* @return JSON { jurnalID, jurnalNo, detailCount, addonCount }
|
|
||||||
*/
|
|
||||||
public function CreateJournal()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$para = $this->sys_input;
|
|
||||||
|
|
||||||
$date = isset($para["date"]) && $para["date"] != "" ? $para["date"] : date("Y-m-d");
|
|
||||||
if (!$this->isValidDate($date)) {
|
|
||||||
throw new Exception("Format tanggal tidak valid. Gunakan YYYY-MM-DD.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$branchCode = isset($para["branchCode"]) ? trim($para["branchCode"]) : "";
|
|
||||||
if ($branchCode == "") {
|
|
||||||
throw new Exception("branchCode wajib diisi.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$title = isset($para["title"]) ? trim($para["title"]) : "";
|
|
||||||
if ($title == "") {
|
|
||||||
throw new Exception("title wajib diisi.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$description = isset($para["description"]) ? trim($para["description"]) : "";
|
|
||||||
if ($description == "") {
|
|
||||||
throw new Exception("description wajib diisi.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$details = isset($para["details"]) && is_array($para["details"]) ? $para["details"] : [];
|
|
||||||
if (count($details) == 0) {
|
|
||||||
throw new Exception("details wajib diisi minimal 1 baris.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$periodeID = isset($para["periodeID"]) && (int) $para["periodeID"] > 0
|
|
||||||
? (int) $para["periodeID"]
|
|
||||||
: $this->getPeriodeIDByDate($date);
|
|
||||||
if ($periodeID <= 0) {
|
|
||||||
throw new Exception("Periode jurnal tidak ditemukan untuk tanggal {$date}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$regionalID = isset($para["regionalID"]) && (int) $para["regionalID"] > 0
|
|
||||||
? (int) $para["regionalID"]
|
|
||||||
: $this->getRegionalIDByBranchCode($branchCode);
|
|
||||||
if ($regionalID <= 0) {
|
|
||||||
throw new Exception("regionalID wajib diisi atau harus bisa diturunkan dari branchCode.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$branchCompanyID = isset($para["branchCompanyID"]) && (int) $para["branchCompanyID"] > 0
|
|
||||||
? (int) $para["branchCompanyID"]
|
|
||||||
: $this->getBranchCompanyIDByBranchCode($branchCode);
|
|
||||||
if ($branchCompanyID <= 0) {
|
|
||||||
throw new Exception("branchCompanyID wajib diisi atau harus bisa diturunkan dari branchCode.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$jurnalTypeID = isset($para["jurnalTypeID"]) && (int) $para["jurnalTypeID"] > 0
|
|
||||||
? (int) $para["jurnalTypeID"]
|
|
||||||
: $this->getJurnalTypeID(isset($para["jurnalTypeCode"]) && $para["jurnalTypeCode"] != "" ? $para["jurnalTypeCode"] : "PAYMENT");
|
|
||||||
if ($jurnalTypeID <= 0) {
|
|
||||||
throw new Exception("jurnalTypeID / jurnalTypeCode tidak valid.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$userID = 0;
|
|
||||||
|
|
||||||
$result = $this->insertJournal(
|
|
||||||
$date,
|
|
||||||
$branchCode,
|
|
||||||
$title,
|
|
||||||
$description,
|
|
||||||
$details,
|
|
||||||
$periodeID,
|
|
||||||
$regionalID,
|
|
||||||
$branchCompanyID,
|
|
||||||
$jurnalTypeID,
|
|
||||||
$userID
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($result === false) {
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->sys_ok($result);
|
|
||||||
} catch (Exception $exc) {
|
|
||||||
$this->sys_error($exc->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GenerateJournalsFromContracts — Generate jurnal otomatis dari seluruh kontrak aset eligible.
|
|
||||||
*
|
|
||||||
* Fungsi ini mengintegrasikan data dari getEligiblePurchaseOrderAssetContracts()
|
|
||||||
* dengan proses pembuatan jurnal (insertJournal()) secara otomatis.
|
|
||||||
*
|
|
||||||
* Untuk setiap kontrak yang eligible, dibuat 1 jurnal dengan 2 baris transaksi:
|
|
||||||
* - Baris DEBIT : COA hutang cicilan (HutangCoaID dari fa_class) — mencatat hutang cicilan
|
|
||||||
* - Baris KREDIT : COA kas/bank/aset (ItemCoaID dari fa_class) — mencatat pembayaran cicilan
|
|
||||||
* Addon (jurnal_addon): menyimpan ID kontrak sebagai addonValue dan ItemID sebagai mItemID
|
|
||||||
*
|
|
||||||
* Parameter (POST JSON):
|
|
||||||
* - date : Tanggal jurnal (YYYY-MM-DD). Default: hari ini.
|
|
||||||
* - userID : ID user yang membuat jurnal.
|
|
||||||
* - dryRun : "Y" = simulasi tanpa simpan ke DB. Default: "N".
|
|
||||||
* - contractID : (opsional) Filter hanya 1 kontrak tertentu.
|
|
||||||
*
|
|
||||||
* Syarat kontrak dilewati (skipped):
|
|
||||||
* - branchCode kosong (data cabang belum lengkap)
|
|
||||||
* - COA hutang (HutangCoaID) tidak ditemukan di fa_class
|
|
||||||
* - COA bayar/aset (ItemCoaID) tidak ditemukan di fa_class
|
|
||||||
*
|
|
||||||
* @return JSON { tanggal, totalDibuat, totalDilewati, daftarDibuat[], daftarDilewati[] }
|
|
||||||
*/
|
|
||||||
public function GenerateJournalsFromContracts()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$para = $this->sys_input;
|
|
||||||
|
|
||||||
$date = isset($para["date"]) && $para["date"] != "" ? $para["date"] : date("Y-m-d");
|
|
||||||
if (!$this->isValidDate($date)) {
|
|
||||||
throw new Exception("Format tanggal tidak valid. Gunakan YYYY-MM-DD.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$userID = 0;
|
|
||||||
$dryRun = isset($para["dryRun"]) && ($para["dryRun"] === true || $para["dryRun"] == "Y" || $para["dryRun"] == "1");
|
|
||||||
$filterContractID = isset($para["contractID"]) && (int) $para["contractID"] > 0
|
|
||||||
? (int) $para["contractID"]
|
|
||||||
: null;
|
|
||||||
|
|
||||||
$monthStart = date("Y-m-01", strtotime($date));
|
|
||||||
$monthEnd = date("Y-m-t", strtotime($date));
|
|
||||||
|
|
||||||
// Ambil semua kontrak yang eligible untuk periode bulan ini
|
|
||||||
$contracts = $this->getEligiblePurchaseOrderAssetContracts($monthStart, $monthEnd);
|
|
||||||
|
|
||||||
$dibuat = [];
|
|
||||||
$dilewati = [];
|
|
||||||
|
|
||||||
foreach ($contracts as $kontrak) {
|
|
||||||
$contractID = (int) $kontrak["PurchaseOrderAssetContractID"];
|
|
||||||
|
|
||||||
// Filter 1 kontrak jika diminta
|
|
||||||
if ($filterContractID !== null && $contractID !== $filterContractID) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$branchCode = $kontrak["M_BranchCode"] ?? "";
|
|
||||||
$regionalID = (int) ($kontrak["M_BranchS_RegionalID"] ?? 0);
|
|
||||||
$branchCompanyID = (int) ($kontrak["M_BranchCompanyID"] ?? 0);
|
|
||||||
$coaHutangID = (int) ($kontrak["HutangCoaID"] ?? 0); // COA debit dari fa_class (Fa_ClassHutangCoaID)
|
|
||||||
$coaBayarID = (int) ($kontrak["ItemCoaID"] ?? 0); // COA kredit dari fa_class (Fa_ClassCoaID)
|
|
||||||
$jumlah = (float) $kontrak["PurchaseOrderAssetContractInstallmentPayAmount"];
|
|
||||||
$itemID = (int) ($kontrak["PurchaseOrderSummaryItemID"] ?? 0);
|
|
||||||
$namaKontrak = $kontrak["PurchaseOrderAssetContractName"] != ""
|
|
||||||
? $kontrak["PurchaseOrderAssetContractName"]
|
|
||||||
: "Kontrak ID {$contractID}";
|
|
||||||
$nomorPO = $kontrak["PurchaseOrderNumber"] ?? "";
|
|
||||||
$cicilanKe = ((int) $kontrak["PurchaseOrderAssetContractInstallmentPaid"]) + 1;
|
|
||||||
$totalCicilan = (int) $kontrak["PurchaseOrderAssetContractInstallmentNumber"];
|
|
||||||
$periode = date("Y-m", strtotime($date));
|
|
||||||
$invoiceNumber = $kontrak["SupplierInvoiceNumber"] ?? "";
|
|
||||||
$invoiceID = (int) ($kontrak["SupplierInvoiceID"] ?? 0);
|
|
||||||
|
|
||||||
// Validasi: branchCode harus ada
|
|
||||||
if ($branchCode == "") {
|
|
||||||
$dilewati[] = [
|
|
||||||
"kontrakID" => $contractID,
|
|
||||||
"alasan" => "Kode cabang (branchCode) tidak ditemukan. Pastikan warehouse PO sudah terhubung ke data cabang."
|
|
||||||
];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validasi: COA hutang harus ada (untuk sisi DEBIT)
|
|
||||||
if ($coaHutangID <= 0) {
|
|
||||||
$dilewati[] = [
|
|
||||||
"kontrakID" => $contractID,
|
|
||||||
"branchCode" => $branchCode,
|
|
||||||
"alasan" => "COA hutang tidak ditemukan. Pastikan item PO memiliki Fa_Class dengan Fa_ClassHutangCoaID."
|
|
||||||
];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validasi: COA bayar/aset harus ada (untuk sisi KREDIT)
|
|
||||||
if ($coaBayarID <= 0) {
|
|
||||||
$dilewati[] = [
|
|
||||||
"kontrakID" => $contractID,
|
|
||||||
"branchCode" => $branchCode,
|
|
||||||
"alasan" => "COA bayar/aset tidak ditemukan. Pastikan item PO memiliki Fa_Class dengan Fa_ClassCoaID."
|
|
||||||
];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mode simulasi: catat tanpa simpan ke DB
|
|
||||||
if ($dryRun) {
|
|
||||||
$dibuat[] = [
|
|
||||||
"kontrakID" => $contractID,
|
|
||||||
"branchCode" => $branchCode,
|
|
||||||
"namaKontrak" => $namaKontrak,
|
|
||||||
"invoiceNumber" => $invoiceNumber,
|
|
||||||
"jumlah" => $jumlah,
|
|
||||||
"coaHutangID" => $coaHutangID,
|
|
||||||
"coaBayarID" => $coaBayarID,
|
|
||||||
"keterangan" => "Mode simulasi (dryRun), data tidak disimpan."
|
|
||||||
];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Susun title dan description jurnal
|
|
||||||
$title = "PI Cicilan Aset - {$invoiceNumber}";
|
|
||||||
$description = "Jurnal cicilan ke-{$cicilanKe} dari {$totalCicilan} | {$namaKontrak} | PO: {$nomorPO} | Periode {$periode}";
|
|
||||||
|
|
||||||
// Ambil periodeID dari tanggal
|
|
||||||
$periodeID = $this->getPeriodeIDByDate($date);
|
|
||||||
if ($periodeID <= 0) {
|
|
||||||
$dilewati[] = [
|
|
||||||
"kontrakID" => $contractID,
|
|
||||||
"branchCode" => $branchCode,
|
|
||||||
"alasan" => "Periode jurnal tidak ditemukan untuk tanggal {$date}."
|
|
||||||
];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ambil jurnalTypeID untuk tipe PAYMENT
|
|
||||||
$jurnalTypeID = $this->getJurnalTypeID("PAYMENTINV");
|
|
||||||
if ($jurnalTypeID <= 0) {
|
|
||||||
$dilewati[] = [
|
|
||||||
"kontrakID" => $contractID,
|
|
||||||
"branchCode" => $branchCode,
|
|
||||||
"alasan" => "Tipe jurnal PAYMENT tidak ditemukan di tabel jurnal_type."
|
|
||||||
];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ambil description detail dari database fa_class dengan fallback jika kosong
|
|
||||||
$descHutang = isset($kontrak["HutangCoaDesc"]) && $kontrak["HutangCoaDesc"] != ""
|
|
||||||
? $kontrak["HutangCoaDesc"]
|
|
||||||
: "Hutang cicilan aset - {$namaKontrak}";
|
|
||||||
$descBayar = isset($kontrak["ItemCoaDesc"]) && $kontrak["ItemCoaDesc"] != ""
|
|
||||||
? $kontrak["ItemCoaDesc"]
|
|
||||||
: "Pembayaran cicilan aset - {$namaKontrak}";
|
|
||||||
|
|
||||||
// Susun 2 baris detail jurnal:
|
|
||||||
// Baris 1 — DEBIT : hutang cicilan aset (COA dari fa_class)
|
|
||||||
// Baris 2 — KREDIT : pembayaran cicilan (COA kas/bank dari parameter)
|
|
||||||
$details = [
|
|
||||||
[
|
|
||||||
"coaID" => $coaHutangID,
|
|
||||||
"description" => $descHutang,
|
|
||||||
"debit" => $jumlah,
|
|
||||||
"credit" => 0,
|
|
||||||
"addonValue" => $invoiceNumber,
|
|
||||||
"mItemID" => $itemID,
|
|
||||||
"addonCode" => "PIINSTALMENT"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"coaID" => $coaBayarID,
|
|
||||||
"description" => $descBayar,
|
|
||||||
"debit" => 0,
|
|
||||||
"credit" => $jumlah,
|
|
||||||
"addonValue" => $invoiceNumber,
|
|
||||||
"mItemID" => $itemID,
|
|
||||||
"addonCode" => "PIINSTALMENT"
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
// Panggil insertJournal() untuk simpan ke DB
|
|
||||||
$result = $this->insertJournal(
|
|
||||||
$date,
|
|
||||||
$branchCode,
|
|
||||||
$title,
|
|
||||||
$description,
|
|
||||||
$details,
|
|
||||||
$periodeID,
|
|
||||||
$regionalID,
|
|
||||||
$branchCompanyID,
|
|
||||||
$jurnalTypeID,
|
|
||||||
$userID
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($result === false) {
|
|
||||||
$dilewati[] = [
|
|
||||||
"kontrakID" => $contractID,
|
|
||||||
"branchCode" => $branchCode,
|
|
||||||
"alasan" => "Gagal menyimpan jurnal ke database."
|
|
||||||
];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$dibuat[] = [
|
|
||||||
"kontrakID" => $contractID,
|
|
||||||
"branchCode" => $branchCode,
|
|
||||||
"namaKontrak" => $namaKontrak,
|
|
||||||
"jurnalID" => $result["jurnalID"],
|
|
||||||
"jurnalNo" => $result["jurnalNo"],
|
|
||||||
"jumlah" => $jumlah
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->sys_ok([
|
|
||||||
"tanggal" => $date,
|
|
||||||
"periodeAwal" => $monthStart,
|
|
||||||
"periodeAkhir" => $monthEnd,
|
|
||||||
"totalDibuat" => count($dibuat),
|
|
||||||
"totalDilewati" => count($dilewati),
|
|
||||||
"daftarDibuat" => $dibuat,
|
|
||||||
"daftarDilewati" => $dilewati
|
|
||||||
]);
|
|
||||||
} catch (Exception $exc) {
|
|
||||||
$this->sys_error($exc->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ListEligiblePurchaseOrderAssetContracts — Menampilkan daftar kontrak aset
|
|
||||||
* yang memenuhi syarat untuk dibuatkan jurnal PI cicilan pada periode tertentu.
|
|
||||||
*
|
|
||||||
* Syarat kontrak eligible:
|
|
||||||
* - Kontrak aktif dan berstatus "belum lunas"
|
|
||||||
* - Nilai cicilan > 0
|
|
||||||
* - Jumlah cicilan terbayar < total cicilan
|
|
||||||
* - Tanggal kontrak masuk dalam rentang startDate–endDate
|
|
||||||
* - PO sudah berstatus Approved
|
|
||||||
* - Barang sudah diterima (receive_order_po sudah confirmed)
|
|
||||||
*
|
|
||||||
* Endpoint ini digunakan untuk preview/verifikasi sebelum proses generate jurnal
|
|
||||||
* dijalankan secara massal oleh CRON.
|
|
||||||
*
|
|
||||||
* Parameter (GET/POST):
|
|
||||||
* - startDate : Awal periode (YYYY-MM-DD). Default: tanggal 1 bulan ini.
|
|
||||||
* - endDate : Akhir periode (YYYY-MM-DD). Default: tanggal akhir bulan ini.
|
|
||||||
*
|
|
||||||
* @return JSON { startDate, endDate, total, records[] }
|
|
||||||
*/
|
|
||||||
public function ListEligiblePurchaseOrderAssetContracts()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$para = $this->sys_input;
|
|
||||||
|
|
||||||
$startDate = isset($para["startDate"]) && $para["startDate"] != ""
|
|
||||||
? $para["startDate"]
|
|
||||||
: date("Y-m-01");
|
|
||||||
$endDate = isset($para["endDate"]) && $para["endDate"] != ""
|
|
||||||
? $para["endDate"]
|
|
||||||
: date("Y-m-t");
|
|
||||||
|
|
||||||
if (!$this->isValidDate($startDate) || !$this->isValidDate($endDate)) {
|
|
||||||
throw new Exception("Format tanggal tidak valid. Gunakan YYYY-MM-DD.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strtotime($startDate) > strtotime($endDate)) {
|
|
||||||
throw new Exception("startDate tidak boleh lebih besar dari endDate");
|
|
||||||
}
|
|
||||||
|
|
||||||
$records = $this->getEligiblePurchaseOrderAssetContracts($startDate, $endDate);
|
|
||||||
|
|
||||||
$this->sys_ok([
|
|
||||||
"startDate" => $startDate,
|
|
||||||
"endDate" => $endDate,
|
|
||||||
"total" => count($records),
|
|
||||||
"records" => $records
|
|
||||||
]);
|
|
||||||
} catch (Exception $exc) {
|
|
||||||
$this->sys_error($exc->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// FUNGSI PRIVATE / HELPER
|
|
||||||
// =========================================================================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* insertJournal — Menyimpan 1 jurnal lengkap ke database (header + tx + addon).
|
|
||||||
*
|
|
||||||
* Fungsi internal yang dipanggil oleh CreateJournal() dan GenerateJournalsFromContracts().
|
|
||||||
* Mengelola transaksi DB secara penuh (begin → commit/rollback).
|
|
||||||
*
|
|
||||||
* Alur:
|
|
||||||
* 1. Validasi balance debit == kredit
|
|
||||||
* 2. Generate nomor jurnal via fn_numbering('J')
|
|
||||||
* 3. INSERT header ke tabel `jurnal`
|
|
||||||
* 4. INSERT baris transaksi ke `jurnal_tx` (per detail)
|
|
||||||
* 5. INSERT addon ke `jurnal_addon` (jika addonValue atau mItemID ada)
|
|
||||||
*
|
|
||||||
* @param string $date Tanggal jurnal (YYYY-MM-DD)
|
|
||||||
* @param string $branchCode Kode cabang
|
|
||||||
* @param string $title Judul jurnal
|
|
||||||
* @param string $description Keterangan jurnal
|
|
||||||
* @param array $details Baris transaksi [ coaID, description, debit, credit, addonValue?, mItemID?, addonCode? ]
|
|
||||||
* @param int $periodeID ID periode akuntansi
|
|
||||||
* @param int $regionalID ID regional
|
|
||||||
* @param int $branchCompanyID ID branch company
|
|
||||||
* @param int $jurnalTypeID ID tipe jurnal
|
|
||||||
* @param int $userID ID user pembuat jurnal
|
|
||||||
*
|
|
||||||
* @return array|false Array { jurnalID, jurnalNo, detailCount, addonCount }, atau false jika gagal
|
|
||||||
*/
|
|
||||||
private function insertJournal($date, $branchCode, $title, $description, $details, $periodeID, $regionalID, $branchCompanyID, $jurnalTypeID, $userID)
|
|
||||||
{
|
|
||||||
// Validasi balance sebelum menyimpan
|
|
||||||
$totalDebit = 0;
|
|
||||||
$totalCredit = 0;
|
|
||||||
foreach ($details as $idx => $detail) {
|
|
||||||
$debit = isset($detail["debit"]) ? (float) $detail["debit"] : 0;
|
|
||||||
$credit = isset($detail["credit"]) ? (float) $detail["credit"] : 0;
|
|
||||||
if ($debit < 0 || $credit < 0) {
|
|
||||||
$this->sys_error("Nilai debit/credit tidak boleh negatif pada detail ke-" . ($idx + 1));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$totalDebit += $debit;
|
|
||||||
$totalCredit += $credit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (round($totalDebit, 2) !== round($totalCredit, 2)) {
|
|
||||||
$this->sys_error("Total debit dan credit harus sama. Debit={$totalDebit}, Credit={$totalCredit}");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$jurnalNo = $this->generateJournalNumber();
|
|
||||||
if ($jurnalNo === false || $jurnalNo == "") {
|
|
||||||
$this->sys_error("Gagal generate nomor jurnal.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->db->trans_begin();
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
// INSERT header jurnal ke tabel `jurnal`
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
$sqlHeader = "INSERT INTO jurnal (
|
|
||||||
jurnalM_BranchCompanyID,
|
|
||||||
JurnalS_RegionalID,
|
|
||||||
jurnalM_BranchCode,
|
|
||||||
jurnalperiodeID,
|
|
||||||
jurnalNo,
|
|
||||||
jurnalTitle,
|
|
||||||
jurnalDescription,
|
|
||||||
jurnalDate,
|
|
||||||
jurnalJurnalTypeID,
|
|
||||||
jurnalCreated,
|
|
||||||
jurnalM_UserID
|
|
||||||
) VALUES (?,?,?,?,?,?,?,?,?,NOW(),?)";
|
|
||||||
|
|
||||||
$qryHeader = $this->db->query($sqlHeader, [
|
|
||||||
$branchCompanyID,
|
|
||||||
$regionalID,
|
|
||||||
$branchCode,
|
|
||||||
$periodeID,
|
|
||||||
$jurnalNo,
|
|
||||||
$title,
|
|
||||||
$description,
|
|
||||||
$date,
|
|
||||||
$jurnalTypeID,
|
|
||||||
$userID
|
|
||||||
]);
|
|
||||||
if (!$qryHeader) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("Gagal insert jurnal header.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$jurnalID = $this->db->insert_id();
|
|
||||||
$createdAddonCount = 0;
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
// INSERT baris transaksi ke tabel `jurnal_tx` (per baris cicilan)
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
foreach ($details as $idx => $detail) {
|
|
||||||
$coaID = isset($detail["coaID"]) ? (int) $detail["coaID"] : 0;
|
|
||||||
$descriptionTx = isset($detail["description"]) ? trim($detail["description"]) : "";
|
|
||||||
$debit = isset($detail["debit"]) ? (float) $detail["debit"] : 0;
|
|
||||||
$credit = isset($detail["credit"]) ? (float) $detail["credit"] : 0;
|
|
||||||
|
|
||||||
if ($coaID <= 0) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("coaID wajib diisi pada detail ke-" . ($idx + 1));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sisi debit = hutang cicilan (COA hutang aset dari fa_class)
|
|
||||||
// Sisi kredit = pembayaran cicilan (COA kas/bank)
|
|
||||||
$sqlTx = "INSERT INTO jurnal_tx (
|
|
||||||
jurnalTxJurnalID,
|
|
||||||
jurnalTxCoaID,
|
|
||||||
jurnalTxDescription,
|
|
||||||
jurnalTxDebit,
|
|
||||||
jurnalTxCredit,
|
|
||||||
jurnalTxCreated,
|
|
||||||
jurnalTxM_UserID
|
|
||||||
) VALUES (?,?,?,?,?,NOW(),?)";
|
|
||||||
|
|
||||||
$qryTx = $this->db->query($sqlTx, [
|
|
||||||
$jurnalID,
|
|
||||||
$coaID,
|
|
||||||
$descriptionTx,
|
|
||||||
$debit,
|
|
||||||
$credit,
|
|
||||||
$userID
|
|
||||||
]);
|
|
||||||
if (!$qryTx) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("Gagal insert jurnal_tx pada detail ke-" . ($idx + 1));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$jurnalTxID = $this->db->insert_id();
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
// INSERT addon ke `jurnal_addon` (jika addonValue atau mItemID ada)
|
|
||||||
// addonValue = ID kontrak aset (untuk tracing)
|
|
||||||
// mItemID = ID item aset dari purchase_order_summary
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
$addonValue = isset($detail["addonValue"]) ? trim($detail["addonValue"]) : "";
|
|
||||||
$mItemID = isset($detail["mItemID"]) ? (int) $detail["mItemID"] : 0;
|
|
||||||
$addonCode = isset($detail["addonCode"]) && $detail["addonCode"] != "" ? trim($detail["addonCode"]) : "PIINSTALMENT";
|
|
||||||
|
|
||||||
if ($addonValue != "" || $mItemID > 0) {
|
|
||||||
$sqlAddon = "INSERT INTO jurnal_addon (
|
|
||||||
jurnalAddOnJurnalID,
|
|
||||||
jurnalAddOnJurnalTxID,
|
|
||||||
jurnalAddOnCode,
|
|
||||||
jurnalAddOnValue,
|
|
||||||
jurnalAddOnM_ItemID,
|
|
||||||
jurnalAddOnCreated,
|
|
||||||
jurnalAddOnCreatedUserID
|
|
||||||
) VALUES (?,?,?,?,?,NOW(),?)";
|
|
||||||
|
|
||||||
$qryAddon = $this->db->query($sqlAddon, [
|
|
||||||
$jurnalID,
|
|
||||||
$jurnalTxID,
|
|
||||||
$addonCode,
|
|
||||||
$addonValue,
|
|
||||||
$mItemID > 0 ? $mItemID : null,
|
|
||||||
$userID
|
|
||||||
]);
|
|
||||||
if (!$qryAddon) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("Gagal insert jurnal_addon pada detail ke-" . ($idx + 1));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$createdAddonCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->db->trans_status() === false) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("Transaksi jurnal gagal.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->db->trans_commit();
|
|
||||||
|
|
||||||
return [
|
|
||||||
"jurnalID" => $jurnalID,
|
|
||||||
"jurnalNo" => $jurnalNo,
|
|
||||||
"detailCount" => count($details),
|
|
||||||
"addonCount" => $createdAddonCount
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* generateJournalNumber — Generate nomor jurnal otomatis.
|
|
||||||
*
|
|
||||||
* Memanggil stored function MySQL fn_numbering('J') untuk mendapatkan
|
|
||||||
* nomor jurnal berikutnya sesuai urutan penomoran yang berlaku.
|
|
||||||
*
|
|
||||||
* @return string|false Nomor jurnal (misal: "J/2025/07/0001"), atau false jika gagal.
|
|
||||||
*/
|
|
||||||
private function generateJournalNumber()
|
|
||||||
{
|
|
||||||
$qry = $this->db->query("SELECT fn_numbering('J') AS JNumber");
|
|
||||||
if (!$qry || $qry->num_rows() == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return $qry->row_array()["JNumber"];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getPeriodeIDByDate — Ambil ID periode akuntansi berdasarkan tanggal transaksi.
|
|
||||||
*
|
|
||||||
* Periode diambil dari tabel `periode` yang aktif dan mencakup tanggal yang diberikan.
|
|
||||||
* Digunakan untuk mengisi field jurnalperiodeID pada header jurnal.
|
|
||||||
*
|
|
||||||
* @param string $date Tanggal transaksi (format YYYY-MM-DD)
|
|
||||||
* @return int periodeID yang sesuai, atau 0 jika tidak ditemukan
|
|
||||||
*/
|
|
||||||
private function getPeriodeIDByDate($date)
|
|
||||||
{
|
|
||||||
$sql = "SELECT periodeID
|
|
||||||
FROM periode
|
|
||||||
WHERE periodeIsActive = 'Y'
|
|
||||||
AND DATE(?) BETWEEN periodeStartDate AND periodeEndDate
|
|
||||||
LIMIT 1";
|
|
||||||
$qry = $this->db->query($sql, [$date]);
|
|
||||||
if (!$qry || $qry->num_rows() == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (int) $qry->row_array()["periodeID"];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getBranchCompanyIDByBranchCode — Ambil ID branch company berdasarkan kode cabang.
|
|
||||||
*
|
|
||||||
* Data diambil dari tabel `m_branch_companydetail` yang aktif.
|
|
||||||
* Digunakan untuk mengisi field jurnalM_BranchCompanyID pada header jurnal.
|
|
||||||
*
|
|
||||||
* @param string $branchCode Kode cabang (misal: "JKT-01")
|
|
||||||
* @return int branchCompanyID yang sesuai, atau 0 jika tidak ditemukan
|
|
||||||
*/
|
|
||||||
private function getBranchCompanyIDByBranchCode($branchCode)
|
|
||||||
{
|
|
||||||
$sql = "SELECT M_BranchCompanyDetailM_BranchCompanyID AS branchCompanyID
|
|
||||||
FROM m_branch_companydetail
|
|
||||||
WHERE M_BranchCompanyDetailM_BranchCode = ?
|
|
||||||
AND M_BranchCompanyDetailIsActive = 'Y'
|
|
||||||
LIMIT 1";
|
|
||||||
$qry = $this->db->query($sql, [$branchCode]);
|
|
||||||
if (!$qry || $qry->num_rows() == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (int) $qry->row_array()["branchCompanyID"];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getRegionalIDByBranchCode — Ambil ID regional berdasarkan kode cabang.
|
|
||||||
*
|
|
||||||
* Data diambil dari tabel `m_branch` yang aktif.
|
|
||||||
* Digunakan untuk mengisi field JurnalS_RegionalID pada header jurnal.
|
|
||||||
*
|
|
||||||
* @param string $branchCode Kode cabang (misal: "JKT-01")
|
|
||||||
* @return int regionalID yang sesuai, atau 0 jika tidak ditemukan
|
|
||||||
*/
|
|
||||||
private function getRegionalIDByBranchCode($branchCode)
|
|
||||||
{
|
|
||||||
$sql = "SELECT M_BranchS_RegionalID AS regionalID
|
|
||||||
FROM m_branch
|
|
||||||
WHERE M_BranchCode = ?
|
|
||||||
AND M_BranchIsActive = 'Y'
|
|
||||||
LIMIT 1";
|
|
||||||
$qry = $this->db->query($sql, [$branchCode]);
|
|
||||||
if (!$qry || $qry->num_rows() == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (int) $qry->row_array()["regionalID"];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getJurnalTypeID — Ambil ID tipe jurnal berdasarkan kode tipe.
|
|
||||||
*
|
|
||||||
* Data diambil dari tabel `jurnal_type` yang aktif.
|
|
||||||
* Untuk PI cicilan order aset, kode yang digunakan adalah "PAYMENT".
|
|
||||||
*
|
|
||||||
* @param string $jurnalTypeCode Kode tipe jurnal (misal: "PAYMENT")
|
|
||||||
* @return int JurnalTypeID yang sesuai, atau 0 jika tidak ditemukan
|
|
||||||
*/
|
|
||||||
private function getJurnalTypeID($jurnalTypeCode)
|
|
||||||
{
|
|
||||||
$sql = "SELECT JurnalTypeID
|
|
||||||
FROM jurnal_type
|
|
||||||
WHERE JurnalTypeCode = ?
|
|
||||||
AND JurnalTypeIsActive = 'Y'
|
|
||||||
LIMIT 1";
|
|
||||||
$qry = $this->db->query($sql, [$jurnalTypeCode]);
|
|
||||||
if (!$qry || $qry->num_rows() == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (int) $qry->row_array()["JurnalTypeID"];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getEligiblePurchaseOrderAssetContracts — Ambil kontrak aset yang layak dibuatkan jurnal.
|
|
||||||
*
|
|
||||||
* Query ini mengambil semua kontrak dari `purchase_order_asset_contract` yang memenuhi
|
|
||||||
* syarat berikut:
|
|
||||||
* - Kontrak aktif, status "belum lunas", nilai cicilan > 0
|
|
||||||
* - Cicilan terbayar masih kurang dari total cicilan
|
|
||||||
* - Tanggal kontrak masuk dalam rentang periode yang diberikan
|
|
||||||
* - Tanggal jatuh tempo cicilan sudah lewat atau sama dengan hari ini
|
|
||||||
* - PO sudah Approved dan aktif
|
|
||||||
* - Barang sudah diterima dan receive order sudah confirmed
|
|
||||||
*
|
|
||||||
* Data yang dikembalikan mencakup:
|
|
||||||
* - Detail kontrak (ID, nama, tanggal, nilai cicilan)
|
|
||||||
* - Data PO (nomor PO, supplier, payment term, warehouse)
|
|
||||||
* - Data cabang (kode cabang, nama, regionalID, branchCompanyID)
|
|
||||||
* - Data item PO pertama (sebagai referensi baris jurnal)
|
|
||||||
*
|
|
||||||
* @param string $startDate Awal periode filter (YYYY-MM-DD)
|
|
||||||
* @param string $endDate Akhir periode filter (YYYY-MM-DD)
|
|
||||||
* @return array Array of row kontrak yang eligible
|
|
||||||
*/
|
|
||||||
private function getEligiblePurchaseOrderAssetContracts($startDate, $endDate)
|
|
||||||
{
|
|
||||||
$sql = "SELECT
|
|
||||||
c.PurchaseOrderAssetContractID,
|
|
||||||
si.SupplierInvoiceID,
|
|
||||||
si.SupplierInvoiceNumber,
|
|
||||||
c.PurchaseOrderAssetContractPurchaseOrderID,
|
|
||||||
c.PurchaseOrderAssetContractName,
|
|
||||||
c.PurchaseOrderAssetContractStartDate,
|
|
||||||
c.PurchaseOrderAssetContractEndDate,
|
|
||||||
c.PurchaseOrderAssetContractInstallmentNumber,
|
|
||||||
c.PurchaseOrderAssetContractInstallmentPaid,
|
|
||||||
c.PurchaseOrderAssetContractInstallmentDate,
|
|
||||||
c.PurchaseOrderAssetContractInstallmentPayAmount,
|
|
||||||
c.PurchaseOrderAssetContractReceiveOrderPoID,
|
|
||||||
po.PurchaseOrderID,
|
|
||||||
po.PurchaseOrderNumber,
|
|
||||||
po.PurchaseOrderSupplierID,
|
|
||||||
po.PurchaseOrderPaymentTerm,
|
|
||||||
po.PurchaseOrderWarehouseType,
|
|
||||||
po.PurchaseOrderWarehouseID,
|
|
||||||
wh.WarehouseCode,
|
|
||||||
wh.WarehouseName,
|
|
||||||
wh.WarehouseType,
|
|
||||||
wh.WarehouseS_RegionalID AS WarehouseS_RegionalID,
|
|
||||||
wh.WarehouseM_BranchID AS WarehouseM_BranchID,
|
|
||||||
ro.ReceiveOrderPoID,
|
|
||||||
ro.ReceiveOrderPoConfirmed,
|
|
||||||
mi.M_ItemID AS ItemID,
|
|
||||||
mi.M_ItemCode AS ItemCode,
|
|
||||||
mi.M_ItemDesc AS ItemDesc,
|
|
||||||
mi.M_ItemFa_ClassID,
|
|
||||||
fc.Fa_ClassID AS ItemFaClassID,
|
|
||||||
fc.Fa_ClassName AS ItemFaClassName,
|
|
||||||
coa_bayar.coaID AS ItemCoaID,
|
|
||||||
coa_bayar.coaAccountNo AS ItemCoaAccountNo,
|
|
||||||
coa_bayar.coaDescription AS ItemCoaDesc,
|
|
||||||
coa_hutang.coaID AS HutangCoaID,
|
|
||||||
coa_hutang.coaAccountNo AS HutangCoaAccountNo,
|
|
||||||
coa_hutang.coaDescription AS HutangCoaDesc,
|
|
||||||
m_branch.M_BranchCode,
|
|
||||||
m_branch.M_BranchName,
|
|
||||||
m_branch.M_BranchS_RegionalID,
|
|
||||||
m_branch_companydetail.M_BranchCompanyDetailM_BranchCompanyID AS M_BranchCompanyID,
|
|
||||||
ps.PurchaseOrderSummaryID,
|
|
||||||
ps.PurchaseOrderSummaryItemID,
|
|
||||||
ps.PurchaseOrderSummaryItemUnitID
|
|
||||||
FROM purchase_order_asset_contract c
|
|
||||||
|
|
||||||
-- Pastikan PO sudah Approved dan aktif
|
|
||||||
JOIN purchase_order po
|
|
||||||
ON po.PurchaseOrderID = c.PurchaseOrderAssetContractPurchaseOrderID
|
|
||||||
AND po.PurchaseOrderIsActive = 'Y'
|
|
||||||
AND po.PurchaseOrderStatus = 'Approved'
|
|
||||||
|
|
||||||
-- Data warehouse/gudang tujuan PO
|
|
||||||
LEFT JOIN warehouse wh
|
|
||||||
ON wh.WarehouseID = po.PurchaseOrderWarehouseID
|
|
||||||
|
|
||||||
-- Ambil 1 item PO pertama sebagai referensi baris jurnal
|
|
||||||
LEFT JOIN (
|
|
||||||
SELECT ps0.*
|
|
||||||
FROM purchase_order_summary ps0
|
|
||||||
JOIN (
|
|
||||||
SELECT
|
|
||||||
PurchaseOrderSummaryPurchaseOrderID,
|
|
||||||
MIN(PurchaseOrderSummaryID) AS PurchaseOrderSummaryID
|
|
||||||
FROM purchase_order_summary
|
|
||||||
WHERE PurchaseOrderSummaryIsActive = 'Y'
|
|
||||||
GROUP BY PurchaseOrderSummaryPurchaseOrderID
|
|
||||||
) psx
|
|
||||||
ON psx.PurchaseOrderSummaryID = ps0.PurchaseOrderSummaryID
|
|
||||||
) ps
|
|
||||||
ON ps.PurchaseOrderSummaryPurchaseOrderID = po.PurchaseOrderID
|
|
||||||
|
|
||||||
-- Hubungkan dengan detail supplier_invoice_detail terlebih dahulu
|
|
||||||
JOIN supplier_invoice_detail sid
|
|
||||||
ON sid.SupplierInvoiceDetailPurchaseOrderID = po.PurchaseOrderID
|
|
||||||
AND sid.SupplierInvoiceDetailPurchaseOrderSummaryID = ps.PurchaseOrderSummaryID
|
|
||||||
AND sid.SupplierInvoiceDetailIsActive = 'Y'
|
|
||||||
|
|
||||||
-- Baru hubungkan ke header supplier_invoice untuk mengambil nomor invoice
|
|
||||||
JOIN supplier_invoice si
|
|
||||||
ON si.SupplierInvoiceID = sid.SupplierInvoiceDetailSupplierInvoiceID
|
|
||||||
AND si.SupplierInvoiceDate >= DATE(?)
|
|
||||||
AND si.SupplierInvoiceDate <= DATE(?)
|
|
||||||
AND si.SupplierInvoiceIsActive = 'Y'
|
|
||||||
|
|
||||||
-- Pastikan barang sudah diterima (receive order confirmed)
|
|
||||||
JOIN (
|
|
||||||
SELECT
|
|
||||||
rd.ReceiveOrderPoDetailPurchaseOrderID,
|
|
||||||
MIN(ro0.ReceiveOrderPoID) AS ReceiveOrderPoID,
|
|
||||||
MAX(ro0.ReceiveOrderPoConfirmed) AS ReceiveOrderPoConfirmed
|
|
||||||
FROM receive_order_po ro0
|
|
||||||
JOIN receive_order_po_detail rd
|
|
||||||
ON rd.ReceiveOrderPoDetailReceiveOrderPoID = ro0.ReceiveOrderPoID
|
|
||||||
AND rd.ReceiveOrderPoDetailIsActive = 'Y'
|
|
||||||
WHERE ro0.ReceiveOrderPoIsActive = 'Y'
|
|
||||||
AND ro0.ReceiveOrderPoConfirmed = 'Y'
|
|
||||||
GROUP BY rd.ReceiveOrderPoDetailPurchaseOrderID
|
|
||||||
) ro
|
|
||||||
ON ro.ReceiveOrderPoDetailPurchaseOrderID = po.PurchaseOrderID
|
|
||||||
|
|
||||||
-- Data cabang dari warehouse
|
|
||||||
LEFT JOIN m_branch
|
|
||||||
ON m_branch.M_BranchID = wh.WarehouseM_BranchID
|
|
||||||
AND m_branch.M_BranchIsActive = 'Y'
|
|
||||||
|
|
||||||
-- Data branch company untuk header jurnal
|
|
||||||
LEFT JOIN m_branch_companydetail
|
|
||||||
ON m_branch_companydetail.M_BranchCompanyDetailM_BranchCode = m_branch.M_BranchCode
|
|
||||||
AND m_branch_companydetail.M_BranchCompanyDetailIsActive = 'Y'
|
|
||||||
|
|
||||||
-- COA jurnal diambil dari item -> fa_class
|
|
||||||
LEFT JOIN m_item mi
|
|
||||||
ON mi.M_ItemID = ps.PurchaseOrderSummaryItemID
|
|
||||||
AND mi.M_ItemIsActive = 'Y'
|
|
||||||
LEFT JOIN fa_class fc
|
|
||||||
ON fc.Fa_ClassID = mi.M_ItemFa_ClassID
|
|
||||||
AND fc.Fa_ClassIsActive = 'Y'
|
|
||||||
|
|
||||||
-- Join langsung ke tabel coa untuk memastikan kevalidan akun dan deskripsi
|
|
||||||
LEFT JOIN coa coa_hutang
|
|
||||||
ON coa_hutang.coaID = fc.Fa_ClassHutangCoaID
|
|
||||||
AND coa_hutang.coaIsActive = 'Y'
|
|
||||||
LEFT JOIN coa coa_bayar
|
|
||||||
ON coa_bayar.coaID = fc.Fa_ClassCoaID
|
|
||||||
AND coa_bayar.coaIsActive = 'Y'
|
|
||||||
|
|
||||||
WHERE c.PurchaseOrderAssetContractIsActive = 'Y'
|
|
||||||
AND c.PurchaseOrderAssetContractStatus = 'belum lunas'
|
|
||||||
-- Hanya kontrak yang ada nilai cicilannya
|
|
||||||
AND IFNULL(c.PurchaseOrderAssetContractInstallmentPayAmount, 0) > 0
|
|
||||||
-- Hanya kontrak yang belum selesai seluruh cicilannya
|
|
||||||
AND IFNULL(c.PurchaseOrderAssetContractInstallmentPaid, 0) < IFNULL(c.PurchaseOrderAssetContractInstallmentNumber, 0)
|
|
||||||
-- Kontrak sudah mulai sebelum atau pada akhir periode
|
|
||||||
AND DATE(c.PurchaseOrderAssetContractStartDate) <= DATE(?)
|
|
||||||
-- Kontrak belum berakhir (atau tidak ada tanggal akhir)
|
|
||||||
AND (
|
|
||||||
c.PurchaseOrderAssetContractEndDate IS NULL
|
|
||||||
OR DATE(c.PurchaseOrderAssetContractEndDate) >= DATE(?)
|
|
||||||
)
|
|
||||||
-- Tanggal jatuh tempo cicilan sudah tiba
|
|
||||||
AND IFNULL(c.PurchaseOrderAssetContractInstallmentDate, 1) <= ?
|
|
||||||
-- Pastikan belum pernah dibuatkan jurnal untuk invoice cicilan ini
|
|
||||||
AND NOT EXISTS (
|
|
||||||
SELECT 1
|
|
||||||
FROM jurnal_addon ja
|
|
||||||
JOIN jurnal j ON j.jurnalID = ja.jurnalAddOnJurnalID
|
|
||||||
WHERE ja.jurnalAddOnCode = 'PIINSTALMENT'
|
|
||||||
AND ja.jurnalAddOnValue = si.SupplierInvoiceNumber
|
|
||||||
)
|
|
||||||
ORDER BY c.PurchaseOrderAssetContractID ASC";
|
|
||||||
|
|
||||||
$qry = $this->db->query($sql, [
|
|
||||||
$startDate,
|
|
||||||
$endDate,
|
|
||||||
$endDate,
|
|
||||||
$startDate,
|
|
||||||
(int) date("d", strtotime($endDate))
|
|
||||||
]);
|
|
||||||
if (!$qry) {
|
|
||||||
$this->sys_error_db("Gagal mengambil data purchase_order_asset_contract.");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $qry->result_array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* isValidDate — Validasi format tanggal YYYY-MM-DD.
|
|
||||||
*
|
|
||||||
* @param string $tanggal String tanggal yang akan divalidasi
|
|
||||||
* @return bool true jika format valid, false jika tidak
|
|
||||||
*/
|
|
||||||
private function isValidDate($tanggal)
|
|
||||||
{
|
|
||||||
$d = DateTime::createFromFormat("Y-m-d", $tanggal);
|
|
||||||
return $d && $d->format("Y-m-d") === $tanggal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
|
|
||||||
# ============================================================
|
|
||||||
# FILE : PurchaseInvoiceInstallment.http
|
|
||||||
# MODUL : Scheduler — Generate Supplier Installment Cicilan Aset
|
|
||||||
# ============================================================
|
|
||||||
#
|
|
||||||
# DESKRIPSI
|
|
||||||
# ---------
|
|
||||||
# File ini berisi HTTP request untuk menguji endpoint scheduler
|
|
||||||
# yang secara otomatis membuat baris cicilan ke tabel
|
|
||||||
# supplier_installment setiap bulan.
|
|
||||||
#
|
|
||||||
# CARA PAKAI
|
|
||||||
# ----------
|
|
||||||
# 1. Gunakan ekstensi "REST Client" di VS Code (humao.rest-client)
|
|
||||||
# atau tool sejenis (IntelliJ HTTP Client, Postman, dll).
|
|
||||||
# 2. Ganti nilai @host sesuai environment.
|
|
||||||
# 3. Klik "Send Request" di atas tiap blok ###
|
|
||||||
#
|
|
||||||
# ALUR
|
|
||||||
# ----
|
|
||||||
# [1] GenerateMonthlyInvoices → Jalankan proses generate installment
|
|
||||||
#
|
|
||||||
# CATATAN
|
|
||||||
# -------
|
|
||||||
# - Default periode: bulan berjalan (tanggal 1 s/d akhir bulan)
|
|
||||||
# - Aman dijalankan ulang — dedup berdasarkan PO + bulan mencegah
|
|
||||||
# duplikasi
|
|
||||||
# - Tidak membuat jurnal — jurnal dibuat saat pembayaran cashier
|
|
||||||
# - Tidak update kontrak — InstallmentPaid diupdate saat pembayaran
|
|
||||||
# ============================================================
|
|
||||||
|
|
||||||
@host = https://accone.aplikasi.web.id/one-api
|
|
||||||
|
|
||||||
# ============================================================
|
|
||||||
# [1] GENERATE INSTALLMENT BULANAN (MAIN ENDPOINT)
|
|
||||||
# ============================================================
|
|
||||||
# Satu request ini akan:
|
|
||||||
# Step 1: Validasi kontrak (aktif, belum lunas, dalam rentang)
|
|
||||||
# Step 2: Validasi PO (Approved, Active)
|
|
||||||
# Step 3: Validasi RO (Confirmed, Active)
|
|
||||||
# Step 4: Validasi parent invoice (IsInstallment = 'Y')
|
|
||||||
# Step 5: Cek dedup (belum ada installment bulan ini)
|
|
||||||
# Step 6: INSERT ke supplier_installment (Status = 'Pending')
|
|
||||||
#
|
|
||||||
# Response:
|
|
||||||
# - totalEligible : jumlah kontrak lolos validasi
|
|
||||||
# - totalInserted : jumlah baris berhasil diinsert
|
|
||||||
# - created[] : detail tiap installment yang dibuat
|
|
||||||
# ============================================================
|
|
||||||
|
|
||||||
### [1] Generate installment untuk periode tertentu
|
|
||||||
POST {{host}}/mockup/scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"startDate": "2026-07-01",
|
|
||||||
"endDate": "2026-07-31"
|
|
||||||
}
|
|
||||||
|
|
||||||
### [1a] Generate installment bulan berjalan (tanpa parameter)
|
|
||||||
POST {{host}}/mockup/scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{}
|
|
||||||
@@ -1,302 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PurchaseInvoiceInstallment
|
|
||||||
*
|
|
||||||
* CRON scheduler untuk membuat baris cicilan otomatis ke tabel supplier_installment
|
|
||||||
* setiap bulan berdasarkan kontrak aset yang aktif dan belum lunas.
|
|
||||||
*
|
|
||||||
* Endpoint:
|
|
||||||
* POST /scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices
|
|
||||||
*/
|
|
||||||
class PurchaseInvoiceInstallment extends MY_Controller
|
|
||||||
{
|
|
||||||
var $db;
|
|
||||||
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
echo "Purchase Invoice Installment — Auto Generate Installment Cicilan Aset";
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GenerateMonthlyInvoices — Step 6
|
|
||||||
*
|
|
||||||
* Creates supplier_installment rows for all eligible contracts this month.
|
|
||||||
* No journal is created here — that happens at cashier payment time.
|
|
||||||
* Contract InstallmentPaid is NOT updated here — that happens at payment time.
|
|
||||||
*
|
|
||||||
* Called by CRON daily at 1:00 AM.
|
|
||||||
* Defaults to current month if no startDate/endDate provided.
|
|
||||||
*/
|
|
||||||
public function GenerateMonthlyInvoices()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$para = $this->sys_input;
|
|
||||||
|
|
||||||
$userID = !empty($this->sys_user["M_UserID"])
|
|
||||||
? (int) $this->sys_user["M_UserID"]
|
|
||||||
: 0;
|
|
||||||
|
|
||||||
$startDate = !empty($para["startDate"])
|
|
||||||
? $para["startDate"]
|
|
||||||
: date("Y-m-01");
|
|
||||||
|
|
||||||
$endDate = !empty($para["endDate"])
|
|
||||||
? $para["endDate"]
|
|
||||||
: date("Y-m-t");
|
|
||||||
|
|
||||||
if (!$this->isValidDate($startDate) || !$this->isValidDate($endDate)) {
|
|
||||||
throw new Exception("Format tanggal tidak valid.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strtotime($startDate) > strtotime($endDate)) {
|
|
||||||
throw new Exception("startDate > endDate.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Steps 1–5: Get eligible contracts ────────────────────
|
|
||||||
$eligible = $this->getEligibleInstallments($startDate, $endDate);
|
|
||||||
|
|
||||||
$created = [];
|
|
||||||
$inserted = 0;
|
|
||||||
|
|
||||||
$this->db->trans_begin();
|
|
||||||
|
|
||||||
foreach ($eligible as $row) {
|
|
||||||
|
|
||||||
$amount = (float) $row["PurchaseOrderAssetContractInstallmentPayAmount"];
|
|
||||||
$dayOfMonth = (int) ($row["PurchaseOrderAssetContractInstallmentDate"] ?? 1);
|
|
||||||
$lastDay = (int) date("t", strtotime($endDate));
|
|
||||||
$dayOfMonth = min($dayOfMonth, $lastDay);
|
|
||||||
$installDate = date("Y-m", strtotime($endDate)) . "-" . str_pad($dayOfMonth, 2, "0", STR_PAD_LEFT);
|
|
||||||
$dueDate = date("Y-m-d", strtotime($installDate . " +7 days"));
|
|
||||||
$createdBy = (int) ($row["PurchaseOrderAssetContractCreatedUserID"] ?? $userID);
|
|
||||||
|
|
||||||
// ── Step 6: INSERT supplier_installment ──────────────
|
|
||||||
$sql = "INSERT INTO supplier_installment (
|
|
||||||
SupplierInstallmentPurchaseOrderID,
|
|
||||||
SupplierInstallmentSupplierID,
|
|
||||||
SupplierInstallmentSupplierInvoiceID,
|
|
||||||
SupplierInstallmentAmount,
|
|
||||||
SupplierInstallmentDate,
|
|
||||||
SupplierInstallmentDueDate,
|
|
||||||
SupplierInstallmentPaymentID,
|
|
||||||
SupplierInstallmentStatus,
|
|
||||||
SupplierInstallmentIsLunas,
|
|
||||||
SupplierInstallmentIsActive,
|
|
||||||
SupplierInstallmentCreated,
|
|
||||||
SupplierInstallmentCreatedUserID
|
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, 0, 'Pending', 'N', 'Y', NOW(), ?)";
|
|
||||||
|
|
||||||
$que = $this->db->query($sql, [
|
|
||||||
$row["PurchaseOrderID"],
|
|
||||||
$row["PurchaseOrderSupplierID"],
|
|
||||||
$row["SupplierInvoiceID"],
|
|
||||||
$amount,
|
|
||||||
$installDate,
|
|
||||||
$dueDate,
|
|
||||||
$createdBy
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!$que) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("Gagal insert supplier_installment.");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$installmentID = $this->db->insert_id();
|
|
||||||
$inserted++;
|
|
||||||
|
|
||||||
$created[] = [
|
|
||||||
"installmentID" => $installmentID,
|
|
||||||
"contractID" => $row["PurchaseOrderAssetContractID"],
|
|
||||||
"purchaseOrderID" => $row["PurchaseOrderID"],
|
|
||||||
"parentInvoiceID" => $row["SupplierInvoiceID"],
|
|
||||||
"parentInvoiceNumber" => $row["SupplierInvoiceNumber"],
|
|
||||||
"amount" => $amount,
|
|
||||||
"installDate" => $installDate,
|
|
||||||
"dueDate" => $dueDate
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->db->trans_status() === false) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("Transaksi gagal.");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->db->trans_commit();
|
|
||||||
|
|
||||||
$this->sys_ok([
|
|
||||||
"startDate" => $startDate,
|
|
||||||
"endDate" => $endDate,
|
|
||||||
"totalEligible" => count($eligible),
|
|
||||||
"totalInserted" => $inserted,
|
|
||||||
"created" => $created
|
|
||||||
]);
|
|
||||||
|
|
||||||
} catch (Exception $exc) {
|
|
||||||
if ($this->db->trans_status() === false) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
}
|
|
||||||
$this->sys_error($exc->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ambil data user berdasarkan userID untuk keperluan CRON.
|
|
||||||
* Jika user tidak ditemukan, kembalikan data default (tanpa branch/regional).
|
|
||||||
*
|
|
||||||
* @param int $userID
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function getCronUser($userID)
|
|
||||||
{
|
|
||||||
$sql = "SELECT
|
|
||||||
M_UserID,
|
|
||||||
M_UserM_BranchID AS M_BranchID,
|
|
||||||
M_UserS_RegionalID AS S_RegionalID
|
|
||||||
FROM m_user
|
|
||||||
WHERE M_UserID = ?
|
|
||||||
LIMIT 1";
|
|
||||||
|
|
||||||
$qry = $this->db->query($sql, [$userID]);
|
|
||||||
if ($qry && $qry->num_rows() > 0) {
|
|
||||||
$user = $qry->row_array();
|
|
||||||
$user["loginLevel"] = "branch";
|
|
||||||
return $user;
|
|
||||||
}
|
|
||||||
|
|
||||||
// User tidak ditemukan, gunakan data kosong agar proses tetap berjalan
|
|
||||||
return [
|
|
||||||
"M_UserID" => $userID,
|
|
||||||
"M_BranchID" => 0,
|
|
||||||
"S_RegionalID" => 0,
|
|
||||||
"loginLevel" => "branch"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hitung tanggal jatuh tempo berdasarkan tanggal acuan dan payment term (dalam hari).
|
|
||||||
*
|
|
||||||
* @param string $tanggal Format YYYY-MM-DD
|
|
||||||
* @param int $term Jumlah hari payment term
|
|
||||||
* @return string Tanggal jatuh tempo (YYYY-MM-DD)
|
|
||||||
*/
|
|
||||||
private function hitungJatuhTempo($tanggal, $term)
|
|
||||||
{
|
|
||||||
$hari = is_numeric($term) ? (int) $term : 0;
|
|
||||||
if ($hari < 0) {
|
|
||||||
$hari = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return date("Y-m-d", strtotime($tanggal . " +" . $hari . " days"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validasi apakah string adalah tanggal yang valid dengan format YYYY-MM-DD.
|
|
||||||
*
|
|
||||||
* @param string $tanggal
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function isValidDate($tanggal)
|
|
||||||
{
|
|
||||||
$d = DateTime::createFromFormat("Y-m-d", $tanggal);
|
|
||||||
return $d && $d->format("Y-m-d") === $tanggal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getEligibleInstallments — Steps 1–5 combined
|
|
||||||
*
|
|
||||||
* Returns contracts that:
|
|
||||||
* Step 1: Are active, not paid off, within date range, due date reached
|
|
||||||
* Step 2: Have approved & active PO
|
|
||||||
* Step 3: Have confirmed & active RO
|
|
||||||
* Step 4: Have a parent supplier_invoice with IsInstallment = 'Y'
|
|
||||||
* Step 5: Do NOT already have a supplier_installment for this month
|
|
||||||
*
|
|
||||||
* @param string $startDate YYYY-MM-DD
|
|
||||||
* @param string $endDate YYYY-MM-DD
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function getEligibleInstallments($startDate, $endDate)
|
|
||||||
{
|
|
||||||
$dayOfMonth = (int) date("d", strtotime($endDate));
|
|
||||||
|
|
||||||
$sql = "SELECT
|
|
||||||
c.PurchaseOrderAssetContractID,
|
|
||||||
c.PurchaseOrderAssetContractInstallmentPayAmount,
|
|
||||||
c.PurchaseOrderAssetContractInstallmentDate,
|
|
||||||
c.PurchaseOrderAssetContractCreatedUserID,
|
|
||||||
po.PurchaseOrderID,
|
|
||||||
po.PurchaseOrderSupplierID,
|
|
||||||
si.SupplierInvoiceID,
|
|
||||||
si.SupplierInvoiceNumber
|
|
||||||
FROM purchase_order_asset_contract c
|
|
||||||
|
|
||||||
-- Step 2: PO must be Approved and Active
|
|
||||||
JOIN purchase_order po
|
|
||||||
ON po.PurchaseOrderID = c.PurchaseOrderAssetContractPurchaseOrderID
|
|
||||||
AND po.PurchaseOrderIsActive = 'Y'
|
|
||||||
AND po.PurchaseOrderStatus = 'Approved'
|
|
||||||
|
|
||||||
-- Step 3: RO must be Confirmed and Active
|
|
||||||
JOIN (
|
|
||||||
SELECT
|
|
||||||
rd.ReceiveOrderPoDetailPurchaseOrderID,
|
|
||||||
MIN(ro0.ReceiveOrderPoID) AS ReceiveOrderPoID,
|
|
||||||
MAX(ro0.ReceiveOrderPoConfirmed) AS ReceiveOrderPoConfirmed
|
|
||||||
FROM receive_order_po ro0
|
|
||||||
JOIN receive_order_po_detail rd
|
|
||||||
ON rd.ReceiveOrderPoDetailReceiveOrderPoID = ro0.ReceiveOrderPoID
|
|
||||||
AND rd.ReceiveOrderPoDetailIsActive = 'Y'
|
|
||||||
WHERE ro0.ReceiveOrderPoIsActive = 'Y'
|
|
||||||
AND ro0.ReceiveOrderPoConfirmed = 'Y'
|
|
||||||
GROUP BY rd.ReceiveOrderPoDetailPurchaseOrderID
|
|
||||||
) ro ON ro.ReceiveOrderPoDetailPurchaseOrderID = po.PurchaseOrderID
|
|
||||||
|
|
||||||
-- Step 4: Parent invoice must exist with IsInstallment = 'Y'
|
|
||||||
JOIN supplier_invoice si
|
|
||||||
ON si.SupplierInvoiceReceiveOrderPoID = ro.ReceiveOrderPoID
|
|
||||||
AND si.SupplierInvoiceIsActive = 'Y'
|
|
||||||
AND si.SupplierInvoiceIsInstallment = 'Y'
|
|
||||||
|
|
||||||
-- Step 1: Contract eligibility
|
|
||||||
WHERE c.PurchaseOrderAssetContractIsActive = 'Y'
|
|
||||||
AND c.PurchaseOrderAssetContractStatus = 'belum lunas'
|
|
||||||
AND IFNULL(c.PurchaseOrderAssetContractInstallmentPayAmount, 0) > 0
|
|
||||||
AND IFNULL(c.PurchaseOrderAssetContractInstallmentPaid, 0)
|
|
||||||
< IFNULL(c.PurchaseOrderAssetContractInstallmentNumber, 0)
|
|
||||||
AND DATE(c.PurchaseOrderAssetContractStartDate) <= DATE(?)
|
|
||||||
AND (
|
|
||||||
c.PurchaseOrderAssetContractEndDate IS NULL
|
|
||||||
OR DATE(c.PurchaseOrderAssetContractEndDate) >= DATE(?)
|
|
||||||
)
|
|
||||||
AND IFNULL(c.PurchaseOrderAssetContractInstallmentDate, 1) <= ?
|
|
||||||
|
|
||||||
-- Step 5: Dedup — no existing supplier_installment this month (any status)
|
|
||||||
AND NOT EXISTS (
|
|
||||||
SELECT 1
|
|
||||||
FROM supplier_installment inst
|
|
||||||
WHERE inst.SupplierInstallmentIsActive = 'Y'
|
|
||||||
AND inst.SupplierInstallmentPurchaseOrderID = po.PurchaseOrderID
|
|
||||||
AND DATE_FORMAT(inst.SupplierInstallmentDate, '%Y-%m') = DATE_FORMAT(?, '%Y-%m')
|
|
||||||
)
|
|
||||||
|
|
||||||
ORDER BY c.PurchaseOrderAssetContractID ASC";
|
|
||||||
|
|
||||||
$params = [$endDate, $startDate, $dayOfMonth, $endDate];
|
|
||||||
|
|
||||||
$qry = $this->db->query($sql, $params);
|
|
||||||
if (!$qry) {
|
|
||||||
$this->sys_error_db("Gagal mengambil daftar installment eligible.");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $qry->result_array();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,220 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PurchaseInvoiceInstallmentInsert
|
|
||||||
*
|
|
||||||
* Endpoint khusus untuk menyimpan supplier_invoice dan supplier_invoice_detail
|
|
||||||
* dari payload yang dikirim controller generator via cURL.
|
|
||||||
*/
|
|
||||||
class PurchaseInvoiceInstallmentInsert extends MY_Controller
|
|
||||||
{
|
|
||||||
var $db;
|
|
||||||
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
echo "Purchase Invoice Installment Insert";
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function InsertSupplierInvoice()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$para = $this->sys_input;
|
|
||||||
|
|
||||||
$required = [
|
|
||||||
"nomorPI",
|
|
||||||
"tanggalPI",
|
|
||||||
"tanggalJatuhTempo",
|
|
||||||
"jumlahCicilan",
|
|
||||||
"catatan",
|
|
||||||
"deskripsi",
|
|
||||||
"userID",
|
|
||||||
"purchaseOrderAssetContractID",
|
|
||||||
"purchaseOrderID",
|
|
||||||
"receiveOrderPoID",
|
|
||||||
"supplierID",
|
|
||||||
"purchaseOrderSummaryID",
|
|
||||||
"purchaseOrderSummaryItemID",
|
|
||||||
"purchaseOrderSummaryItemUnitID"
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($required as $field) {
|
|
||||||
if (!isset($para[$field]) || $para[$field] === "" || $para[$field] === null) {
|
|
||||||
throw new Exception("Field wajib belum lengkap: " . $field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$tanggalPI = $para["tanggalPI"];
|
|
||||||
$tanggalJatuhTempo = $para["tanggalJatuhTempo"];
|
|
||||||
if (!$this->isValidDate($tanggalPI) || !$this->isValidDate($tanggalJatuhTempo)) {
|
|
||||||
throw new Exception("Format tanggal tidak valid. Gunakan YYYY-MM-DD.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$jumlahCicilan = (float) $para["jumlahCicilan"];
|
|
||||||
if ($jumlahCicilan <= 0) {
|
|
||||||
throw new Exception("jumlahCicilan harus lebih besar dari 0.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$receiveOrderPoID = (int) $para["receiveOrderPoID"];
|
|
||||||
$monthKey = date("Y-m", strtotime($tanggalPI));
|
|
||||||
|
|
||||||
$sqlDuplikat = "SELECT SupplierInvoiceID, SupplierInvoiceNumber
|
|
||||||
FROM supplier_invoice
|
|
||||||
WHERE SupplierInvoiceIsActive = 'Y'
|
|
||||||
AND SupplierInvoiceStatus = 'Draft'
|
|
||||||
AND SupplierInvoiceReceiveOrderPoID = ?
|
|
||||||
AND DATE_FORMAT(SupplierInvoiceDate, '%Y-%m') = ?
|
|
||||||
LIMIT 1";
|
|
||||||
|
|
||||||
$qryDuplikat = $this->db->query($sqlDuplikat, [$receiveOrderPoID, $monthKey]);
|
|
||||||
if (!$qryDuplikat) {
|
|
||||||
$this->sys_error_db("Gagal mengecek duplikasi supplier_invoice.");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($qryDuplikat->num_rows() > 0) {
|
|
||||||
$existing = $qryDuplikat->row_array();
|
|
||||||
$this->sys_ok([
|
|
||||||
"duplicate" => true,
|
|
||||||
"supplierInvoiceID" => $existing["SupplierInvoiceID"],
|
|
||||||
"supplierInvoiceNumber" => $existing["SupplierInvoiceNumber"]
|
|
||||||
]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->db->trans_begin();
|
|
||||||
|
|
||||||
$sqlHeader = "INSERT INTO supplier_invoice (
|
|
||||||
SupplierInvoiceNumber,
|
|
||||||
SupplierInvoiceReceiveOrderPoID,
|
|
||||||
SupplierInvoiceDate,
|
|
||||||
SupplierInvoiceDueDate,
|
|
||||||
SupplierInvoiceDraftPaymentDate,
|
|
||||||
SupplierInvoiceSupplierID,
|
|
||||||
SupplierInvoiceSupplierInvoiceNumber,
|
|
||||||
SupplierInvoiceSupplierInvoiceDate,
|
|
||||||
SupplierInvoiceSubTotal,
|
|
||||||
SupplierInvoiceDiscountPercent,
|
|
||||||
SupplierInvoiceDiscountAmount,
|
|
||||||
SupplierInvoiceTaxPercentPph,
|
|
||||||
SupplierInvoiceTaxAmountPph,
|
|
||||||
SupplierInvoiceTaxPercentPpn,
|
|
||||||
SupplierInvoiceTaxAmountPpn,
|
|
||||||
SupplierInvoiceShippingCost,
|
|
||||||
SupplierInvoiceAdjustmentAmount,
|
|
||||||
SupplierInvoiceAdjustmentNote,
|
|
||||||
SupplierInvoiceGrandTotal,
|
|
||||||
SupplierInvoiceUnpaid,
|
|
||||||
SupplierInvoiceNote,
|
|
||||||
SupplierInvoiceStatus,
|
|
||||||
SupplierInvoiceCreatedUserID
|
|
||||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
|
||||||
|
|
||||||
$qryHeader = $this->db->query($sqlHeader, [
|
|
||||||
$para["nomorPI"],
|
|
||||||
$receiveOrderPoID,
|
|
||||||
$tanggalPI,
|
|
||||||
$tanggalJatuhTempo,
|
|
||||||
$tanggalPI,
|
|
||||||
(int) $para["supplierID"],
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
$jumlahCicilan,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
null,
|
|
||||||
$jumlahCicilan,
|
|
||||||
$jumlahCicilan,
|
|
||||||
$para["catatan"],
|
|
||||||
"Draft",
|
|
||||||
(int) $para["userID"]
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!$qryHeader) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("Gagal insert header supplier_invoice.");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$supplierInvoiceID = $this->db->insert_id();
|
|
||||||
|
|
||||||
$sqlDetail = "INSERT INTO supplier_invoice_detail (
|
|
||||||
SupplierInvoiceDetailSupplierInvoiceID,
|
|
||||||
SupplierInvoiceDetailPurchaseOrderID,
|
|
||||||
SupplierInvoiceDetailReceiveOrderPoID,
|
|
||||||
SupplierInvoiceDetailPurchaseOrderSummaryID,
|
|
||||||
SupplierInvoiceDetailItemID,
|
|
||||||
SupplierInvoiceDetailItemUnitID,
|
|
||||||
SupplierInvoiceDetailDescription,
|
|
||||||
SupplierInvoiceDetailQty,
|
|
||||||
SupplierInvoiceDetailPrice,
|
|
||||||
SupplierInvoiceDetailDiscountPercent,
|
|
||||||
SupplierInvoiceDetailDiscountDiscountRupiah,
|
|
||||||
SupplierInvoiceDetailDiscountDiscountType,
|
|
||||||
SupplierInvoiceDetailDiscountPoProrata,
|
|
||||||
SupplierInvoiceDetailDiscountAmount,
|
|
||||||
SupplierInvoiceDetailTotal,
|
|
||||||
SupplierInvoiceDetailUnpaid,
|
|
||||||
SupplierInvoiceDetailCreatedUserID
|
|
||||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
|
||||||
|
|
||||||
$qryDetail = $this->db->query($sqlDetail, [
|
|
||||||
$supplierInvoiceID,
|
|
||||||
(int) $para["purchaseOrderID"],
|
|
||||||
$receiveOrderPoID,
|
|
||||||
(int) $para["purchaseOrderSummaryID"],
|
|
||||||
(int) $para["purchaseOrderSummaryItemID"],
|
|
||||||
(int) $para["purchaseOrderSummaryItemUnitID"],
|
|
||||||
$para["deskripsi"],
|
|
||||||
1,
|
|
||||||
$jumlahCicilan,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
"R",
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
$jumlahCicilan,
|
|
||||||
$jumlahCicilan,
|
|
||||||
(int) $para["userID"]
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!$qryDetail) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("Gagal insert detail supplier_invoice_detail.");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->db->trans_status() === false) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("Transaksi insert supplier_invoice gagal.");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->db->trans_commit();
|
|
||||||
|
|
||||||
$this->sys_ok([
|
|
||||||
"duplicate" => false,
|
|
||||||
"supplierInvoiceID" => $supplierInvoiceID,
|
|
||||||
"supplierInvoiceNumber" => $para["nomorPI"]
|
|
||||||
]);
|
|
||||||
} catch (Exception $exc) {
|
|
||||||
$this->sys_error($exc->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function isValidDate($tanggal)
|
|
||||||
{
|
|
||||||
$d = DateTime::createFromFormat("Y-m-d", $tanggal);
|
|
||||||
return $d && $d->format("Y-m-d") === $tanggal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -28,92 +28,29 @@ class Billv2 extends MY_Controller {
|
|||||||
$offset = ($params['currentpage'] - 1) * $limit;
|
$offset = ($params['currentpage'] - 1) * $limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── UNION base — invoice + downpayment + installment ───
|
$sql_base = "SELECT
|
||||||
$sql_base = "
|
SupplierPaymentID,
|
||||||
SELECT
|
SupplierPaymentDate,
|
||||||
sp.SupplierPaymentID,
|
SupplierPaymentNumber,
|
||||||
sp.SupplierPaymentDate,
|
SupplierPaymentAmount,
|
||||||
sp.SupplierPaymentNumber,
|
SupplierPaymentStatus,
|
||||||
sp.SupplierPaymentAmount,
|
SupplierPaymentIsVerif,
|
||||||
sp.SupplierPaymentStatus,
|
SupplierPaymentIsApproved,
|
||||||
sp.SupplierPaymentIsVerif,
|
SupplierInvoiceID,
|
||||||
sp.SupplierPaymentIsApproved,
|
SupplierInvoiceNumber,
|
||||||
sp.SupplierPaymentIsActive,
|
SupplierInvoiceDraftPaymentDate,
|
||||||
si.SupplierInvoiceID,
|
SupplierCode,
|
||||||
si.SupplierInvoiceNumber,
|
SupplierName
|
||||||
si.SupplierInvoiceDraftPaymentDate,
|
FROM supplier_payment
|
||||||
sup.SupplierCode,
|
JOIN supplier_invoice ON SupplierInvoiceID = SupplierPaymentSupplierInvoiceID
|
||||||
sup.SupplierName,
|
AND SupplierPaymentNumber LIKE ?
|
||||||
'INVOICE' AS type
|
AND (SupplierPaymentDate BETWEEN DATE(?) AND DATE(?))
|
||||||
FROM supplier_payment sp
|
AND (SupplierPaymentStatus = ? OR ? = 'All')
|
||||||
JOIN supplier_invoice si
|
JOIN supplier ON SupplierID = SupplierInvoiceSupplierID
|
||||||
ON si.SupplierInvoiceID = sp.SupplierPaymentSupplierInvoiceID
|
WHERE SupplierPaymentIsActive = 'Y'
|
||||||
JOIN supplier sup
|
ORDER BY SupplierPaymentID DESC";
|
||||||
ON sup.SupplierID = si.SupplierInvoiceSupplierID
|
|
||||||
WHERE sp.SupplierPaymentSupplierInvoiceID > 0
|
|
||||||
|
|
||||||
UNION ALL
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
sp.SupplierPaymentID,
|
|
||||||
sp.SupplierPaymentDate,
|
|
||||||
sp.SupplierPaymentNumber,
|
|
||||||
sp.SupplierPaymentAmount,
|
|
||||||
sp.SupplierPaymentStatus,
|
|
||||||
sp.SupplierPaymentIsVerif,
|
|
||||||
sp.SupplierPaymentIsApproved,
|
|
||||||
sp.SupplierPaymentIsActive,
|
|
||||||
dp.SupplierDownpaymentID * -1 AS SupplierInvoiceID,
|
|
||||||
CONCAT('DP-', po.PurchaseOrderNumber) AS SupplierInvoiceNumber,
|
|
||||||
dp.SupplierDownpaymentDueDate AS SupplierInvoiceDraftPaymentDate,
|
|
||||||
dp_sup.SupplierCode AS SupplierCode,
|
|
||||||
dp_sup.SupplierName AS SupplierName,
|
|
||||||
'DP' AS type
|
|
||||||
FROM supplier_payment sp
|
|
||||||
JOIN supplier_downpayment dp
|
|
||||||
ON dp.SupplierDownpaymentID = sp.SupplierPaymentSupplierDownpaymentID
|
|
||||||
JOIN supplier dp_sup
|
|
||||||
ON dp_sup.SupplierID = dp.SupplierDownpaymentSupplierID
|
|
||||||
JOIN purchase_order po
|
|
||||||
ON po.PurchaseOrderID = dp.SupplierDownpaymentPurchasOrderID
|
|
||||||
WHERE sp.SupplierPaymentSupplierDownpaymentID IS NOT NULL
|
|
||||||
|
|
||||||
UNION ALL
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
sp.SupplierPaymentID,
|
|
||||||
sp.SupplierPaymentDate,
|
|
||||||
sp.SupplierPaymentNumber,
|
|
||||||
sp.SupplierPaymentAmount,
|
|
||||||
sp.SupplierPaymentStatus,
|
|
||||||
sp.SupplierPaymentIsVerif,
|
|
||||||
sp.SupplierPaymentIsApproved,
|
|
||||||
sp.SupplierPaymentIsActive,
|
|
||||||
0 AS SupplierInvoiceID,
|
|
||||||
CONCAT('INST-', si_inst.SupplierInvoiceNumber) AS SupplierInvoiceNumber,
|
|
||||||
inst.SupplierInstallmentDueDate AS SupplierInvoiceDraftPaymentDate,
|
|
||||||
inst_sup.SupplierCode AS SupplierCode,
|
|
||||||
inst_sup.SupplierName AS SupplierName,
|
|
||||||
'INSTALLMENT' AS type
|
|
||||||
FROM supplier_payment sp
|
|
||||||
JOIN supplier_installment inst
|
|
||||||
ON inst.SupplierInstallmentID = sp.SupplierPaymentSupplierInstallmentID
|
|
||||||
JOIN supplier_invoice si_inst
|
|
||||||
ON si_inst.SupplierInvoiceID = inst.SupplierInstallmentSupplierInvoiceID
|
|
||||||
JOIN supplier inst_sup
|
|
||||||
ON inst_sup.SupplierID = inst.SupplierInstallmentSupplierID
|
|
||||||
WHERE sp.SupplierPaymentSupplierInstallmentID IS NOT NULL";
|
|
||||||
|
|
||||||
// ── Outer: common filters + ordering + pagination ───────
|
|
||||||
$sql_data = "
|
|
||||||
SELECT * FROM ($sql_base) AS combined
|
|
||||||
WHERE SupplierPaymentIsActive = 'Y'
|
|
||||||
AND SupplierPaymentNumber LIKE ?
|
|
||||||
AND (SupplierPaymentDate BETWEEN DATE(?) AND DATE(?))
|
|
||||||
AND (SupplierPaymentStatus = ? OR ? = 'All')
|
|
||||||
ORDER BY SupplierPaymentID DESC
|
|
||||||
LIMIT ? OFFSET ?";
|
|
||||||
|
|
||||||
|
$sql_data = $sql_base . " LIMIT ? OFFSET ? ";
|
||||||
$que_data = $this->db->query($sql_data, [
|
$que_data = $this->db->query($sql_data, [
|
||||||
$keyword, $params['startdate'], $params['enddate'],
|
$keyword, $params['startdate'], $params['enddate'],
|
||||||
$params['status'], $params['status'], $limit, $offset
|
$params['status'], $params['status'], $limit, $offset
|
||||||
@@ -122,13 +59,7 @@ class Billv2 extends MY_Controller {
|
|||||||
throw new Exception("[Error] failed get data supplier payment", 2);
|
throw new Exception("[Error] failed get data supplier payment", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── COUNT — wrap UNION in outer filter ──────────────────
|
$sql_total = "SELECT COUNT(*) AS total FROM ($sql_base) AS x";
|
||||||
$sql_total = "SELECT COUNT(*) AS total FROM ($sql_base) AS combined
|
|
||||||
WHERE SupplierPaymentIsActive = 'Y'
|
|
||||||
AND SupplierPaymentNumber LIKE ?
|
|
||||||
AND (SupplierPaymentDate BETWEEN DATE(?) AND DATE(?))
|
|
||||||
AND (SupplierPaymentStatus = ? OR ? = 'All')";
|
|
||||||
|
|
||||||
$que_total = $this->db->query($sql_total, [
|
$que_total = $this->db->query($sql_total, [
|
||||||
$keyword, $params['startdate'], $params['enddate'],
|
$keyword, $params['startdate'], $params['enddate'],
|
||||||
$params['status'], $params['status']
|
$params['status'], $params['status']
|
||||||
@@ -139,10 +70,11 @@ class Billv2 extends MY_Controller {
|
|||||||
|
|
||||||
$output = [
|
$output = [
|
||||||
"records" => $que_data->result_array(),
|
"records" => $que_data->result_array(),
|
||||||
"total" => $que_total->row_array()['total']
|
"total" =>$que_total->row_array()['total']
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->sys_ok($output);
|
$this->sys_ok($output);
|
||||||
|
exit;
|
||||||
} catch (Exception $exc) {
|
} catch (Exception $exc) {
|
||||||
$message = $exc->getMessage();
|
$message = $exc->getMessage();
|
||||||
$code = $exc->getCode();
|
$code = $exc->getCode();
|
||||||
@@ -164,169 +96,70 @@ class Billv2 extends MY_Controller {
|
|||||||
|
|
||||||
$para = $this->sys_input;
|
$para = $this->sys_input;
|
||||||
|
|
||||||
// ── Detect payment type ──────────────────────────────────
|
$sql = "SELECT
|
||||||
$sql_type = "SELECT
|
SupplierInvoiceID,
|
||||||
SupplierPaymentSupplierInvoiceID,
|
SupplierInvoiceRefNumber,
|
||||||
SupplierPaymentSupplierDownpaymentID,
|
SupplierInvoiceDeliveryOrderNumber,
|
||||||
SupplierPaymentSupplierInstallmentID
|
SupplierInvoiceSupplierInvoiceNumber,
|
||||||
FROM supplier_payment
|
SupplierInvoiceSupplierInvoiceDate,
|
||||||
WHERE SupplierPaymentID = ? AND SupplierPaymentIsActive = 'Y'";
|
SupplierInvoiceSubTotal,
|
||||||
|
SupplierInvoiceTaxPercentPph,
|
||||||
$que_type = $this->db->query($sql_type, [$para['paymentID']]);
|
SupplierInvoiceTaxPercentPpn,
|
||||||
if (!$que_type) {
|
SupplierInvoiceTaxAmountPpn,
|
||||||
throw new Exception("[Error] failed get payment header", 2);
|
SupplierInvoiceDiscountAmount,
|
||||||
|
SupplierInvoiceDiscountPercent,
|
||||||
|
SupplierInvoiceShippingCost,
|
||||||
|
SupplierInvoiceGrandTotal,
|
||||||
|
SupplierInvoiceAdjustmentAmount,
|
||||||
|
SupplierInvoiceAdjustmentNote,
|
||||||
|
SupplierInvoiceNote,
|
||||||
|
IF (SupplierInvoiceDiscountAmount > 0, 'R', 'P') AS DiscountType
|
||||||
|
FROM supplier_payment
|
||||||
|
JOIN supplier_invoice ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID
|
||||||
|
AND SupplierPaymentID = ?
|
||||||
|
AND SupplierPaymentIsActive = 'Y'";
|
||||||
|
$que = $this->db->query($sql, [$para['paymentID']]);
|
||||||
|
if (!$que) {
|
||||||
|
throw new Exception("[Error] failed get row data", 2);
|
||||||
}
|
}
|
||||||
$payment = $que_type->row_array();
|
$data = $que->row_array();
|
||||||
if (!$payment) {
|
|
||||||
throw new Exception("[Error] payment not found", 2);
|
$sql_detail = "SELECT
|
||||||
|
SupplierInvoiceDetailID,
|
||||||
|
SupplierInvoiceDetailSupplierInvoiceID,
|
||||||
|
SupplierInvoiceDetailPurchaseOrderID,
|
||||||
|
SupplierInvoiceDetailPurchaseOrderSummaryID,
|
||||||
|
SupplierInvoiceDetailReceiveOrderPoID,
|
||||||
|
SupplierInvoiceDetailReceiveOrderPoDetailID,
|
||||||
|
SupplierInvoiceDetailItemID,
|
||||||
|
SupplierInvoiceDetailItemUnitID,
|
||||||
|
SupplierInvoiceDetailDescription,
|
||||||
|
SupplierInvoiceDetailQty,
|
||||||
|
SupplierInvoiceDetailPrice,
|
||||||
|
SupplierInvoiceDetailDiscountPercent,
|
||||||
|
SupplierInvoiceDetailDiscountDiscountRupiah,
|
||||||
|
SupplierInvoiceDetailDiscountDiscountType,
|
||||||
|
SupplierInvoiceDetailDiscountAmount,
|
||||||
|
(SupplierInvoiceDetailPrice - SupplierInvoiceDetailDiscountAmount) AS DiscountedPrice,
|
||||||
|
SupplierInvoiceDetailDiscountPoProrata,
|
||||||
|
SupplierInvoiceDetailTotal,
|
||||||
|
M_ItemCode,
|
||||||
|
M_ItemDesc
|
||||||
|
FROM supplier_payment_detail
|
||||||
|
JOIN supplier_invoice_detail ON SupplierInvoiceDetailIsActive = 'Y'
|
||||||
|
AND SupplierPaymentDetailSupplierPaymentID = ?
|
||||||
|
AND SupplierInvoiceDetailSupplierInvoiceID = ?
|
||||||
|
JOIN m_item ON M_ItemID = SupplierInvoiceDetailItemID
|
||||||
|
AND M_ItemIsActive = 'Y'
|
||||||
|
GROUP BY SupplierInvoiceDetailID";
|
||||||
|
$que_detail = $this->db->query($sql_detail, [
|
||||||
|
$para['paymentID'], $data['SupplierInvoiceID']
|
||||||
|
]);
|
||||||
|
if (!$que_detail) {
|
||||||
|
throw new Exception("[Error] failed to get item payments", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── INVOICE branch ──────────────────────────────────────
|
$data['detail'] = $que_detail->result_array();
|
||||||
if ($payment['SupplierPaymentSupplierInvoiceID'] > 0) {
|
|
||||||
$sql = "SELECT
|
|
||||||
si.SupplierInvoiceSubTotal,
|
|
||||||
si.SupplierInvoiceShippingCost,
|
|
||||||
si.SupplierInvoiceDiscountPercent,
|
|
||||||
si.SupplierInvoiceDiscountAmount,
|
|
||||||
si.SupplierInvoiceTaxPercentPpn,
|
|
||||||
si.SupplierInvoiceTaxAmountPpn,
|
|
||||||
si.SupplierInvoiceGrandTotal,
|
|
||||||
si.SupplierInvoiceID,
|
|
||||||
'INVOICE' AS type
|
|
||||||
FROM supplier_payment sp
|
|
||||||
JOIN supplier_invoice si
|
|
||||||
ON si.SupplierInvoiceID = sp.SupplierPaymentSupplierInvoiceID
|
|
||||||
WHERE sp.SupplierPaymentID = ? AND sp.SupplierPaymentIsActive = 'Y'";
|
|
||||||
|
|
||||||
$que = $this->db->query($sql, [$para['paymentID']]);
|
|
||||||
if (!$que) {
|
|
||||||
throw new Exception("[Error] failed get row data", 2);
|
|
||||||
}
|
|
||||||
$data = $que->row_array();
|
|
||||||
|
|
||||||
$sql_detail = "SELECT
|
|
||||||
M_ItemDesc,
|
|
||||||
SupplierInvoiceDetailQty,
|
|
||||||
SupplierInvoiceDetailPrice,
|
|
||||||
SupplierInvoiceDetailDiscountAmount,
|
|
||||||
(SupplierInvoiceDetailPrice - SupplierInvoiceDetailDiscountAmount) AS DiscountedPrice,
|
|
||||||
SupplierInvoiceDetailTotal
|
|
||||||
FROM supplier_payment_detail
|
|
||||||
JOIN supplier_invoice_detail
|
|
||||||
ON SupplierInvoiceDetailIsActive = 'Y'
|
|
||||||
AND SupplierPaymentDetailSupplierPaymentID = ?
|
|
||||||
AND SupplierInvoiceDetailSupplierInvoiceID = ?
|
|
||||||
JOIN m_item
|
|
||||||
ON M_ItemID = SupplierInvoiceDetailItemID AND M_ItemIsActive = 'Y'
|
|
||||||
GROUP BY SupplierInvoiceDetailID";
|
|
||||||
|
|
||||||
$que_detail = $this->db->query($sql_detail, [
|
|
||||||
$para['paymentID'], $data['SupplierInvoiceID']
|
|
||||||
]);
|
|
||||||
if (!$que_detail) {
|
|
||||||
throw new Exception("[Error] failed to get item payments", 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($data['SupplierInvoiceID']);
|
|
||||||
$data['detail'] = $que_detail->result_array();
|
|
||||||
|
|
||||||
// ── DOWNPAYMENT branch ──────────────────────────────────
|
|
||||||
} elseif ($payment['SupplierPaymentSupplierDownpaymentID'] > 0) {
|
|
||||||
$sql = "SELECT
|
|
||||||
dp.SupplierDownpaymentPurchasOrderID,
|
|
||||||
dp.SupplierDownpaymentAmount AS SupplierInvoiceSubTotal,
|
|
||||||
0 AS SupplierInvoiceShippingCost,
|
|
||||||
0 AS SupplierInvoiceDiscountPercent,
|
|
||||||
0 AS SupplierInvoiceDiscountAmount,
|
|
||||||
0 AS SupplierInvoiceTaxPercentPpn,
|
|
||||||
0 AS SupplierInvoiceTaxAmountPpn,
|
|
||||||
dp.SupplierDownpaymentAmount AS SupplierInvoiceGrandTotal,
|
|
||||||
'DP' AS type
|
|
||||||
FROM supplier_payment sp
|
|
||||||
JOIN supplier_downpayment dp
|
|
||||||
ON dp.SupplierDownpaymentID = sp.SupplierPaymentSupplierDownpaymentID
|
|
||||||
WHERE sp.SupplierPaymentID = ? AND sp.SupplierPaymentIsActive = 'Y'";
|
|
||||||
|
|
||||||
$que = $this->db->query($sql, [$para['paymentID']]);
|
|
||||||
if (!$que) {
|
|
||||||
throw new Exception("[Error] failed get DP row data", 2);
|
|
||||||
}
|
|
||||||
$data = $que->row_array();
|
|
||||||
|
|
||||||
$sql_detail = "SELECT
|
|
||||||
CONCAT('DP-', M_ItemDesc) AS M_ItemDesc,
|
|
||||||
PurchaseOrderDetailQty AS SupplierInvoiceDetailQty,
|
|
||||||
PurchaseOrderDetailPrice AS SupplierInvoiceDetailPrice,
|
|
||||||
PurchaseOrderSummaryDiscountAmount AS SupplierInvoiceDetailDiscountAmount,
|
|
||||||
(PurchaseOrderDetailPrice - PurchaseOrderSummaryDiscountAmount) AS DiscountedPrice,
|
|
||||||
PurchaseOrderSummaryTotal AS SupplierInvoiceDetailTotal
|
|
||||||
FROM supplier_downpayment
|
|
||||||
JOIN purchase_order
|
|
||||||
ON SupplierDownpaymentPurchasOrderID = PurchaseOrderID
|
|
||||||
JOIN purchase_order_detail
|
|
||||||
ON PurchaseOrderDetailPurchaseOrderID = PurchaseOrderID
|
|
||||||
AND PurchaseOrderDetailIsActive = 'Y'
|
|
||||||
JOIN purchase_order_summary
|
|
||||||
ON PurchaseOrderSummaryID = PurchaseOrderDetailPurchaseSummaryID
|
|
||||||
AND PurchaseOrderSummaryIsActive = 'Y'
|
|
||||||
JOIN m_item
|
|
||||||
ON M_ItemID = PurchaseOrderDetailItemID
|
|
||||||
WHERE SupplierDownpaymentPurchasOrderID = ?";
|
|
||||||
|
|
||||||
$que_detail = $this->db->query($sql_detail, [
|
|
||||||
$data['SupplierDownpaymentPurchasOrderID']
|
|
||||||
]);
|
|
||||||
if (!$que_detail) {
|
|
||||||
throw new Exception('failed to get dp detail', 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['detail'] = $que_detail->result_array();
|
|
||||||
} else {
|
|
||||||
$sql = "SELECT
|
|
||||||
inst.SupplierInstallmentAmount AS SupplierInvoiceSubTotal,
|
|
||||||
0 AS SupplierInvoiceShippingCost,
|
|
||||||
0 AS SupplierInvoiceDiscountPercent,
|
|
||||||
0 AS SupplierInvoiceDiscountAmount,
|
|
||||||
0 AS SupplierInvoiceTaxPercentPpn,
|
|
||||||
0 AS SupplierInvoiceTaxAmountPpn,
|
|
||||||
inst.SupplierInstallmentAmount AS SupplierInvoiceGrandTotal,
|
|
||||||
si.SupplierInvoiceID,
|
|
||||||
'INSTALLMENT' AS type
|
|
||||||
FROM supplier_payment sp
|
|
||||||
JOIN supplier_installment inst
|
|
||||||
ON inst.SupplierInstallmentID = sp.SupplierPaymentSupplierInstallmentID
|
|
||||||
JOIN supplier_invoice si
|
|
||||||
ON si.SupplierInvoiceID = inst.SupplierInstallmentSupplierInvoiceID
|
|
||||||
WHERE sp.SupplierPaymentID = ? AND sp.SupplierPaymentIsActive = 'Y'";
|
|
||||||
|
|
||||||
$que = $this->db->query($sql, [$para['paymentID']]);
|
|
||||||
if (!$que) {
|
|
||||||
throw new Exception("[Error] failed get Installment row data", 2);
|
|
||||||
}
|
|
||||||
$data = $que->row_array();
|
|
||||||
|
|
||||||
$sql_detail = "SELECT
|
|
||||||
M_ItemDesc,
|
|
||||||
SupplierInvoiceDetailQty,
|
|
||||||
SupplierInvoiceDetailPrice,
|
|
||||||
SupplierInvoiceDetailDiscountAmount,
|
|
||||||
(SupplierInvoiceDetailPrice - SupplierInvoiceDetailDiscountAmount) AS DiscountedPrice,
|
|
||||||
SupplierInvoiceDetailTotal
|
|
||||||
FROM supplier_invoice_detail
|
|
||||||
JOIN m_item
|
|
||||||
ON M_ItemID = SupplierInvoiceDetailItemID AND M_ItemIsActive = 'Y'
|
|
||||||
WHERE SupplierInvoiceDetailSupplierInvoiceID = ?
|
|
||||||
AND SupplierInvoiceDetailIsActive = 'Y'
|
|
||||||
GROUP BY SupplierInvoiceDetailID";
|
|
||||||
|
|
||||||
$que_detail = $this->db->query($sql_detail, [$data['SupplierInvoiceID']]);
|
|
||||||
if (!$que_detail) {
|
|
||||||
throw new Exception("[Error] failed to get installment item payments", 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($data['SupplierInvoiceID']);
|
|
||||||
$data['detail'] = $que_detail->result_array();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->sys_ok($data);
|
$this->sys_ok($data);
|
||||||
} catch (Exception $exc) {
|
} catch (Exception $exc) {
|
||||||
@@ -381,12 +214,12 @@ class Billv2 extends MY_Controller {
|
|||||||
$user = $this->sys_user;
|
$user = $this->sys_user;
|
||||||
|
|
||||||
if ($para['userlevel'] == '1') {
|
if ($para['userlevel'] == '1') {
|
||||||
$sql = "UPDATE supplier_payment SET
|
$sql = "UPDATE supplier_payment SET
|
||||||
SupplierPaymentIsVerif = 'Y',
|
SupplierPaymentIsVerif = 'Y',
|
||||||
SupplierPaymentStatus = 'Verified',
|
SupplierPaymentStatus = 'Verified',
|
||||||
SupplierPaymentVerifUserID = ?,
|
SupplierPaymentVerifUserID = ?,
|
||||||
SupplierPaymentVerifDate = NOW()
|
SupplierPaymentVerifDate = NOW()
|
||||||
WHERE SupplierPaymentID = ?
|
WHERE SupplierPaymentID = ?
|
||||||
AND SupplierPaymentIsActive = 'Y'";
|
AND SupplierPaymentIsActive = 'Y'";
|
||||||
$query = $this->db->query($sql, [
|
$query = $this->db->query($sql, [
|
||||||
$user['M_UserID'], $para['paymentID']
|
$user['M_UserID'], $para['paymentID']
|
||||||
@@ -398,12 +231,12 @@ class Billv2 extends MY_Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($para['userlevel'] == '2') {
|
if ($para['userlevel'] == '2') {
|
||||||
$sql = "UPDATE supplier_payment SET
|
$sql = "UPDATE supplier_payment SET
|
||||||
SupplierPaymentIsApproved = 'Y',
|
SupplierPaymentIsApproved = 'Y',
|
||||||
SupplierPaymentStatus = 'Approved',
|
SupplierPaymentStatus = 'Approved',
|
||||||
SupplierPaymentApprovedUserID = ?,
|
SupplierPaymentApprovedUserID = ?,
|
||||||
SupplierPaymentApprovedDate = NOW()
|
SupplierPaymentApprovedDate = NOW()
|
||||||
WHERE SupplierPaymentID = ?
|
WHERE SupplierPaymentID = ?
|
||||||
AND SupplierPaymentIsActive = 'Y'";
|
AND SupplierPaymentIsActive = 'Y'";
|
||||||
$query = $this->db->query($sql, [
|
$query = $this->db->query($sql, [
|
||||||
$user['M_UserID'], $para['paymentID']
|
$user['M_UserID'], $para['paymentID']
|
||||||
@@ -428,4 +261,4 @@ class Billv2 extends MY_Controller {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
class Bill extends MY_Controller
|
class Bill extends MY_Controller
|
||||||
{
|
{
|
||||||
var $db_onedev;
|
var $db_onedev;
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
echo "Bill API";
|
echo "Bill API";
|
||||||
}
|
}
|
||||||
|
public function __construct()
|
||||||
public function __construct()
|
{
|
||||||
{
|
parent::__construct();
|
||||||
parent::__construct();
|
$this->db_onedev = $this->load->database("onedev", true);
|
||||||
$this->db_onedev = $this->load->database("onedev", true);
|
}
|
||||||
}
|
|
||||||
|
public function add_notes($orderid){
|
||||||
public function add_notes($orderid)
|
$sql = " SELECT SupplierPaymentSupplierInvoiceID as note_order_id,
|
||||||
{
|
SupplierPaymentID as note_id,
|
||||||
$sql = "SELECT SupplierPaymentSupplierInvoiceID as note_order_id,
|
|
||||||
SupplierPaymentID as note_id,
|
|
||||||
SupplierPaymentDetailSupplierInvoiceDetailID as detail_id,
|
SupplierPaymentDetailSupplierInvoiceDetailID as detail_id,
|
||||||
SupplierPaymentDate as note_date,
|
SupplierPaymentDate as note_date,
|
||||||
SupplierPaymentNumber as note_number,
|
SupplierPaymentNumber as note_number,
|
||||||
@@ -43,205 +41,63 @@ class Bill extends MY_Controller
|
|||||||
LEFT JOIN m_user a ON SupplierPaymentApprovedUserID = a.M_UserID
|
LEFT JOIN m_user a ON SupplierPaymentApprovedUserID = a.M_UserID
|
||||||
LEFT JOIN m_user b ON SupplierPaymentVerifUserID = b.M_UserID
|
LEFT JOIN m_user b ON SupplierPaymentVerifUserID = b.M_UserID
|
||||||
WHERE
|
WHERE
|
||||||
SupplierPaymentSupplierInvoiceID = {$orderid}
|
SupplierPaymentSupplierInvoiceID = {$orderid}
|
||||||
AND
|
AND
|
||||||
SupplierPaymentIsActive = 'Y'
|
SupplierPaymentIsActive = 'Y'
|
||||||
GROUP BY SupplierPaymentID";
|
GROUP BY SupplierPaymentID";
|
||||||
$query = $this->db_onedev->query($sql);
|
$query = $this->db_onedev->query($sql);
|
||||||
if ($query) {
|
if ($query) {
|
||||||
$rows = $query->result_array();
|
$rows = $query->result_array();
|
||||||
if ($rows) {
|
if($rows){
|
||||||
foreach ($rows as $k => $v) {
|
foreach($rows as $k => $v){
|
||||||
$rows[$k]['tests'] = $this->add_tests($v['note_id']);
|
$rows[$k]['tests'] = $this->add_tests($v['note_id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $rows;
|
return $rows;
|
||||||
} else {
|
|
||||||
$this->sys_error_db("get notes", $this->db_onedev);
|
} else {
|
||||||
exit;
|
$this->sys_error_db("get notes", $this->db_onedev);
|
||||||
}
|
exit;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
public function add_tagihans($orderid){
|
||||||
|
$sql = "SELECT SupplierInvoiceID as tagihan_id,
|
||||||
|
PurchaseOrderNumber as tagihan_number,
|
||||||
|
jurnalTxDescription as pasien,
|
||||||
|
jurnalTxCredit as tagihan_total,
|
||||||
|
IF(SupplierPaymentDetailID IS NULL , jurnalTxCredit, jurnalTxCredit - SUM(SupplierPaymentDetailAmount)) as tagihan_tagihan,
|
||||||
|
0 as tagihan_bayar,
|
||||||
|
DATE_FORMAT(SupplierInvoiceDueDate,'%d-%m-%Y') as tagihan_duedate,
|
||||||
|
SupplierInvoiceIsActive as tagihan_active,
|
||||||
|
'N' as show_detail,
|
||||||
|
jurnalTxID SupplierInvoiceDetailID,
|
||||||
|
PurchaseOrderID SupplierInvoiceDetailPurchaseOrderID
|
||||||
|
|
||||||
public function add_notes_downpayment($orderid)
|
FROM supplier_invoice
|
||||||
{
|
JOIN receive_order_po ON ReceiveOrderPoID = SupplierInvoiceReceiveOrderPoID
|
||||||
$sql = "SELECT SupplierPaymentSupplierDownpaymentID AS note_order_id,
|
JOIN receive_order_po_detail ON ReceiveOrderPoDetailReceiveOrderPoID = ReceiveOrderPoID
|
||||||
SupplierPaymentID AS note_id,
|
JOIN purchase_order ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID
|
||||||
SupplierDownpaymentID AS detail_id,
|
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
||||||
SupplierPaymentDate AS note_date,
|
JOIN jurnal_tx ON jurnalTxJurnalID = jurnalAddOnJurnalID AND jurnalTxCredit <> 0 AND jurnalTxCoaID <> 563
|
||||||
SupplierPaymentNumber AS note_number,
|
LEFT JOIN supplier_payment ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID AND SupplierInvoiceIsActive = 'Y'
|
||||||
GROUP_CONCAT(DISTINCT coaDescription separator ' , ') AS paymenttypes_name,
|
LEFT JOIN supplier_payment_detail ON SupplierPaymentDetailSupplierPaymentID = SupplierPaymentID AND SupplierPaymentDetailSupplierInvoiceDetailID = jurnalTxID AND SupplierPaymentDetailIsActive = 'Y'
|
||||||
SUM(SupplierDownpaymentAmount) AS note_amount,
|
WHERE
|
||||||
n.M_UserUsername AS note_user,
|
SupplierInvoiceID = {$orderid}
|
||||||
SupplierDownpaymentIsActive AS note_active,
|
GROUP BY jurnalTxID
|
||||||
'N' AS show_detail,
|
";
|
||||||
SupplierPaymentNote AS keterangan,
|
$query = $this->db_onedev->query($sql);
|
||||||
SupplierPaymentCoaID,
|
if ($query) {
|
||||||
coaID,
|
$rows = $query->result_array();
|
||||||
coaDescription,
|
return $rows;
|
||||||
SupplierPaymentIsConfirm,
|
|
||||||
CONCAT(
|
} else {
|
||||||
'Confirmed by : ',c.M_UserUsername, ' ',
|
$this->sys_error_db("get notes", $this->db_onedev);
|
||||||
DATE_FORMAT(SupplierPaymentConfirmDate, '%d-%m-%Y %H:%i')
|
exit;
|
||||||
) AS d_confirm,
|
}
|
||||||
SupplierPaymentIsApproved,
|
}
|
||||||
CONCAT(
|
public function add_tests($orderid){
|
||||||
'Approved by : ',a.M_UserUsername, ' ',
|
$sql = " SELECT SupplierPaymentSupplierInvoiceID as note_order_id,
|
||||||
DATE_FORMAT(SupplierPaymentApprovedDate,'%d-%m-%Y %H:%i')
|
SupplierPaymentID as note_id,
|
||||||
) AS d_approved,
|
|
||||||
CONCAT(
|
|
||||||
'Verified by : ',b.M_UserUsername, ' ',
|
|
||||||
DATE_FORMAT(SupplierPaymentVerifDate,'%d-%m-%Y %H:%i')
|
|
||||||
) AS d_verif
|
|
||||||
FROM supplier_payment
|
|
||||||
JOIN supplier_downpayment
|
|
||||||
ON SupplierDownpaymentID = SupplierPaymentSupplierDownpaymentID
|
|
||||||
AND SupplierDownpaymentIsActive = 'Y'
|
|
||||||
LEFT JOIN coa ON SupplierPaymentCoaID = coaID
|
|
||||||
LEFT JOIN m_user n ON SupplierPaymentUserID = n.M_UserID
|
|
||||||
LEFT JOIN m_user c ON SupplierPaymentConfirmUserID = c.M_UserID
|
|
||||||
LEFT JOIN m_user a ON SupplierPaymentApprovedUserID = a.M_UserID
|
|
||||||
LEFT JOIN m_user b ON SupplierPaymentVerifUserID = b.M_UserID
|
|
||||||
WHERE SupplierPaymentSupplierDownpaymentID = {$orderid}
|
|
||||||
AND SupplierPaymentIsActive = 'Y'
|
|
||||||
GROUP BY SupplierPaymentID";
|
|
||||||
$query = $this->db_onedev->query($sql);
|
|
||||||
if ($query) {
|
|
||||||
$rows = $query->result_array();
|
|
||||||
return $rows ?: [];
|
|
||||||
} else {
|
|
||||||
$this->sys_error_db("get DP notes", $this->db_onedev);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function add_notes_installment($orderid)
|
|
||||||
{
|
|
||||||
$sql = "SELECT SupplierPaymentSupplierInstallmentID as note_order_id,
|
|
||||||
SupplierPaymentID as note_id,
|
|
||||||
SupplierInstallmentID as detail_id,
|
|
||||||
SupplierPaymentDate as note_date,
|
|
||||||
SupplierPaymentNumber as note_number,
|
|
||||||
GROUP_CONCAT(DISTINCT coaDescription separator ' , ') as paymenttypes_name,
|
|
||||||
SUM(SupplierInstallmentAmount) as note_amount,
|
|
||||||
n.M_UserUsername as note_user,
|
|
||||||
SupplierInstallmentIsActive as note_active,
|
|
||||||
'N' as show_detail,
|
|
||||||
SupplierPaymentNote as keterangan,
|
|
||||||
SupplierPaymentCoaID,
|
|
||||||
coaID,
|
|
||||||
coaDescription,
|
|
||||||
SupplierPaymentIsConfirm,
|
|
||||||
CONCAT(
|
|
||||||
'Confirmed by : ',c.M_UserUsername, ' ',
|
|
||||||
DATE_FORMAT(SupplierPaymentConfirmDate,'%d-%m-%Y %H:%i')
|
|
||||||
) AS d_confirm,
|
|
||||||
SupplierPaymentIsApproved,
|
|
||||||
CONCAT(
|
|
||||||
'Approved by : ',a.M_UserUsername, ' ',
|
|
||||||
DATE_FORMAT(SupplierPaymentApprovedDate,'%d-%m-%Y %H:%i')
|
|
||||||
) AS d_approved,
|
|
||||||
CONCAT(
|
|
||||||
'Verified by : ',b.M_UserUsername, ' ',
|
|
||||||
DATE_FORMAT(SupplierPaymentVerifDate,'%d-%m-%Y %H:%i')
|
|
||||||
) AS d_verif
|
|
||||||
FROM supplier_payment
|
|
||||||
JOIN supplier_installment
|
|
||||||
ON SupplierInstallmentID = SupplierPaymentSupplierInstallmentID
|
|
||||||
AND SupplierInstallmentIsActive = 'Y'
|
|
||||||
LEFT JOIN coa ON SupplierPaymentCoaID = coaID
|
|
||||||
LEFT JOIN m_user n ON SupplierPaymentUserID = n.M_UserID
|
|
||||||
LEFT JOIN m_user c ON SupplierPaymentConfirmUserID = c.M_UserID
|
|
||||||
LEFT JOIN m_user a ON SupplierPaymentApprovedUserID = a.M_UserID
|
|
||||||
LEFT JOIN m_user b ON SupplierPaymentVerifUserID = b.M_UserID
|
|
||||||
WHERE SupplierPaymentSupplierInstallmentID = {$orderid}
|
|
||||||
AND SupplierPaymentIsActive = 'Y'
|
|
||||||
GROUP BY SupplierPaymentID";
|
|
||||||
$query = $this->db_onedev->query($sql);
|
|
||||||
if ($query) {
|
|
||||||
$rows = $query->result_array();
|
|
||||||
return $rows ?: [];
|
|
||||||
} else {
|
|
||||||
$this->sys_error_db("get Installment notes", $this->db_onedev);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function add_tagihans($orderid)
|
|
||||||
{
|
|
||||||
$sql_dp = "SELECT
|
|
||||||
Fa_ClassDownPaymentCoaID
|
|
||||||
FROM supplier_invoice_detail
|
|
||||||
JOIN m_item
|
|
||||||
ON M_ItemID = SupplierInvoiceDetailItemID
|
|
||||||
AND SupplierInvoiceDetailSupplierInvoiceID = ?
|
|
||||||
AND SupplierInvoiceDetailIsActive = 'Y'
|
|
||||||
AND SupplierInvoiceDetailIsVerified = 'Y'
|
|
||||||
JOIN fa_class
|
|
||||||
ON Fa_ClassID = M_ItemFa_ClassID
|
|
||||||
AND Fa_ClassIsActive = 'Y'";
|
|
||||||
$que_dp = $this->db_onedev->query($sql_dp, [$orderid]);
|
|
||||||
if (!$que_dp) {
|
|
||||||
$this->sys_error_db("failed to get coa id dp tagihans", $this->db_onedev);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
$dataDP = $que_dp->result_array();
|
|
||||||
$excludeIds = array_column($dataDP, 'Fa_ClassDownPaymentCoaID');
|
|
||||||
$excludeIds[] = 563; // always excluded
|
|
||||||
$excludeIds = array_unique($excludeIds);
|
|
||||||
$excludeIds = array_values($excludeIds); // re-index
|
|
||||||
|
|
||||||
$notInPlaceholders = implode(',', array_fill(0, count($excludeIds), '?'));
|
|
||||||
|
|
||||||
$sql = "SELECT
|
|
||||||
SupplierInvoiceID as tagihan_id,
|
|
||||||
PurchaseOrderNumber as tagihan_number,
|
|
||||||
jurnalTxDescription as pasien,
|
|
||||||
jurnalTxCredit as tagihan_total,
|
|
||||||
IF(SupplierPaymentDetailID IS NULL , jurnalTxCredit, jurnalTxCredit - SUM(SupplierPaymentDetailAmount)) as tagihan_tagihan,
|
|
||||||
0 as tagihan_bayar,
|
|
||||||
DATE_FORMAT(SupplierInvoiceDueDate,'%d-%m-%Y') as tagihan_duedate,
|
|
||||||
SupplierInvoiceIsActive as tagihan_active,
|
|
||||||
'N' as show_detail,
|
|
||||||
jurnalTxID SupplierInvoiceDetailID,
|
|
||||||
PurchaseOrderID SupplierInvoiceDetailPurchaseOrderID
|
|
||||||
FROM supplier_invoice
|
|
||||||
JOIN receive_order_po
|
|
||||||
ON ReceiveOrderPoID = SupplierInvoiceReceiveOrderPoID
|
|
||||||
JOIN receive_order_po_detail
|
|
||||||
ON ReceiveOrderPoDetailReceiveOrderPoID = ReceiveOrderPoID
|
|
||||||
JOIN purchase_order
|
|
||||||
ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID
|
|
||||||
JOIN jurnal_addon
|
|
||||||
ON jurnalAddOnValue = SupplierInvoiceNumber
|
|
||||||
AND jurnalAddOnIsActive = 'Y'
|
|
||||||
JOIN jurnal_tx
|
|
||||||
ON jurnalTxJurnalID = jurnalAddOnJurnalID
|
|
||||||
AND jurnalTxIsActive = 'Y'
|
|
||||||
AND jurnalTxCredit <> 0
|
|
||||||
AND jurnalTxCoaID NOT IN ($notInPlaceholders)
|
|
||||||
LEFT JOIN supplier_payment
|
|
||||||
ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID
|
|
||||||
AND SupplierInvoiceIsActive = 'Y'
|
|
||||||
LEFT JOIN supplier_payment_detail
|
|
||||||
ON SupplierPaymentDetailSupplierPaymentID = SupplierPaymentID
|
|
||||||
AND SupplierPaymentDetailSupplierInvoiceDetailID = jurnalTxID
|
|
||||||
AND SupplierPaymentDetailIsActive = 'Y'
|
|
||||||
WHERE SupplierInvoiceID = ?
|
|
||||||
GROUP BY jurnalTxID";
|
|
||||||
$query = $this->db_onedev->query($sql, array_merge($excludeIds, [$orderid]));
|
|
||||||
if ($query) {
|
|
||||||
$rows = $query->result_array();
|
|
||||||
return $rows;
|
|
||||||
} else {
|
|
||||||
$this->sys_error_db("get tagihans", $this->db_onedev);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function add_tests($orderid)
|
|
||||||
{
|
|
||||||
$sql = " SELECT SupplierPaymentSupplierInvoiceID as note_order_id,
|
|
||||||
SupplierPaymentID as note_id,
|
|
||||||
SupplierPaymentDate as note_date,
|
SupplierPaymentDate as note_date,
|
||||||
SupplierPaymentNumber as note_number,
|
SupplierPaymentNumber as note_number,
|
||||||
GROUP_CONCAT(coaDescription separator ' , ') as paymenttypes_name,
|
GROUP_CONCAT(coaDescription separator ' , ') as paymenttypes_name,
|
||||||
@@ -252,537 +108,150 @@ class Bill extends MY_Controller
|
|||||||
SupplierInvoiceDetailTotal,
|
SupplierInvoiceDetailTotal,
|
||||||
SupplierPaymentDetailAmount
|
SupplierPaymentDetailAmount
|
||||||
FROM supplier_payment
|
FROM supplier_payment
|
||||||
JOIN supplier_payment_detail ON SupplierPaymentDetailSupplierPaymentID = SupplierPaymentID
|
JOIN supplier_payment_detail ON SupplierPaymentDetailSupplierPaymentID = SupplierPaymentID
|
||||||
LEFT JOIN supplier_invoice_detail ON SupplierPaymentDetailSupplierInvoiceDetailID = SupplierInvoiceDetailID
|
LEFT JOIN supplier_invoice_detail ON SupplierPaymentDetailSupplierInvoiceDetailID = SupplierInvoiceDetailID
|
||||||
LEFT JOIN purchase_order ON SupplierInvoiceDetailPurchaseOrderID = PurchaseOrderID
|
LEFT JOIN purchase_order ON SupplierInvoiceDetailPurchaseOrderID = PurchaseOrderID
|
||||||
LEFT JOIN coa ON SupplierPaymentCoaID = coaID
|
LEFT JOIN coa ON SupplierPaymentCoaID = coaID
|
||||||
LEFT JOIN m_user ON SupplierPaymentDetailUserID = M_UserID
|
LEFT JOIN m_user ON SupplierPaymentDetailUserID = M_UserID
|
||||||
WHERE
|
WHERE
|
||||||
SupplierPaymentID = {$orderid}
|
SupplierPaymentID = {$orderid}
|
||||||
GROUP BY SupplierPaymentDetailID";
|
GROUP BY SupplierPaymentDetailID";
|
||||||
$query = $this->db_onedev->query($sql);
|
$query = $this->db_onedev->query($sql);
|
||||||
if ($query) {
|
if ($query) {
|
||||||
$rows = $query->result_array();
|
$rows = $query->result_array();
|
||||||
if ($rows) {
|
if($rows){
|
||||||
}
|
}
|
||||||
return $rows;
|
return $rows;
|
||||||
} else {
|
|
||||||
$this->sys_error_db("get notes", $this->db_onedev);
|
} else {
|
||||||
exit;
|
$this->sys_error_db("get notes", $this->db_onedev);
|
||||||
}
|
exit;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public function search_old()
|
public function search()
|
||||||
{
|
{
|
||||||
//# cek token valid
|
//# cek token valid
|
||||||
if (! $this->isLogin) {
|
if (! $this->isLogin) {
|
||||||
$this->sys_error("Invalid Token");
|
$this->sys_error("Invalid Token");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
$prm = $this->sys_input;
|
||||||
$prm = $this->sys_input;
|
$supplier = $prm["supplier"];
|
||||||
$supplier = $prm["supplier"];
|
$search = $prm["search"];
|
||||||
$search = $prm["search"];
|
$status = $prm["status"];
|
||||||
$status = $prm["status"];
|
$startdate = $prm["startdate"];
|
||||||
$startdate = $prm["startdate"];
|
$enddate = $prm["enddate"];
|
||||||
$enddate = $prm["enddate"];
|
$regionalid = $this->sys_user['S_RegionalID'];
|
||||||
$regionalid = $this->sys_user['S_RegionalID'];
|
|
||||||
|
$number_limit = 10;
|
||||||
$number_limit = 10;
|
$number_offset = ($prm['current_page'] - 1) * $number_limit ;
|
||||||
$number_offset = ($prm['current_page'] - 1) * $number_limit;
|
|
||||||
|
$where = "SupplierInvoiceIsActive = 'Y'
|
||||||
$where = "SupplierInvoiceIsActive = 'Y'
|
AND SupplierInvoiceStatus = 'Approved'
|
||||||
AND SupplierInvoiceStatus = 'Approved'
|
AND SupplierInvoiceGrandTotal > 0
|
||||||
AND SupplierInvoiceGrandTotal > 0
|
AND IF(SupplierPaymentID IS NULL,'N','Y') = '{$status}'
|
||||||
AND IF(SupplierPaymentID IS NULL,'N','Y') = '{$status}'
|
AND (SupplierInvoiceNumber LIKE '%{$search}%' AND SupplierName LIKE '%{$supplier}%')
|
||||||
AND (SupplierInvoiceNumber LIKE '%{$search}%' AND SupplierName LIKE '%{$supplier}%')
|
AND ReceiveOrderPoS_RegionalID = {$regionalid}
|
||||||
AND ReceiveOrderPoS_RegionalID = {$regionalid}
|
AND SupplierInvoiceDraftPaymentDate BETWEEN '{$startdate}' AND '{$enddate}'";
|
||||||
AND SupplierInvoiceDraftPaymentDate BETWEEN '{$startdate}' AND '{$enddate}'";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$sql = " SELECT count(*) as total
|
||||||
$sql = " SELECT count(*) as total
|
FROM supplier_invoice
|
||||||
FROM supplier_invoice
|
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
||||||
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
LEFT JOIN supplier_payment ON SupplierInvoiceID = SupplierPaymentSupplierInvoiceID AND SupplierPaymentIsActive = 'Y'
|
||||||
LEFT JOIN supplier_payment ON SupplierInvoiceID = SupplierPaymentSupplierInvoiceID AND SupplierPaymentIsActive = 'Y'
|
LEFT JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
||||||
LEFT JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
JOIN receive_order_po ON SupplierInvoiceReceiveOrderPoID = ReceiveOrderPoID
|
||||||
JOIN receive_order_po ON SupplierInvoiceReceiveOrderPoID = ReceiveOrderPoID
|
WHERE
|
||||||
WHERE
|
$where
|
||||||
$where
|
";
|
||||||
";
|
// echo $sql;
|
||||||
// echo $sql;
|
$query = $this->db_onedev->query($sql, $sql_param);
|
||||||
$query = $this->db_onedev->query($sql, $sql_param);
|
|
||||||
|
|
||||||
|
$tot_count = 0;
|
||||||
$tot_count = 0;
|
$tot_page = 0;
|
||||||
$tot_page = 0;
|
if ($query) {
|
||||||
if ($query) {
|
$tot_count = $query->result_array()[0]["total"];
|
||||||
$tot_count = $query->result_array()[0]["total"];
|
$tot_page = ceil($tot_count/$number_limit);
|
||||||
$tot_page = ceil($tot_count / $number_limit);
|
} else {
|
||||||
} else {
|
$this->sys_error_db("supplier_invoice count", $this->db_onedev);
|
||||||
$this->sys_error_db("supplier_invoice count", $this->db_onedev);
|
exit;
|
||||||
exit;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
$sql = "SELECT supplier_invoice.*,
|
||||||
$sql = "SELECT supplier_invoice.*,
|
SupplierName,
|
||||||
SupplierName,
|
'' M_MouName,
|
||||||
'' M_MouName,
|
0 as totalbill,
|
||||||
0 as totalbill,
|
0 as paid,
|
||||||
0 as paid,
|
0 as unpaid,
|
||||||
0 as unpaid,
|
SupplierInvoiceIsLunas as flaglunas,
|
||||||
SupplierInvoiceIsLunas as flaglunas,
|
0 as SupplierPaymentID,
|
||||||
0 as SupplierPaymentID,
|
'' as SupplierPaymentNumber,
|
||||||
'' as SupplierPaymentNumber,
|
0 as SupplierPaymentAmount,
|
||||||
0 as SupplierPaymentAmount,
|
'' as SupplierPaymentDate,
|
||||||
'' as SupplierPaymentDate,
|
'' as SupplierInvoiceIssueRefNumber,
|
||||||
'' as SupplierInvoiceIssueRefNumber,
|
'' as notes,
|
||||||
'' as notes,
|
'' as tagihans,
|
||||||
'' as tagihans,
|
'N' as isbillterpusat,
|
||||||
'N' as isbillterpusat,
|
DATE_FORMAT(SupplierInvoiceDraftPaymentDate,'%d-%m-%Y') as tanggalbayar,
|
||||||
DATE_FORMAT(SupplierInvoiceDraftPaymentDate,'%d-%m-%Y') as tanggalbayar,
|
DATE_FORMAT(SupplierInvoiceDraftPaymentDate,'%d%m%Y') as tanggalbayartext,
|
||||||
DATE_FORMAT(SupplierInvoiceDraftPaymentDate,'%d%m%Y') as tanggalbayartext,
|
IF(SupplierPaymentID IS NULL,'N','Y') as status_invoice,
|
||||||
IF(SupplierPaymentID IS NULL,'N','Y') as status_invoice,
|
IFNULL(SupplierPaymentIsApproved,'N') as SupplierPaymentIsApproved,
|
||||||
IFNULL(SupplierPaymentIsApproved,'N') as SupplierPaymentIsApproved,
|
IFNULL(SupplierPaymentIsVerif,'N') as SupplierPaymentIsVerif,
|
||||||
IFNULL(SupplierPaymentIsVerif,'N') as SupplierPaymentIsVerif,
|
IFNULL(SupplierPaymentCashierNumber,'') SupplierPaymentCashierNumber
|
||||||
IFNULL(SupplierPaymentCashierNumber,'') SupplierPaymentCashierNumber
|
|
||||||
|
FROM supplier_invoice
|
||||||
FROM supplier_invoice
|
LEFT JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
||||||
LEFT JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
||||||
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
JOIN receive_order_po ON SupplierInvoiceReceiveOrderPoID = ReceiveOrderPoID
|
||||||
JOIN receive_order_po ON SupplierInvoiceReceiveOrderPoID = ReceiveOrderPoID
|
LEFT JOIN supplier_payment ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID AND SupplierPaymentIsActive = 'Y'
|
||||||
LEFT JOIN supplier_payment ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID AND SupplierPaymentIsActive = 'Y'
|
WHERE
|
||||||
WHERE
|
$where
|
||||||
$where
|
GROUP BY SupplierInvoiceID
|
||||||
GROUP BY SupplierInvoiceID
|
ORDER BY SupplierInvoiceID ASC
|
||||||
ORDER BY SupplierInvoiceID ASC
|
limit $number_limit offset $number_offset";
|
||||||
limit $number_limit offset $number_offset";
|
//echo $sql;
|
||||||
//echo $sql;
|
$query = $this->db_onedev->query($sql, $sql_param);
|
||||||
$query = $this->db_onedev->query($sql, $sql_param);
|
$rows = $query->result_array();
|
||||||
$rows = $query->result_array();
|
if($rows){
|
||||||
if ($rows) {
|
foreach($rows as $k => $v){
|
||||||
foreach ($rows as $k => $v) {
|
$s_payment = $this->db_onedev->query("SELECT GROUP_CONCAT(SupplierPaymentNumber SEPARATOR ', ') as SupplierPaymentNumber,
|
||||||
$s_payment = $this->db_onedev->query("SELECT GROUP_CONCAT(SupplierPaymentNumber SEPARATOR ', ') as SupplierPaymentNumber,
|
SUM(IFNULL(SupplierPaymentAmount,0)) as SupplierPaymentAmount,
|
||||||
SUM(IFNULL(SupplierPaymentAmount,0)) as SupplierPaymentAmount,
|
IFNULL(SupplierPaymentID,0) SupplierPaymentID,
|
||||||
IFNULL(SupplierPaymentID,0) SupplierPaymentID,
|
GROUP_CONCAT(DATE_FORMAT(SupplierPaymentDate,'%d-%m-%Y') SEPARATOR ', ') as SupplierPaymentDate
|
||||||
GROUP_CONCAT(DATE_FORMAT(SupplierPaymentDate,'%d-%m-%Y') SEPARATOR ', ') as SupplierPaymentDate
|
FROM supplier_payment
|
||||||
FROM supplier_payment
|
WHERE SupplierPaymentIsActive = 'Y' AND SupplierPaymentSupplierInvoiceID = {$v['SupplierInvoiceID']}")->row();
|
||||||
WHERE SupplierPaymentIsActive = 'Y' AND SupplierPaymentSupplierInvoiceID = {$v['SupplierInvoiceID']}")->row();
|
|
||||||
|
$s_jurnal = $this->db_onedev->query("SELECT SUM(jurnalTxCredit) totalbill
|
||||||
$s_jurnal = $this->db_onedev->query("SELECT SUM(jurnalTxCredit) totalbill
|
FROM supplier_invoice
|
||||||
FROM supplier_invoice
|
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
||||||
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
JOIN jurnal_tx ON jurnalTxJurnalID = jurnalAddOnJurnalID AND jurnalTxCredit <> 0 AND jurnalTxCoaID <> 563
|
||||||
JOIN jurnal_tx ON jurnalTxJurnalID = jurnalAddOnJurnalID AND jurnalTxCredit <> 0 AND jurnalTxCoaID <> 563
|
WHERE SupplierInvoiceID = {$v['SupplierInvoiceID']}
|
||||||
WHERE SupplierInvoiceID = {$v['SupplierInvoiceID']}
|
GROUP BY SupplierInvoiceID")->row();
|
||||||
GROUP BY SupplierInvoiceID")->row();
|
$amount = $s_payment->SupplierPaymentAmount ? $s_payment->SupplierPaymentAmount : "0.00";
|
||||||
$amount = $s_payment->SupplierPaymentAmount ? $s_payment->SupplierPaymentAmount : "0.00";
|
$unpaid = (float)$s_jurnal->totalbill - (float)$amount;
|
||||||
$unpaid = (float)$s_jurnal->totalbill - (float)$amount;
|
$rows[$k]['SupplierPaymentID'] = $s_payment->SupplierPaymentID ? $s_payment->SupplierPaymentID : '0';
|
||||||
$rows[$k]['SupplierPaymentID'] = $s_payment->SupplierPaymentID ? $s_payment->SupplierPaymentID : '0';
|
$rows[$k]['SupplierPaymentNumber'] = $s_payment->SupplierPaymentNumber ? $s_payment->SupplierPaymentNumber : '';
|
||||||
$rows[$k]['SupplierPaymentNumber'] = $s_payment->SupplierPaymentNumber ? $s_payment->SupplierPaymentNumber : '';
|
$rows[$k]['SupplierPaymentAmount'] = $amount;
|
||||||
$rows[$k]['SupplierPaymentAmount'] = $amount;
|
$rows[$k]['SupplierPaymentDate'] = $s_payment->SupplierPaymentDate;
|
||||||
$rows[$k]['SupplierPaymentDate'] = $s_payment->SupplierPaymentDate;
|
$rows[$k]['paid'] = $amount;
|
||||||
$rows[$k]['paid'] = $amount;
|
$rows[$k]['totalbill'] = $s_jurnal->totalbill ? $s_jurnal->totalbill : "0.00";
|
||||||
$rows[$k]['totalbill'] = $s_jurnal->totalbill ? $s_jurnal->totalbill : "0.00";
|
$rows[$k]['unpaid'] = number_format($unpaid, 2, '.', '');
|
||||||
$rows[$k]['unpaid'] = number_format($unpaid, 2, '.', '');
|
|
||||||
|
$rows[$k]['notes'] = $this->add_notes($v['SupplierInvoiceID']);
|
||||||
$rows[$k]['notes'] = $this->add_notes($v['SupplierInvoiceID']);
|
$rows[$k]['tagihans'] = $this->add_tagihans($v['SupplierInvoiceID']);
|
||||||
$rows[$k]['tagihans'] = $this->add_tagihans($v['SupplierInvoiceID']);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$result = array("total" => $tot_page, "records" => $rows, "sql" => $this->db_onedev->last_query());
|
$result = array("total" => $tot_page, "records" => $rows, "sql"=> $this->db_onedev->last_query());
|
||||||
$this->sys_ok($result);
|
$this->sys_ok($result);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* search — unified invoice + downpayment list:
|
|
||||||
* - Only columns the frontend actually reads (no wildcard, no dead aliases)
|
|
||||||
* - UNION ALL merges supplier_invoice and supplier_downpayment
|
|
||||||
* - DP rows enriched via SupplierPaymentSupplierDownpaymentID FK
|
|
||||||
* - All queries use PDO parameterised placeholders
|
|
||||||
*/
|
|
||||||
public function search()
|
|
||||||
{
|
|
||||||
if (! $this->isLogin) {
|
|
||||||
$this->sys_error("Invalid Token");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$prm = $this->sys_input;
|
|
||||||
$supplier = $prm["supplier"];
|
|
||||||
$search = $prm["search"];
|
|
||||||
$status = $prm["status"];
|
|
||||||
$startdate = $prm["startdate"];
|
|
||||||
$enddate = $prm["enddate"];
|
|
||||||
$regionalid = $this->sys_user['S_RegionalID'];
|
|
||||||
|
|
||||||
$number_limit = 10;
|
|
||||||
$number_offset = ((int)$prm['current_page'] - 1) * $number_limit;
|
|
||||||
|
|
||||||
// ── INVOICE WHERE ──────────────────────────────────────────
|
|
||||||
$inv_where = " SupplierInvoiceIsActive = 'Y'
|
|
||||||
AND SupplierInvoiceStatus = 'Approved'
|
|
||||||
AND SupplierInvoiceGrandTotal > 0
|
|
||||||
AND SupplierInvoiceIsInstallment = 'N'
|
|
||||||
AND IF(SupplierPaymentID IS NULL,'N','Y') = ?
|
|
||||||
AND SupplierInvoiceNumber LIKE ?
|
|
||||||
AND SupplierName LIKE ?
|
|
||||||
AND ReceiveOrderPoS_RegionalID = ?
|
|
||||||
AND SupplierInvoiceDraftPaymentDate BETWEEN ? AND ? ";
|
|
||||||
|
|
||||||
$inv_params = [
|
|
||||||
$status,
|
|
||||||
'%' . $search . '%',
|
|
||||||
'%' . $supplier . '%',
|
|
||||||
$regionalid,
|
|
||||||
$startdate,
|
|
||||||
$enddate,
|
|
||||||
];
|
|
||||||
|
|
||||||
// ── DOWNPAYMENT WHERE ──────────────────────────────────────
|
|
||||||
$dp_where = " SupplierDownpaymentIsActive = 'Y'
|
|
||||||
AND IF(SupplierDownpaymentStatus = 'Paid','Y','N') = ?
|
|
||||||
AND PurchaseOrderNumber LIKE ?
|
|
||||||
AND SupplierName LIKE ?
|
|
||||||
AND PurchaseOrderS_RegionalID = ?
|
|
||||||
AND SupplierDownpaymentDueDate BETWEEN ? AND ? ";
|
|
||||||
|
|
||||||
$dp_params = [
|
|
||||||
$status,
|
|
||||||
'%' . $search . '%',
|
|
||||||
'%' . $supplier . '%',
|
|
||||||
$regionalid,
|
|
||||||
$startdate,
|
|
||||||
$enddate,
|
|
||||||
];
|
|
||||||
|
|
||||||
// ── INSTALLMENT WHERE ───────────────────────────────────
|
|
||||||
$inst_where = " inst.SupplierInstallmentIsActive = 'Y'
|
|
||||||
AND IF(sp.SupplierPaymentID IS NULL,'N','Y') = ?
|
|
||||||
AND CONCAT('INST-', si.SupplierInvoiceNumber) LIKE ?
|
|
||||||
AND sup.SupplierName LIKE ?
|
|
||||||
AND rop.ReceiveOrderPoS_RegionalID = ?
|
|
||||||
AND inst.SupplierInstallmentDueDate BETWEEN ? AND ? ";
|
|
||||||
|
|
||||||
$inst_params = [
|
|
||||||
$status,
|
|
||||||
'%' . $search . '%',
|
|
||||||
'%' . $supplier . '%',
|
|
||||||
$regionalid,
|
|
||||||
$startdate,
|
|
||||||
$enddate,
|
|
||||||
];
|
|
||||||
|
|
||||||
// ── COUNT query — UNION of all three sources ────────────
|
|
||||||
$sql_count = "SELECT SUM(cnt) as total FROM (
|
|
||||||
SELECT count(*) as cnt
|
|
||||||
FROM supplier_invoice
|
|
||||||
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
|
||||||
LEFT JOIN supplier_payment
|
|
||||||
ON SupplierInvoiceID = SupplierPaymentSupplierInvoiceID
|
|
||||||
AND SupplierPaymentIsActive = 'Y'
|
|
||||||
LEFT JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
|
||||||
JOIN receive_order_po ON SupplierInvoiceReceiveOrderPoID = ReceiveOrderPoID
|
|
||||||
WHERE $inv_where
|
|
||||||
|
|
||||||
UNION ALL
|
|
||||||
|
|
||||||
SELECT count(*) as cnt
|
|
||||||
FROM supplier_downpayment
|
|
||||||
JOIN purchase_order ON PurchaseOrderID = SupplierDownpaymentPurchasOrderID
|
|
||||||
JOIN supplier ON SupplierID = SupplierDownpaymentSupplierID
|
|
||||||
WHERE $dp_where
|
|
||||||
|
|
||||||
UNION ALL
|
|
||||||
|
|
||||||
SELECT count(*) as cnt
|
|
||||||
FROM supplier_installment inst
|
|
||||||
LEFT JOIN supplier_payment sp
|
|
||||||
ON sp.SupplierPaymentSupplierInstallmentID = inst.SupplierInstallmentID
|
|
||||||
AND sp.SupplierPaymentIsActive = 'Y'
|
|
||||||
JOIN supplier_invoice si
|
|
||||||
ON si.SupplierInvoiceID = inst.SupplierInstallmentSupplierInvoiceID
|
|
||||||
JOIN receive_order_po rop
|
|
||||||
ON rop.ReceiveOrderPoID = si.SupplierInvoiceReceiveOrderPoID
|
|
||||||
JOIN supplier sup
|
|
||||||
ON sup.SupplierID = inst.SupplierInstallmentSupplierID
|
|
||||||
WHERE $inst_where
|
|
||||||
) AS combined";
|
|
||||||
|
|
||||||
$count_params = array_merge($inv_params, $dp_params, $inst_params);
|
|
||||||
$query = $this->db_onedev->query($sql_count, $count_params);
|
|
||||||
|
|
||||||
$tot_count = 0;
|
|
||||||
$tot_page = 0;
|
|
||||||
if ($query) {
|
|
||||||
$tot_count = $query->result_array()[0]["total"];
|
|
||||||
$tot_page = ceil($tot_count / $number_limit);
|
|
||||||
} else {
|
|
||||||
$this->sys_error_db("payment instructions count", $this->db_onedev);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── DATA query — UNION with identical columns ──────────────
|
|
||||||
$sql_data = "
|
|
||||||
SELECT * FROM (
|
|
||||||
SELECT
|
|
||||||
SupplierInvoiceID,
|
|
||||||
0 as DownpaymentID,
|
|
||||||
0 as InstallmentID,
|
|
||||||
SupplierInvoiceNumber,
|
|
||||||
SupplierInvoiceDraftPaymentDate,
|
|
||||||
SupplierInvoiceIsLunas as flaglunas,
|
|
||||||
SupplierName,
|
|
||||||
DATE_FORMAT(SupplierInvoiceDraftPaymentDate,'%d-%m-%Y') as tanggalbayar,
|
|
||||||
IFNULL(SupplierPaymentIsApproved,'N') as SupplierPaymentIsApproved,
|
|
||||||
IFNULL(SupplierPaymentCashierNumber,'') as SupplierPaymentCashierNumber,
|
|
||||||
0 as totalbill,
|
|
||||||
0 as paid,
|
|
||||||
0 as unpaid,
|
|
||||||
0 as SupplierPaymentID,
|
|
||||||
'' as SupplierPaymentNumber,
|
|
||||||
0 as SupplierPaymentAmount,
|
|
||||||
'' as SupplierPaymentDate,
|
|
||||||
'' as notes,
|
|
||||||
'' as tagihans,
|
|
||||||
0 as parent_invoice_id,
|
|
||||||
'INVOICE' as type
|
|
||||||
FROM supplier_invoice
|
|
||||||
LEFT JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
|
||||||
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
|
||||||
JOIN receive_order_po ON SupplierInvoiceReceiveOrderPoID = ReceiveOrderPoID
|
|
||||||
LEFT JOIN supplier_payment
|
|
||||||
ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID
|
|
||||||
AND SupplierPaymentIsActive = 'Y'
|
|
||||||
WHERE $inv_where
|
|
||||||
GROUP BY SupplierInvoiceID
|
|
||||||
|
|
||||||
UNION ALL
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
0 as SupplierInvoiceID,
|
|
||||||
SupplierDownpaymentID as DownpaymentID,
|
|
||||||
0 as InstallmentID,
|
|
||||||
CONCAT('DP-', PurchaseOrderNumber) as SupplierInvoiceNumber,
|
|
||||||
SupplierDownpaymentDueDate as SupplierInvoiceDraftPaymentDate,
|
|
||||||
SupplierDownpaymentIsLunas as flaglunas,
|
|
||||||
SupplierName,
|
|
||||||
DATE_FORMAT(SupplierDownpaymentDueDate,'%d-%m-%Y') as tanggalbayar,
|
|
||||||
IFNULL(SupplierPaymentIsApproved,'N') as SupplierPaymentIsApproved,
|
|
||||||
IFNULL(SupplierPaymentCashierNumber,'') as SupplierPaymentCashierNumber,
|
|
||||||
SupplierDownpaymentAmount as totalbill,
|
|
||||||
CASE WHEN SupplierDownpaymentStatus = 'Paid'
|
|
||||||
THEN SupplierDownpaymentAmount
|
|
||||||
ELSE 0 END as paid,
|
|
||||||
CASE WHEN SupplierDownpaymentStatus = 'Paid'
|
|
||||||
THEN 0
|
|
||||||
ELSE SupplierDownpaymentAmount END as unpaid,
|
|
||||||
0 as SupplierPaymentID,
|
|
||||||
'' as SupplierPaymentNumber,
|
|
||||||
0 as SupplierPaymentAmount,
|
|
||||||
'' as SupplierPaymentDate,
|
|
||||||
'' as notes,
|
|
||||||
'' as tagihans,
|
|
||||||
0 as parent_invoice_id,
|
|
||||||
'DP' as type
|
|
||||||
FROM supplier_downpayment
|
|
||||||
JOIN purchase_order ON PurchaseOrderID = SupplierDownpaymentPurchasOrderID
|
|
||||||
JOIN supplier ON SupplierID = SupplierDownpaymentSupplierID
|
|
||||||
LEFT JOIN supplier_payment
|
|
||||||
ON SupplierPaymentSupplierDownpaymentID = SupplierDownpaymentID
|
|
||||||
AND SupplierPaymentIsActive = 'Y'
|
|
||||||
WHERE $dp_where
|
|
||||||
|
|
||||||
UNION ALL
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
0 as SupplierInvoiceID,
|
|
||||||
0 as DownpaymentID,
|
|
||||||
inst.SupplierInstallmentID as InstallmentID,
|
|
||||||
CONCAT('INST-', si.SupplierInvoiceNumber) as SupplierInvoiceNumber,
|
|
||||||
inst.SupplierInstallmentDueDate as SupplierInvoiceDraftPaymentDate,
|
|
||||||
inst.SupplierInstallmentIsLunas as flaglunas,
|
|
||||||
sup.SupplierName,
|
|
||||||
DATE_FORMAT(inst.SupplierInstallmentDueDate,'%d-%m-%Y') as tanggalbayar,
|
|
||||||
IFNULL(sp.SupplierPaymentIsApproved,'N') as SupplierPaymentIsApproved,
|
|
||||||
IFNULL(sp.SupplierPaymentCashierNumber,'') as SupplierPaymentCashierNumber,
|
|
||||||
inst.SupplierInstallmentAmount as totalbill,
|
|
||||||
CASE WHEN inst.SupplierInstallmentStatus = 'Paid'
|
|
||||||
THEN inst.SupplierInstallmentAmount
|
|
||||||
ELSE 0 END as paid,
|
|
||||||
CASE WHEN inst.SupplierInstallmentStatus = 'Paid'
|
|
||||||
THEN 0
|
|
||||||
ELSE inst.SupplierInstallmentAmount END as unpaid,
|
|
||||||
0 as SupplierPaymentID,
|
|
||||||
'' as SupplierPaymentNumber,
|
|
||||||
0 as SupplierPaymentAmount,
|
|
||||||
'' as SupplierPaymentDate,
|
|
||||||
'' as notes,
|
|
||||||
'' as tagihans,
|
|
||||||
si.SupplierInvoiceID as parent_invoice_id,
|
|
||||||
'INSTALLMENT' as type
|
|
||||||
FROM supplier_installment inst
|
|
||||||
LEFT JOIN supplier_payment sp
|
|
||||||
ON sp.SupplierPaymentSupplierInstallmentID = inst.SupplierInstallmentID
|
|
||||||
AND sp.SupplierPaymentIsActive = 'Y'
|
|
||||||
JOIN supplier_invoice si
|
|
||||||
ON si.SupplierInvoiceID = inst.SupplierInstallmentSupplierInvoiceID
|
|
||||||
JOIN receive_order_po rop
|
|
||||||
ON rop.ReceiveOrderPoID = si.SupplierInvoiceReceiveOrderPoID
|
|
||||||
JOIN supplier sup
|
|
||||||
ON sup.SupplierID = inst.SupplierInstallmentSupplierID
|
|
||||||
WHERE $inst_where
|
|
||||||
) AS combined
|
|
||||||
ORDER BY SupplierInvoiceID ASC
|
|
||||||
LIMIT ? OFFSET ?";
|
|
||||||
|
|
||||||
$data_params = array_merge($inv_params, $dp_params, $inst_params, [$number_limit, $number_offset]);
|
|
||||||
$query = $this->db_onedev->query($sql_data, $data_params);
|
|
||||||
if (!$query) {
|
|
||||||
$this->sys_error_db("payment instructions data", $this->db_onedev);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
$rows = $query->result_array();
|
|
||||||
|
|
||||||
// ── ENRICH — per-row sub-queries ───────────────────────────
|
|
||||||
if ($rows) {
|
|
||||||
foreach ($rows as $k => $v) {
|
|
||||||
|
|
||||||
// ── Downpayment branch ──────────────────────────
|
|
||||||
if ($v['type'] === 'DP') {
|
|
||||||
$dp_id = $v['DownpaymentID'];
|
|
||||||
|
|
||||||
$s_payment = $this->db_onedev->query("
|
|
||||||
SELECT
|
|
||||||
GROUP_CONCAT(SupplierPaymentNumber SEPARATOR ', ') as SupplierPaymentNumber,
|
|
||||||
SUM(IFNULL(SupplierPaymentAmount,0)) as SupplierPaymentAmount,
|
|
||||||
IFNULL(SupplierPaymentID,0) as SupplierPaymentID,
|
|
||||||
GROUP_CONCAT(
|
|
||||||
DATE_FORMAT(SupplierPaymentDate,'%d-%m-%Y')
|
|
||||||
SEPARATOR ', '
|
|
||||||
) as SupplierPaymentDate
|
|
||||||
FROM supplier_payment
|
|
||||||
WHERE SupplierPaymentIsActive = 'Y'
|
|
||||||
AND SupplierPaymentSupplierDownpaymentID = ?",
|
|
||||||
[$dp_id]
|
|
||||||
)->row();
|
|
||||||
|
|
||||||
$amount = $s_payment->SupplierPaymentAmount
|
|
||||||
? $s_payment->SupplierPaymentAmount
|
|
||||||
: "0.00";
|
|
||||||
$rows[$k]['SupplierPaymentID'] = $s_payment->SupplierPaymentID
|
|
||||||
? $s_payment->SupplierPaymentID
|
|
||||||
: '0';
|
|
||||||
$rows[$k]['SupplierPaymentNumber'] = $s_payment->SupplierPaymentNumber
|
|
||||||
? $s_payment->SupplierPaymentNumber
|
|
||||||
: '';
|
|
||||||
$rows[$k]['SupplierPaymentAmount'] = $amount;
|
|
||||||
$rows[$k]['SupplierPaymentDate'] = $s_payment->SupplierPaymentDate;
|
|
||||||
$rows[$k]['paid'] = $amount;
|
|
||||||
$rows[$k]['notes'] = $this->add_notes_downpayment($dp_id);
|
|
||||||
$rows[$k]['tagihans'] = [];
|
|
||||||
// totalbill, unpaid already correct from UNION CASE
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Installment branch ─────────────────────────
|
|
||||||
if ($v['type'] === 'INSTALLMENT') {
|
|
||||||
$inst_id = $v['InstallmentID'];
|
|
||||||
$parent_invoice_id = $v['parent_invoice_id'];
|
|
||||||
|
|
||||||
$s_payment = $this->db_onedev->query("
|
|
||||||
SELECT
|
|
||||||
GROUP_CONCAT(SupplierPaymentNumber SEPARATOR ', ') as SupplierPaymentNumber,
|
|
||||||
SUM(IFNULL(SupplierPaymentAmount,0)) as SupplierPaymentAmount,
|
|
||||||
IFNULL(SupplierPaymentID,0) as SupplierPaymentID,
|
|
||||||
GROUP_CONCAT(
|
|
||||||
DATE_FORMAT(SupplierPaymentDate,'%d-%m-%Y')
|
|
||||||
SEPARATOR ', '
|
|
||||||
) as SupplierPaymentDate
|
|
||||||
FROM supplier_payment
|
|
||||||
WHERE SupplierPaymentIsActive = 'Y'
|
|
||||||
AND SupplierPaymentSupplierInstallmentID = ?",
|
|
||||||
[$inst_id]
|
|
||||||
)->row();
|
|
||||||
|
|
||||||
$amount = $s_payment->SupplierPaymentAmount
|
|
||||||
? $s_payment->SupplierPaymentAmount
|
|
||||||
: "0.00";
|
|
||||||
$rows[$k]['SupplierPaymentID'] = $s_payment->SupplierPaymentID
|
|
||||||
? $s_payment->SupplierPaymentID
|
|
||||||
: '0';
|
|
||||||
$rows[$k]['SupplierPaymentNumber'] = $s_payment->SupplierPaymentNumber
|
|
||||||
? $s_payment->SupplierPaymentNumber
|
|
||||||
: '';
|
|
||||||
$rows[$k]['SupplierPaymentAmount'] = $amount;
|
|
||||||
$rows[$k]['SupplierPaymentDate'] = $s_payment->SupplierPaymentDate;
|
|
||||||
$rows[$k]['paid'] = $amount;
|
|
||||||
$rows[$k]['notes'] = $this->add_notes_installment($inst_id);
|
|
||||||
$rows[$k]['tagihans'] = $this->add_tagihans($parent_invoice_id);
|
|
||||||
// totalbill, unpaid already correct from UNION CASE
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Invoice branch ───────────────────────────────
|
|
||||||
$inv_id = $v['SupplierInvoiceID'];
|
|
||||||
|
|
||||||
$s_payment = $this->db_onedev->query("
|
|
||||||
SELECT
|
|
||||||
GROUP_CONCAT(SupplierPaymentNumber SEPARATOR ', ') as SupplierPaymentNumber,
|
|
||||||
SUM(IFNULL(SupplierPaymentAmount,0)) as SupplierPaymentAmount,
|
|
||||||
IFNULL(SupplierPaymentID,0) as SupplierPaymentID,
|
|
||||||
GROUP_CONCAT(
|
|
||||||
DATE_FORMAT(SupplierPaymentDate,'%d-%m-%Y')
|
|
||||||
SEPARATOR ', '
|
|
||||||
) as SupplierPaymentDate
|
|
||||||
FROM supplier_payment
|
|
||||||
WHERE SupplierPaymentIsActive = 'Y'
|
|
||||||
AND SupplierPaymentSupplierInvoiceID = ?",
|
|
||||||
[$inv_id]
|
|
||||||
)->row();
|
|
||||||
|
|
||||||
$s_jurnal = $this->db_onedev->query("
|
|
||||||
SELECT SUM(jurnalTxCredit) totalbill
|
|
||||||
FROM supplier_invoice
|
|
||||||
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
|
||||||
JOIN jurnal_tx
|
|
||||||
ON jurnalTxJurnalID = jurnalAddOnJurnalID
|
|
||||||
AND jurnalTxCredit <> 0
|
|
||||||
AND jurnalTxCoaID <> 563
|
|
||||||
WHERE SupplierInvoiceID = ?
|
|
||||||
GROUP BY SupplierInvoiceID",
|
|
||||||
[$inv_id]
|
|
||||||
)->row();
|
|
||||||
|
|
||||||
$amount = $s_payment->SupplierPaymentAmount
|
|
||||||
? $s_payment->SupplierPaymentAmount
|
|
||||||
: "0.00";
|
|
||||||
$unpaid = (float)$s_jurnal->totalbill - (float)$amount;
|
|
||||||
|
|
||||||
$rows[$k]['SupplierPaymentID'] = $s_payment->SupplierPaymentID
|
|
||||||
? $s_payment->SupplierPaymentID
|
|
||||||
: '0';
|
|
||||||
$rows[$k]['SupplierPaymentNumber'] = $s_payment->SupplierPaymentNumber
|
|
||||||
? $s_payment->SupplierPaymentNumber
|
|
||||||
: '';
|
|
||||||
$rows[$k]['SupplierPaymentAmount'] = $amount;
|
|
||||||
$rows[$k]['SupplierPaymentDate'] = $s_payment->SupplierPaymentDate;
|
|
||||||
$rows[$k]['paid'] = $amount;
|
|
||||||
$rows[$k]['totalbill'] = $s_jurnal->totalbill
|
|
||||||
? $s_jurnal->totalbill
|
|
||||||
: "0.00";
|
|
||||||
$rows[$k]['unpaid'] = number_format($unpaid, 2, '.', '');
|
|
||||||
|
|
||||||
$rows[$k]['notes'] = $this->add_notes($inv_id);
|
|
||||||
$rows[$k]['tagihans'] = $this->add_tagihans($inv_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = array("total" => $tot_page, "records" => $rows);
|
|
||||||
$this->sys_ok($result);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,532 +0,0 @@
|
|||||||
<?php
|
|
||||||
defined('BASEPATH') or exit('No direct script access allowed');
|
|
||||||
|
|
||||||
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
|
||||||
// =============================================================================
|
|
||||||
class FakturFpdf extends FPDF
|
|
||||||
{
|
|
||||||
public $printUsername = '-';
|
|
||||||
public $printDate = '';
|
|
||||||
|
|
||||||
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
|
||||||
{
|
|
||||||
parent::__construct($orientation, $unit, $size);
|
|
||||||
// Daftarkan Arial Narrow
|
|
||||||
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
|
||||||
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Footer()
|
|
||||||
{
|
|
||||||
$pageW = $this->GetPageWidth() - 30; // margin 15+15
|
|
||||||
|
|
||||||
// -- Posisi: 20mm dari bawah halaman ----------------------------------
|
|
||||||
$this->SetY(-20);
|
|
||||||
|
|
||||||
// -- Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ---------------
|
|
||||||
$colSide = ($pageW - 40) / 2;
|
|
||||||
$colCenter = 40;
|
|
||||||
|
|
||||||
$this->SetFont('Arial_Narrow', '', 7);
|
|
||||||
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
|
||||||
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
|
||||||
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
|
||||||
|
|
||||||
// -- Baris 2: Tgl Print (kiri) ------------------------------------------
|
|
||||||
$this->SetFont('Arial_Narrow', '', 7);
|
|
||||||
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
|
||||||
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Controller
|
|
||||||
// =============================================================================
|
|
||||||
class Rpt_faktur extends MY_Controller
|
|
||||||
{
|
|
||||||
// -- Properti bersama antar fungsi PDF -------------------------------------
|
|
||||||
/** @var FakturFpdf */
|
|
||||||
private $_pdf;
|
|
||||||
private $_pageW;
|
|
||||||
private $_header_data;
|
|
||||||
private $_username;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
echo "Faktur (Supplier Invoice) Report API";
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// ENDPOINT: pdf
|
|
||||||
// GET/POST: id (SupplierInvoiceID), username (opsional)
|
|
||||||
// =========================================================================
|
|
||||||
public function pdf()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$id = intval($this->input->get_post('id'));
|
|
||||||
$username = trim($this->input->get_post('username') ?? '');
|
|
||||||
|
|
||||||
if ($id <= 0) {
|
|
||||||
$this->sys_error("ID tidak valid");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Ambil data header & detail dari DB ----------------------------
|
|
||||||
$header = $this->_get_header($id);
|
|
||||||
$details = $this->_get_detail($id);
|
|
||||||
|
|
||||||
// -- Inisialisasi FPDF custom --------------------------------------
|
|
||||||
$this->_pdf = new FakturFpdf('P', 'mm', 'A4');
|
|
||||||
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
|
||||||
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
|
||||||
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
|
||||||
$this->_header_data = $header;
|
|
||||||
$this->_username = $this->_pdf->printUsername;
|
|
||||||
|
|
||||||
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
|
||||||
$this->_pdf->SetMargins(15, 15, 15);
|
|
||||||
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
|
||||||
$this->_pdf->AddPage();
|
|
||||||
|
|
||||||
// -- Susun isi halaman ---------------------------------------------
|
|
||||||
$this->_pdf_header();
|
|
||||||
$this->_pdf_data($details);
|
|
||||||
$this->_pdf_summary();
|
|
||||||
$this->_pdf_terms();
|
|
||||||
|
|
||||||
// -- Output --------------------------------------------------------
|
|
||||||
$filename = 'INV_' . str_replace('/', '-', $header['SupplierInvoiceNumber']) . '.pdf';
|
|
||||||
header('Content-Type: application/pdf');
|
|
||||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
|
||||||
header('Cache-Control: private, max-age=0, must-revalidate');
|
|
||||||
header('Pragma: public');
|
|
||||||
echo $this->_pdf->Output('S');
|
|
||||||
} catch (Exception $exc) {
|
|
||||||
$this->sys_error($exc->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// DATABASE: Ambil data header
|
|
||||||
// =========================================================================
|
|
||||||
private function _get_header($id)
|
|
||||||
{
|
|
||||||
$sql = "
|
|
||||||
SELECT
|
|
||||||
si.*,
|
|
||||||
sup.SupplierName,
|
|
||||||
sup.SupplierAddress,
|
|
||||||
sup.SupplierPhone,
|
|
||||||
IFNULL(uCr.M_UserUsername, '') AS CreatedByName,
|
|
||||||
IFNULL(uVe.M_UserUsername, '') AS VerifiedByName,
|
|
||||||
IFNULL(uAp.M_UserUsername, '') AS ApprovedByName,
|
|
||||||
IFNULL(uPa.M_UserUsername, '') AS PaidByName,
|
|
||||||
IFNULL(uRe.M_UserUsername, '') AS ReceivedByName
|
|
||||||
FROM supplier_invoice si
|
|
||||||
LEFT JOIN supplier sup ON sup.SupplierID = si.SupplierInvoiceSupplierID
|
|
||||||
AND sup.SupplierIsActive = 'Y'
|
|
||||||
LEFT JOIN m_user uCr ON uCr.M_UserID = si.SupplierInvoiceCreatedUserID
|
|
||||||
LEFT JOIN m_user uVe ON uVe.M_UserID = si.SupplierInvoiceVerifiedUserID
|
|
||||||
LEFT JOIN m_user uAp ON uAp.M_UserID = si.SupplierInvoiceApprovedUserID
|
|
||||||
LEFT JOIN m_user uPa ON uPa.M_UserID = si.SupplierInvoicePaidUserID
|
|
||||||
LEFT JOIN m_user uRe ON uRe.M_UserID = si.SupplierInvoiceReceivedBy
|
|
||||||
WHERE si.SupplierInvoiceID = ?
|
|
||||||
AND si.SupplierInvoiceIsActive = 'Y'
|
|
||||||
LIMIT 1
|
|
||||||
";
|
|
||||||
$qry = $this->db->query($sql, array($id));
|
|
||||||
if (!$qry || $qry->num_rows() === 0) {
|
|
||||||
$this->sys_error("Data Faktur tidak ditemukan");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
return $qry->row_array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// DATABASE: Ambil data detail
|
|
||||||
// =========================================================================
|
|
||||||
private function _get_detail($id)
|
|
||||||
{
|
|
||||||
$sql = "
|
|
||||||
SELECT
|
|
||||||
sid.*,
|
|
||||||
i.M_ItemCode,
|
|
||||||
i.M_ItemDesc,
|
|
||||||
iu.ItemUnitName,
|
|
||||||
iu.ItemUnitCode
|
|
||||||
FROM supplier_invoice_detail sid
|
|
||||||
LEFT JOIN m_item i ON i.M_ItemID = sid.SupplierInvoiceDetailItemID
|
|
||||||
LEFT JOIN itemunit iu ON iu.ItemUnitID = sid.SupplierInvoiceDetailItemUnitID
|
|
||||||
WHERE sid.SupplierInvoiceDetailSupplierInvoiceID = ?
|
|
||||||
AND sid.SupplierInvoiceDetailIsActive = 'Y'
|
|
||||||
ORDER BY sid.SupplierInvoiceDetailID ASC
|
|
||||||
";
|
|
||||||
$qry = $this->db->query($sql, array($id));
|
|
||||||
return $qry ? $qry->result_array() : array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_header()
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
$header = $this->_header_data;
|
|
||||||
|
|
||||||
// -- Judul utama --------------------------------------------------------
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
|
||||||
$pdf->Cell($pageW, 8, 'FAKTUR (SUPPLIER INVOICE)', 0, 1, 'L');
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
$pdf->SetLineWidth(0.5);
|
|
||||||
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
|
||||||
$pdf->Ln(2);
|
|
||||||
|
|
||||||
$startY = $pdf->GetY();
|
|
||||||
$halfW = $pageW / 2;
|
|
||||||
$lblW = 32;
|
|
||||||
$valW = $halfW - $lblW - 4;
|
|
||||||
|
|
||||||
// -- Kolom Kiri -----------------------------------------------------------
|
|
||||||
$pdf->SetY($startY);
|
|
||||||
|
|
||||||
$leftItems = array(
|
|
||||||
array('Nomor Faktur', $header['SupplierInvoiceNumber'], true),
|
|
||||||
array('Tgl Faktur', $this->_fmt_date($header['SupplierInvoiceDate']), false),
|
|
||||||
array('Tgl Jatuh Tempo', $this->_fmt_date($header['SupplierInvoiceDueDate']), false),
|
|
||||||
array('Status', $header['SupplierInvoiceStatus'], false),
|
|
||||||
array('Supplier', $header['SupplierName'] ?: '-', false),
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($leftItems as $item) {
|
|
||||||
$pdf->SetX(15);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
if ($item[2]) {
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
} else {
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
}
|
|
||||||
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alamat Supplier (MultiCell)
|
|
||||||
if (!empty($header['SupplierAddress'])) {
|
|
||||||
$pdf->SetX(15);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, 'Alamat Supplier', 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
$pdf->MultiCell($valW, 4, $header['SupplierAddress'], 0, 'L');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keterangan
|
|
||||||
if (!empty($header['SupplierInvoiceNote'])) {
|
|
||||||
$pdf->SetX(15);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
$pdf->MultiCell($valW, 4, $header['SupplierInvoiceNote'], 0, 'L');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
}
|
|
||||||
$leftY = $pdf->GetY();
|
|
||||||
|
|
||||||
// -- Kolom Kanan ----------------------------------------------------------
|
|
||||||
$pdf->SetY($startY);
|
|
||||||
$rightX = 15 + $halfW;
|
|
||||||
|
|
||||||
// No. Supplier Invoice & tgl (jika ada)
|
|
||||||
$rightItems = array();
|
|
||||||
if (!empty($header['SupplierInvoiceSupplierInvoiceNumber'])) {
|
|
||||||
$rightItems[] = array('No. Inv. Supplier', $header['SupplierInvoiceSupplierInvoiceNumber']);
|
|
||||||
$rightItems[] = array('Tgl Inv. Supplier', $this->_fmt_date($header['SupplierInvoiceSupplierInvoiceDate']));
|
|
||||||
}
|
|
||||||
$rightItems[] = array('No. Delivery Order', $header['SupplierInvoiceDeliveryOrderNumber'] ?: '-');
|
|
||||||
$rightItems[] = array('Dibuat Oleh', $header['CreatedByName'] ?: '-');
|
|
||||||
$rightItems[] = array('Dibuat Tgl', $this->_fmt_datetime($header['SupplierInvoiceCreated']));
|
|
||||||
|
|
||||||
if ($header['SupplierInvoiceStatus'] === 'Verified' || in_array($header['SupplierInvoiceStatus'], ['Approved', 'Scheduled', 'Paid', 'Partially Paid'])) {
|
|
||||||
if (!empty($header['SupplierInvoiceVerifiedDate'])) {
|
|
||||||
$rightItems[] = array('Diverifikasi Oleh', $header['VerifiedByName'] ?: '-');
|
|
||||||
$rightItems[] = array('Tgl Verifikasi', $this->_fmt_datetime($header['SupplierInvoiceVerifiedDate']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array($header['SupplierInvoiceStatus'], ['Approved', 'Scheduled', 'Paid', 'Partially Paid'])) {
|
|
||||||
if (!empty($header['SupplierInvoiceApprovedDate'])) {
|
|
||||||
$rightItems[] = array('Disetujui Oleh', $header['ApprovedByName'] ?: '-');
|
|
||||||
$rightItems[] = array('Tgl Disetujui', $this->_fmt_datetime($header['SupplierInvoiceApprovedDate']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($header['SupplierInvoiceStatus'] === 'Paid' || $header['SupplierInvoiceStatus'] === 'Partially Paid') {
|
|
||||||
if (!empty($header['SupplierInvoicePaidDate'])) {
|
|
||||||
$rightItems[] = array('Dibayar Oleh', $header['PaidByName'] ?: '-');
|
|
||||||
$rightItems[] = array('Tgl Dibayar', $this->_fmt_datetime($header['SupplierInvoicePaidDate']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tgl Terima & Penerima (jika ada)
|
|
||||||
if (!empty($header['SupplierInvoiceReceiveDate'])) {
|
|
||||||
$rightItems[] = array('Tgl Terima', $this->_fmt_date($header['SupplierInvoiceReceiveDate']));
|
|
||||||
$rightItems[] = array('Diterima Oleh', $header['ReceivedByName'] ?: '-');
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($rightItems as $item) {
|
|
||||||
$pdf->SetX($rightX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
|
||||||
}
|
|
||||||
|
|
||||||
$rightY = $pdf->GetY();
|
|
||||||
|
|
||||||
// Posisikan Y ke yang paling bawah + margin
|
|
||||||
$pdf->SetY(max($leftY, $rightY) + 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Data — Tabel detail item
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_data($details)
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
|
|
||||||
// -- Definisi kolom: [label, lebar, align] -------------------------------
|
|
||||||
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
|
||||||
// 8 + 62 + 15 + 20 + 25 + 25 + 25 = 180
|
|
||||||
$cols = array(
|
|
||||||
array('No', 8, 'C'),
|
|
||||||
array('Deskripsi', 62, 'L'),
|
|
||||||
array('Unit', 15, 'C'),
|
|
||||||
array('Qty', 20, 'R'),
|
|
||||||
array('Harga Satuan', 25, 'R'),
|
|
||||||
array('Diskon', 25, 'R'),
|
|
||||||
array('Total', 25, 'R'),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Header kolom
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 7);
|
|
||||||
$pdf->SetFillColor(220, 220, 220);
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
foreach ($cols as $c) {
|
|
||||||
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
|
||||||
}
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
// Baris data
|
|
||||||
$pdf->SetLineWidth(0.2);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 7.5);
|
|
||||||
$pdf->SetFillColor(255, 255, 255);
|
|
||||||
$no = 1;
|
|
||||||
|
|
||||||
foreach ($details as $d) {
|
|
||||||
$qty = floatval($d['SupplierInvoiceDetailQty'] ?? 0);
|
|
||||||
$price = floatval($d['SupplierInvoiceDetailPrice'] ?? 0);
|
|
||||||
$discAmount = floatval($d['SupplierInvoiceDetailDiscountAmount'] ?? 0);
|
|
||||||
$total = floatval($d['SupplierInvoiceDetailTotal'] ?? 0);
|
|
||||||
$desc = $d['SupplierInvoiceDetailDescription'] ?: ($d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'));
|
|
||||||
|
|
||||||
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[1][1], 6, $desc, 1, 0, 'L');
|
|
||||||
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'),1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($qty), 1, 0, 'R');
|
|
||||||
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($price), 1, 0, 'R');
|
|
||||||
$pdf->Cell($cols[5][1], 6, $discAmount > 0 ? $this->_fmt_rp($discAmount) : '-', 1, 0, 'R');
|
|
||||||
$pdf->Cell($cols[6][1], 6, $this->_fmt_rp($total), 1, 0, 'R');
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
$no++;
|
|
||||||
}
|
|
||||||
|
|
||||||
$pdf->Ln(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Ringkasan Nilai (SubTotal, Pajak, Grand Total)
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_summary()
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
$header = $this->_header_data;
|
|
||||||
|
|
||||||
// -- Ringkasan nilai (rata kanan) ----------------------------------------
|
|
||||||
$cW1 = 50;
|
|
||||||
$cW2 = 40;
|
|
||||||
$offsetX = 15 + $this->_pageW - $cW1 - $cW2;
|
|
||||||
|
|
||||||
// Garis pemisah
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->Line(15 + $pageW - $cW1 - $cW2 - 4, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
|
||||||
$pdf->Ln(2);
|
|
||||||
|
|
||||||
$items = array();
|
|
||||||
|
|
||||||
// Sub Total
|
|
||||||
$items[] = array('Sub Total', $this->_fmt_rp($header['SupplierInvoiceSubTotal']));
|
|
||||||
|
|
||||||
// Diskon (jika ada)
|
|
||||||
$discPct = floatval($header['SupplierInvoiceDiscountPercent'] ?? 0);
|
|
||||||
$discAmt = floatval($header['SupplierInvoiceDiscountAmount'] ?? 0);
|
|
||||||
if ($discPct > 0 || $discAmt > 0) {
|
|
||||||
$label = 'Diskon';
|
|
||||||
if ($discPct > 0) $label .= ' (' . $this->_fmt_num($discPct) . '%)';
|
|
||||||
$items[] = array($label, $this->_fmt_rp($discAmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
// PPh (jika ada)
|
|
||||||
$pphPct = floatval($header['SupplierInvoiceTaxPercentPph'] ?? 0);
|
|
||||||
$pphAmt = floatval($header['SupplierInvoiceTaxAmountPph'] ?? 0);
|
|
||||||
if ($pphPct > 0 || $pphAmt > 0) {
|
|
||||||
$label = 'PPh';
|
|
||||||
if ($pphPct > 0) $label .= ' (' . $this->_fmt_num($pphPct) . '%)';
|
|
||||||
$items[] = array($label, $this->_fmt_rp($pphAmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
// PPN (jika ada)
|
|
||||||
$ppnPct = floatval($header['SupplierInvoiceTaxPercentPpn'] ?? 0);
|
|
||||||
$ppnAmt = floatval($header['SupplierInvoiceTaxAmountPpn'] ?? 0);
|
|
||||||
if ($ppnPct > 0 || $ppnAmt > 0) {
|
|
||||||
$label = 'PPN';
|
|
||||||
if ($ppnPct > 0) $label .= ' (' . $this->_fmt_num($ppnPct) . '%)';
|
|
||||||
$items[] = array($label, $this->_fmt_rp($ppnAmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Biaya Kirim (jika ada)
|
|
||||||
$shipCost = floatval($header['SupplierInvoiceShippingCost'] ?? 0);
|
|
||||||
if ($shipCost > 0) {
|
|
||||||
$items[] = array('Biaya Kirim', $this->_fmt_rp($shipCost));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Penyesuaian (jika ada)
|
|
||||||
$adjAmt = floatval($header['SupplierInvoiceAdjustmentAmount'] ?? 0);
|
|
||||||
if ($adjAmt != 0) {
|
|
||||||
$label = 'Penyesuaian';
|
|
||||||
if (!empty($header['SupplierInvoiceAdjustmentNote'])) {
|
|
||||||
$label .= ' (' . $header['SupplierInvoiceAdjustmentNote'] . ')';
|
|
||||||
}
|
|
||||||
$items[] = array($label, $this->_fmt_rp($adjAmt));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($items as $item) {
|
|
||||||
$pdf->SetX($offsetX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
$pdf->Cell($cW1, 5, $item[0], 0, 0, 'L');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
$pdf->Cell($cW2, 5, $item[1], 0, 1, 'R');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grand Total (tebal)
|
|
||||||
$pdf->SetX($offsetX);
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->Line($offsetX, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
|
||||||
$pdf->Ln(1);
|
|
||||||
|
|
||||||
$pdf->SetX($offsetX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 10);
|
|
||||||
$pdf->Cell($cW1, 6, 'Grand Total', 0, 0, 'L');
|
|
||||||
$pdf->Cell($cW2, 6, $this->_fmt_rp($header['SupplierInvoiceGrandTotal']), 0, 1, 'R');
|
|
||||||
|
|
||||||
// Sudah dibayar / sisa
|
|
||||||
$paidAmt = floatval($header['SupplierInvoicePaidAmount'] ?? 0);
|
|
||||||
$unpaidAmt = floatval($header['SupplierInvoiceUnpaid'] ?? 0);
|
|
||||||
$isLunas = $header['SupplierInvoiceIsLunas'] ?? 'N';
|
|
||||||
|
|
||||||
if ($paidAmt > 0) {
|
|
||||||
$pdf->SetX($offsetX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
$pdf->Cell($cW1, 5, 'Dibayar', 0, 0, 'L');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
$pdf->Cell($cW2, 5, $this->_fmt_rp($paidAmt), 0, 1, 'R');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($isLunas === 'Y') {
|
|
||||||
$pdf->SetX($offsetX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
$pdf->SetTextColor(0, 128, 0);
|
|
||||||
$pdf->Cell($cW1 + $cW2, 5, 'LUNAS', 0, 1, 'R');
|
|
||||||
$pdf->SetTextColor(0, 0, 0);
|
|
||||||
} elseif ($unpaidAmt > 0) {
|
|
||||||
$pdf->SetX($offsetX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
|
||||||
$pdf->Cell($cW1, 5, 'Sisa Tagihan', 0, 0, 'L');
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
|
||||||
$pdf->Cell($cW2, 5, $this->_fmt_rp($unpaidAmt), 0, 1, 'R');
|
|
||||||
}
|
|
||||||
|
|
||||||
$pdf->Ln(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Syarat & Ketentuan
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_terms()
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
|
|
||||||
$terms = array(
|
|
||||||
'Faktur ini diterbitkan berdasarkan barang/jasa yang telah diterima dan sesuai dengan purchase order.',
|
|
||||||
'Pembayaran harus dilakukan sesuai dengan tanggal jatuh tempo yang tercantum.',
|
|
||||||
'Keterlambatan pembayaran akan dikenakan sanksi sesuai ketentuan yang berlaku.',
|
|
||||||
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan administrasi perusahaan.',
|
|
||||||
);
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
foreach ($terms as $i => $t) {
|
|
||||||
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
|
||||||
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// HELPER: Format tampilan
|
|
||||||
// =========================================================================
|
|
||||||
private function _fmt_date($d)
|
|
||||||
{
|
|
||||||
if (!$d || $d === '0000-00-00') return '-';
|
|
||||||
return date('d-m-Y', strtotime($d));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_datetime($d)
|
|
||||||
{
|
|
||||||
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
|
||||||
return date('d-m-Y H:i', strtotime($d));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_num($n)
|
|
||||||
{
|
|
||||||
return number_format(floatval($n), 2, ',', '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_qty($n)
|
|
||||||
{
|
|
||||||
return number_format(floatval($n), 0, ',', '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_rp($n)
|
|
||||||
{
|
|
||||||
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,531 +0,0 @@
|
|||||||
<?php
|
|
||||||
defined('BASEPATH') or exit('No direct script access allowed');
|
|
||||||
|
|
||||||
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
|
||||||
// =============================================================================
|
|
||||||
class PemakaianItemDivisiFpdf extends FPDF
|
|
||||||
{
|
|
||||||
public $printUsername = '-';
|
|
||||||
public $printDate = '';
|
|
||||||
|
|
||||||
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
|
||||||
{
|
|
||||||
parent::__construct($orientation, $unit, $size);
|
|
||||||
// Daftarkan Arial Narrow
|
|
||||||
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
|
||||||
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Footer()
|
|
||||||
{
|
|
||||||
$pageW = $this->GetPageWidth() - 30; // margin 15+15
|
|
||||||
|
|
||||||
// -- Posisi: 20mm dari bawah halaman ----------------------------------
|
|
||||||
$this->SetY(-20);
|
|
||||||
|
|
||||||
// -- Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ---------------
|
|
||||||
$colSide = ($pageW - 40) / 2;
|
|
||||||
$colCenter = 40;
|
|
||||||
|
|
||||||
$this->SetFont('Arial_Narrow', '', 7);
|
|
||||||
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
|
||||||
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
|
||||||
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
|
||||||
|
|
||||||
// -- Baris 2: Tgl Print (kiri) ------------------------------------------
|
|
||||||
$this->SetFont('Arial_Narrow', '', 7);
|
|
||||||
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
|
||||||
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Controller
|
|
||||||
// =============================================================================
|
|
||||||
class Rpt_pemakaian_item_divisi extends MY_Controller
|
|
||||||
{
|
|
||||||
// -- Properti bersama antar fungsi PDF -------------------------------------
|
|
||||||
/** @var PemakaianItemDivisiFpdf */
|
|
||||||
private $_pdf;
|
|
||||||
private $_pageW;
|
|
||||||
private $_start_date;
|
|
||||||
private $_end_date;
|
|
||||||
private $_division_id;
|
|
||||||
private $_division_name;
|
|
||||||
private $_username;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
echo "Pemakaian Item per Divisi Report API";
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// ENDPOINT: pdf
|
|
||||||
// GET/POST: start_date, end_date, division_id (opsional), username (opsional)
|
|
||||||
// =========================================================================
|
|
||||||
public function pdf()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$start_date = trim($this->input->get_post('start_date') ?? '');
|
|
||||||
$end_date = trim($this->input->get_post('end_date') ?? '');
|
|
||||||
$division_id = intval($this->input->get_post('division_id'));
|
|
||||||
$username = trim($this->input->get_post('username') ?? '');
|
|
||||||
|
|
||||||
if ($start_date === '' || $end_date === '') {
|
|
||||||
$this->sys_error("Periode tanggal harus diisi");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Ambil data dari DB --------------------------------------------
|
|
||||||
$data = $this->_get_data($start_date, $end_date, $division_id);
|
|
||||||
if (empty($data)) {
|
|
||||||
$this->sys_error("Tidak ada data pemakaian item pada periode tersebut");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->_start_date = $start_date;
|
|
||||||
$this->_end_date = $end_date;
|
|
||||||
$this->_division_id = $division_id;
|
|
||||||
|
|
||||||
// Ambil nama divisi jika dipilih
|
|
||||||
if ($division_id > 0) {
|
|
||||||
$div = $this->_get_division($division_id);
|
|
||||||
$this->_division_name = $div ? $div['DivisionName'] : '';
|
|
||||||
} else {
|
|
||||||
$this->_division_name = 'Semua Divisi';
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Inisialisasi FPDF custom --------------------------------------
|
|
||||||
$this->_pdf = new PemakaianItemDivisiFpdf('P', 'mm', 'A4');
|
|
||||||
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
|
||||||
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
|
||||||
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
|
||||||
$this->_username = $this->_pdf->printUsername;
|
|
||||||
|
|
||||||
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
|
||||||
$this->_pdf->SetMargins(15, 15, 15);
|
|
||||||
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
|
||||||
$this->_pdf->AddPage();
|
|
||||||
|
|
||||||
// -- Susun isi halaman ---------------------------------------------
|
|
||||||
$this->_pdf_header();
|
|
||||||
$this->_pdf_data($data);
|
|
||||||
$this->_pdf_terms();
|
|
||||||
|
|
||||||
// -- Output --------------------------------------------------------
|
|
||||||
$filename = 'PID_' . date('Ymd') . '.pdf';
|
|
||||||
header('Content-Type: application/pdf');
|
|
||||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
|
||||||
header('Cache-Control: private, max-age=0, must-revalidate');
|
|
||||||
header('Pragma: public');
|
|
||||||
echo $this->_pdf->Output('S');
|
|
||||||
} catch (Exception $exc) {
|
|
||||||
$this->sys_error($exc->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// DATABASE: Ambil data divisi
|
|
||||||
// =========================================================================
|
|
||||||
private function _get_division($id)
|
|
||||||
{
|
|
||||||
$sql = "
|
|
||||||
SELECT DivisionID, DivisionCode, DivisionName
|
|
||||||
FROM division
|
|
||||||
WHERE DivisionID = ?
|
|
||||||
AND DivisionIsActive = 'Y'
|
|
||||||
LIMIT 1
|
|
||||||
";
|
|
||||||
$qry = $this->db->query($sql, array($id));
|
|
||||||
return $qry && $qry->num_rows() > 0 ? $qry->row_array() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// DATABASE: Ambil data pemakaian item per divisi
|
|
||||||
// =========================================================================
|
|
||||||
private function _get_data($start_date, $end_date, $division_id = 0)
|
|
||||||
{
|
|
||||||
$sql_where = "
|
|
||||||
WHERE iu.ItemUsedIsActive = 'Y'
|
|
||||||
AND iu.ItemUsedIsConfirm = 'Y'
|
|
||||||
AND iu.ItemUsedDate BETWEEN ? AND ?
|
|
||||||
";
|
|
||||||
$params = array($start_date, $end_date);
|
|
||||||
|
|
||||||
if ($division_id > 0) {
|
|
||||||
// Filter by division melalui item_usage
|
|
||||||
$sql_where .= " AND iu.ItemUsedItemUsageID IN (
|
|
||||||
SELECT ItemUsageID FROM item_usage
|
|
||||||
WHERE ItemUsageDivisionID = ?
|
|
||||||
AND ItemUsageIsActive = 'Y'
|
|
||||||
)";
|
|
||||||
$params[] = $division_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql = "
|
|
||||||
SELECT
|
|
||||||
d.DivisionID,
|
|
||||||
d.DivisionCode,
|
|
||||||
d.DivisionName,
|
|
||||||
iu.ItemUsedID,
|
|
||||||
iu.ItemUsedDate,
|
|
||||||
iu.ItemUsedNumber,
|
|
||||||
iu.ItemUsedBatchNo,
|
|
||||||
iu.ItemUsedQty,
|
|
||||||
iu.ItemUsedPrice,
|
|
||||||
iu.ItemUsedTotal,
|
|
||||||
item.M_ItemID,
|
|
||||||
item.M_ItemCode,
|
|
||||||
item.M_ItemDesc,
|
|
||||||
iunit.ItemUnitName,
|
|
||||||
iunit.ItemUnitCode,
|
|
||||||
us.ItemUsageID,
|
|
||||||
us.ItemUsageDivisionID
|
|
||||||
FROM item_used iu
|
|
||||||
JOIN item_usage us ON us.ItemUsageID = iu.ItemUsedItemUsageID
|
|
||||||
AND us.ItemUsageIsActive = 'Y'
|
|
||||||
JOIN division d ON d.DivisionID = us.ItemUsageDivisionID
|
|
||||||
AND d.DivisionIsActive = 'Y'
|
|
||||||
JOIN m_item item ON item.M_ItemID = iu.ItemUsedM_ItemID
|
|
||||||
AND item.M_ItemIsActive = 'Y'
|
|
||||||
JOIN itemunit iunit ON iunit.ItemUnitID = iu.ItemUsedItemUnitID
|
|
||||||
AND iunit.ItemUnitIsActive = 'Y'
|
|
||||||
$sql_where
|
|
||||||
ORDER BY d.DivisionCode ASC, d.DivisionName ASC, iu.ItemUsedDate ASC, iu.ItemUsedNumber ASC
|
|
||||||
";
|
|
||||||
$qry = $this->db->query($sql, $params);
|
|
||||||
return $qry ? $qry->result_array() : array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Header — Judul + Informasi Laporan
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_header()
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
|
|
||||||
// -- Judul utama -------------------------------------------------------
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
|
||||||
$pdf->Cell($pageW, 8, 'LAPORAN PEMAKAIAN ITEM PER DIVISI', 0, 1, 'L');
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
$pdf->SetLineWidth(0.5);
|
|
||||||
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
|
||||||
$pdf->Ln(2);
|
|
||||||
|
|
||||||
$startY = $pdf->GetY();
|
|
||||||
$halfW = $pageW / 2;
|
|
||||||
$lblW = 30;
|
|
||||||
$valW = $halfW - $lblW - 4;
|
|
||||||
|
|
||||||
// -- Kolom Kiri --------------------------------------------------------
|
|
||||||
$pdf->SetY($startY);
|
|
||||||
|
|
||||||
$leftItems = array(
|
|
||||||
array('Periode Awal', $this->_fmt_date($this->_start_date), false),
|
|
||||||
array('Periode Akhir', $this->_fmt_date($this->_end_date), false),
|
|
||||||
array('Divisi', $this->_division_name, true),
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($leftItems as $item) {
|
|
||||||
$pdf->SetX(15);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
if ($item[2]) {
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
} else {
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
}
|
|
||||||
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
|
||||||
}
|
|
||||||
$leftY = $pdf->GetY();
|
|
||||||
|
|
||||||
// -- Kolom Kanan -------------------------------------------------------
|
|
||||||
$pdf->SetY($startY);
|
|
||||||
$rightX = 15 + $halfW;
|
|
||||||
|
|
||||||
$rightItems = array(
|
|
||||||
array('Print Oleh', $this->_username),
|
|
||||||
array('Tgl Print', $this->_pdf->printDate),
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($rightItems as $item) {
|
|
||||||
$pdf->SetX($rightX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
|
||||||
}
|
|
||||||
$rightY = $pdf->GetY();
|
|
||||||
|
|
||||||
// Posisikan Y ke yang paling bawah + margin
|
|
||||||
$pdf->SetY(max($leftY, $rightY) + 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Data — Tabel pemakaian item per divisi
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_data($data)
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
|
|
||||||
// -- Definisi kolom: [label, lebar, align] -----------------------------
|
|
||||||
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
|
||||||
// 8 + 8 + 68 + 15 + 15 + 22 + 22 + 22 = 180
|
|
||||||
$cols = array(
|
|
||||||
array('No', 6, 'C'),
|
|
||||||
array('Tgl', 16, 'C'),
|
|
||||||
array('Nama Item', 62, 'L'),
|
|
||||||
array('Batch No', 24, 'C'),
|
|
||||||
array('Unit', 14, 'C'),
|
|
||||||
array('Qty', 10, 'R'),
|
|
||||||
array('Harga', 18, 'R'),
|
|
||||||
array('Total', 30, 'R'),
|
|
||||||
);
|
|
||||||
|
|
||||||
$no = 1;
|
|
||||||
$prevDivID = null;
|
|
||||||
$divTotalQty = 0;
|
|
||||||
$divTotalVal = 0;
|
|
||||||
$grandTotalQty = 0;
|
|
||||||
$grandTotalVal = 0;
|
|
||||||
|
|
||||||
// Simpan posisi awal Y untuk setiap divisi — dipakai untuk bounding box
|
|
||||||
$divStartY = 0;
|
|
||||||
|
|
||||||
foreach ($data as $d) {
|
|
||||||
$divID = $d['DivisionID'];
|
|
||||||
|
|
||||||
// -- Jika berganti divisi, cetak subtotal divisi sebelumnya ----------
|
|
||||||
if ($prevDivID !== null && $divID !== $prevDivID) {
|
|
||||||
$this->_pdf_divisi_subtotal($divTotalQty, $divTotalVal);
|
|
||||||
$grandTotalQty += $divTotalQty;
|
|
||||||
$grandTotalVal += $divTotalVal;
|
|
||||||
$divTotalQty = 0;
|
|
||||||
$divTotalVal = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Jika divisi baru, cetak header nama divisi ---------------------
|
|
||||||
if ($prevDivID === null || $divID !== $prevDivID) {
|
|
||||||
// Cek sisa ruang: butuh minimal 8+7+6*n+8 ˜ 40mm untuk header+1 baris+subtotal
|
|
||||||
if ($pdf->GetY() > 230) {
|
|
||||||
$pdf->AddPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
$divStartY = $pdf->GetY();
|
|
||||||
|
|
||||||
// Nama Divisi
|
|
||||||
$pdf->SetFillColor(50, 80, 130);
|
|
||||||
$pdf->SetTextColor(255, 255, 255);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 10);
|
|
||||||
$pdf->Cell($pageW, 7, ' ' . $d['DivisionName'] . ' (' . $d['DivisionCode'] . ')', 1, 1, 'L', true);
|
|
||||||
$pdf->SetTextColor(0, 0, 0);
|
|
||||||
|
|
||||||
// Header kolom
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 7);
|
|
||||||
$pdf->SetFillColor(220, 220, 220);
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
foreach ($cols as $c) {
|
|
||||||
$pdf->Cell($c[1], 6, $c[0], 1, 0, 'C', true);
|
|
||||||
}
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
$no = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Cek apakah perlu halaman baru (min 12mm untuk 1 baris + subtotal) -
|
|
||||||
if ($pdf->GetY() > 258) {
|
|
||||||
$pdf->AddPage();
|
|
||||||
// Ulang header kolom di halaman baru
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 7);
|
|
||||||
$pdf->SetFillColor(220, 220, 220);
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
foreach ($cols as $c) {
|
|
||||||
$pdf->Cell($c[1], 6, $c[0], 1, 0, 'C', true);
|
|
||||||
}
|
|
||||||
$pdf->Ln();
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Baris data item -----------------------------------------------
|
|
||||||
$pdf->SetLineWidth(0.2);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 7.5);
|
|
||||||
$pdf->SetFillColor(255, 255, 255);
|
|
||||||
|
|
||||||
$itemDesc = $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-');
|
|
||||||
$batchNo = $d['ItemUsedBatchNo'] ?: '-';
|
|
||||||
$qty = floatval($d['ItemUsedQty']);
|
|
||||||
$price = floatval($d['ItemUsedPrice']);
|
|
||||||
$total = floatval($d['ItemUsedTotal']);
|
|
||||||
|
|
||||||
// Simpan posisi Y sebelum cell untuk wrap detection
|
|
||||||
$beforeY = $pdf->GetY();
|
|
||||||
|
|
||||||
$pdf->Cell($cols[0][1], 5, $no, 1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[1][1], 5, $this->_fmt_date($d['ItemUsedDate']), 1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[2][1], 5, $itemDesc, 1, 0, 'L');
|
|
||||||
$pdf->Cell($cols[3][1], 5, $batchNo, 1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[4][1], 5, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[5][1], 5, $this->_fmt_qty($qty), 1, 0, 'R');
|
|
||||||
$pdf->Cell($cols[6][1], 5, $this->_fmt_rp($price), 1, 0, 'R');
|
|
||||||
$pdf->Cell($cols[7][1], 5, $this->_fmt_rp($total), 1, 0, 'R');
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
$divTotalQty += $qty;
|
|
||||||
$divTotalVal += $total;
|
|
||||||
$prevDivID = $divID;
|
|
||||||
$no++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Subtotal divisi terakhir -----------------------------------------
|
|
||||||
if ($prevDivID !== null) {
|
|
||||||
$this->_pdf_divisi_subtotal($divTotalQty, $divTotalVal);
|
|
||||||
$grandTotalQty += $divTotalQty;
|
|
||||||
$grandTotalVal += $divTotalVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Grand Total ------------------------------------------------------
|
|
||||||
$pdf->Ln(3);
|
|
||||||
|
|
||||||
// Cek ruang untuk grand total
|
|
||||||
if ($pdf->GetY() > 270) {
|
|
||||||
$pdf->AddPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
$pdf->SetLineWidth(0.4);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 10);
|
|
||||||
$pdf->SetFillColor(180, 200, 220);
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
|
|
||||||
$spanSum = array_sum(array_column(array_slice($cols, 0, 5), 1));
|
|
||||||
$pdf->Cell($spanSum, 7, 'GRAND TOTAL', 1, 0, 'R', true);
|
|
||||||
$pdf->Cell($cols[5][1], 7, $this->_fmt_qty($grandTotalQty), 1, 0, 'R', true);
|
|
||||||
$pdf->Cell($cols[6][1], 7, '', 1, 0, 'R', true);
|
|
||||||
$pdf->Cell($cols[7][1], 7, $this->_fmt_rp($grandTotalVal), 1, 0, 'R', true);
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
$pdf->Ln(4);
|
|
||||||
|
|
||||||
// -- Ringkasan Akhir --------------------------------------------------
|
|
||||||
$summaryX = 15 + $pageW - 90;
|
|
||||||
$cW1 = 50;
|
|
||||||
$cW2 = 40;
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->SetX($summaryX);
|
|
||||||
$pdf->Cell($cW1, 5, 'Total Item Digunakan', 0, 0, 'L');
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
$pdf->Cell($cW2, 5, $this->_fmt_qty($grandTotalQty) . ' ' . 'pcs', 0, 1, 'R');
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->SetX($summaryX);
|
|
||||||
$pdf->Cell($cW1, 5, 'Total Nilai Pemakaian', 0, 0, 'L');
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
$pdf->Cell($cW2, 5, $this->_fmt_rp($grandTotalVal), 0, 1, 'R');
|
|
||||||
|
|
||||||
$pdf->Ln(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SUB-SECTION: Subtotal per Divisi
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_divisi_subtotal($qty, $val)
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
// Gunakan lebar kolom yang sama persis dengan _pdf_data()
|
|
||||||
$cols = array(
|
|
||||||
array('No', 6, 'C'),
|
|
||||||
array('Tgl', 16, 'C'),
|
|
||||||
array('Nama Item', 62, 'L'),
|
|
||||||
array('Batch No', 24, 'C'),
|
|
||||||
array('Unit', 14, 'C'),
|
|
||||||
array('Qty', 10, 'R'),
|
|
||||||
array('Harga', 18, 'R'),
|
|
||||||
array('Total', 30, 'R'),
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($pdf->GetY() > 270) {
|
|
||||||
$pdf->AddPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
$spanSum = array_sum(array_column(array_slice($cols, 0, 5), 1));
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
|
||||||
$pdf->SetFillColor(235, 240, 248);
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
$pdf->Cell($spanSum, 6, 'Sub Total', 1, 0, 'R', true);
|
|
||||||
$pdf->Cell($cols[5][1], 6, $this->_fmt_qty($qty), 1, 0, 'R', true);
|
|
||||||
$pdf->Cell($cols[6][1], 6, '', 1, 0, 'R', true);
|
|
||||||
$pdf->Cell($cols[7][1], 6, $this->_fmt_rp($val), 1, 0, 'R', true);
|
|
||||||
$pdf->Ln();
|
|
||||||
$pdf->Ln(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Syarat & Ketentuan
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_terms()
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
|
|
||||||
$terms = array(
|
|
||||||
'Laporan ini menampilkan seluruh pemakaian item yang telah dikonfirmasi pada periode yang dipilih.',
|
|
||||||
'Data pemakaian dikelompokkan berdasarkan divisi yang melakukan pemakaian.',
|
|
||||||
'Harga yang ditampilkan adalah harga rata-rata pada saat pemakaian item.',
|
|
||||||
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan monitoring pemakaian item.',
|
|
||||||
);
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
foreach ($terms as $i => $t) {
|
|
||||||
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
|
||||||
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// HELPER: Format tampilan
|
|
||||||
// =========================================================================
|
|
||||||
private function _fmt_date($d)
|
|
||||||
{
|
|
||||||
if (!$d || $d === '0000-00-00') return '-';
|
|
||||||
return date('d-m-Y', strtotime($d));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_datetime($d)
|
|
||||||
{
|
|
||||||
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
|
||||||
return date('d-m-Y H:i', strtotime($d));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_num($n)
|
|
||||||
{
|
|
||||||
return number_format(floatval($n), 2, ',', '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_qty($n)
|
|
||||||
{
|
|
||||||
return number_format(floatval($n), 0, ',', '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_rp($n)
|
|
||||||
{
|
|
||||||
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,427 +0,0 @@
|
|||||||
<?php
|
|
||||||
defined('BASEPATH') or exit('No direct script access allowed');
|
|
||||||
|
|
||||||
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
|
||||||
// =============================================================================
|
|
||||||
class MutasiPenerimaanFpdf extends FPDF
|
|
||||||
{
|
|
||||||
public $printUsername = '-';
|
|
||||||
public $printDate = '';
|
|
||||||
|
|
||||||
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
|
||||||
{
|
|
||||||
parent::__construct($orientation, $unit, $size);
|
|
||||||
// Daftarkan Arial Narrow
|
|
||||||
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
|
||||||
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Footer()
|
|
||||||
{
|
|
||||||
$pageW = $this->GetPageWidth() - 30; // margin 15+15
|
|
||||||
|
|
||||||
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
|
||||||
$this->SetY(-20);
|
|
||||||
|
|
||||||
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
|
||||||
$colSide = ($pageW - 40) / 2;
|
|
||||||
$colCenter = 40;
|
|
||||||
|
|
||||||
$this->SetFont('Arial_Narrow', '', 7);
|
|
||||||
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
|
||||||
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
|
||||||
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
|
||||||
|
|
||||||
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
|
||||||
$this->SetFont('Arial_Narrow', '', 7);
|
|
||||||
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
|
||||||
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Controller
|
|
||||||
// =============================================================================
|
|
||||||
class Rpt_penerimaan_mutasi extends MY_Controller
|
|
||||||
{
|
|
||||||
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
|
||||||
/** @var MutasiPenerimaanFpdf */
|
|
||||||
private $_pdf;
|
|
||||||
private $_pageW;
|
|
||||||
private $_header_data;
|
|
||||||
private $_username;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
echo "Mutasi Penerimaan (Receive Mutasi) Report API";
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// ENDPOINT: pdf
|
|
||||||
// GET/POST: id (MutasiHandoverID), username (opsional)
|
|
||||||
// =========================================================================
|
|
||||||
public function pdf()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$id = intval($this->input->get_post('id'));
|
|
||||||
$username = trim($this->input->get_post('username') ?? '');
|
|
||||||
|
|
||||||
if ($id <= 0) {
|
|
||||||
$this->sys_error("ID tidak valid");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Ambil data header & detail dari DB ────────────────────────────
|
|
||||||
$header = $this->_get_header($id);
|
|
||||||
|
|
||||||
// Validasi: hanya dokumen berstatus Received yang bisa dicetak
|
|
||||||
if ($header['MutasiHandoverStatus'] !== 'Received') {
|
|
||||||
$this->sys_error("Dokumen belum diterima (Status: " . $header['MutasiHandoverStatus'] . ")");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$details = $this->_get_detail($id);
|
|
||||||
|
|
||||||
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
|
||||||
$this->_pdf = new MutasiPenerimaanFpdf('P', 'mm', 'A4');
|
|
||||||
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
|
||||||
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
|
||||||
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
|
||||||
$this->_header_data = $header;
|
|
||||||
$this->_username = $this->_pdf->printUsername;
|
|
||||||
|
|
||||||
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
|
||||||
$this->_pdf->SetMargins(15, 15, 15);
|
|
||||||
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
|
||||||
$this->_pdf->AddPage();
|
|
||||||
|
|
||||||
// ── Susun isi halaman ─────────────────────────────────────────────
|
|
||||||
$this->_pdf_header();
|
|
||||||
$this->_pdf_data($details);
|
|
||||||
$this->_pdf_terms();
|
|
||||||
|
|
||||||
// ── Output ────────────────────────────────────────────────────────
|
|
||||||
$filename = 'PM_' . str_replace('/', '-', $header['MutasiHandoverNumber']) . '.pdf';
|
|
||||||
header('Content-Type: application/pdf');
|
|
||||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
|
||||||
header('Cache-Control: private, max-age=0, must-revalidate');
|
|
||||||
header('Pragma: public');
|
|
||||||
echo $this->_pdf->Output('S');
|
|
||||||
} catch (Exception $exc) {
|
|
||||||
$this->sys_error($exc->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// DATABASE: Ambil data header
|
|
||||||
// =========================================================================
|
|
||||||
private function _get_header($id)
|
|
||||||
{
|
|
||||||
$sql = "
|
|
||||||
SELECT
|
|
||||||
mh.*,
|
|
||||||
mr.MutasiRequestNumber,
|
|
||||||
ic.itemCategoryID,
|
|
||||||
ic.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,
|
|
||||||
IFNULL(u.M_UserUsername, '') AS CreatedByName,
|
|
||||||
IFNULL(ur.M_UserUsername, '') AS ReceiveByName,
|
|
||||||
CASE
|
|
||||||
WHEN wh.WarehouseType = 'B' THEN CONCAT(wh.WarehouseCode, ' ', wh.WarehouseName, ' - ', b.M_BranchName)
|
|
||||||
ELSE wh.WarehouseName
|
|
||||||
END AS WarehouseName,
|
|
||||||
r.M_RuanganName
|
|
||||||
FROM mutasi_handover mh
|
|
||||||
LEFT JOIN mutasi_request mr ON mr.MutasiRequestID = mh.MutasiHandoverMutasiRequestID
|
|
||||||
JOIN item_category ic ON ic.itemCategoryID = mh.MutasiHandoverItemCategoryID
|
|
||||||
AND ic.itemCategoryIsActive = 'Y'
|
|
||||||
JOIN m_branch a ON a.M_BranchID = mh.MutasiHandoverFromBranchID
|
|
||||||
AND a.M_BranchIsActive = 'Y'
|
|
||||||
JOIN m_branch b ON b.M_BranchID = mh.MutasiHandoverToBranchID
|
|
||||||
AND b.M_BranchIsActive = 'Y'
|
|
||||||
LEFT JOIN m_user u ON u.M_UserID = mh.MutasiHandoverUserID
|
|
||||||
LEFT JOIN m_user ur ON ur.M_UserID = mh.MutasiHandoverReceiveUserID
|
|
||||||
LEFT JOIN warehouse wh ON wh.WarehouseID = mh.MutasiHandoverReceiveWarehouseID
|
|
||||||
AND wh.WarehouseIsActive = 'Y'
|
|
||||||
LEFT JOIN m_ruangan r ON r.M_RuanganID = mh.MutasiHandoverReceiveM_RuanganID
|
|
||||||
AND r.M_RuanganIsActive = 'Y'
|
|
||||||
WHERE mh.MutasiHandoverID = ?
|
|
||||||
AND mh.MutasiHandoverIsActive = 'Y'
|
|
||||||
LIMIT 1
|
|
||||||
";
|
|
||||||
$qry = $this->db->query($sql, array($id));
|
|
||||||
if (!$qry || $qry->num_rows() === 0) {
|
|
||||||
$this->sys_error("Data Penerimaan Mutasi tidak ditemukan");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
return $qry->row_array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// DATABASE: Ambil data detail
|
|
||||||
// =========================================================================
|
|
||||||
private function _get_detail($id)
|
|
||||||
{
|
|
||||||
$sql = "
|
|
||||||
SELECT
|
|
||||||
mhd.*,
|
|
||||||
i.M_ItemCode,
|
|
||||||
i.M_ItemDesc,
|
|
||||||
iu.ItemUnitName,
|
|
||||||
iu.ItemUnitCode,
|
|
||||||
st.StockStockNumber AS StockToNumber,
|
|
||||||
sf.StockStockNumber AS StockFromNumber
|
|
||||||
FROM mutasi_handover_detail mhd
|
|
||||||
LEFT JOIN m_item i ON i.M_ItemID = mhd.MutasiHandoverDetailM_ItemID
|
|
||||||
LEFT JOIN itemunit iu ON iu.ItemUnitID = mhd.MutasiHandoverDetailItemUnitID
|
|
||||||
LEFT JOIN stock sf ON sf.StockID = mhd.MutasiHandoverDetailStockID_From
|
|
||||||
LEFT JOIN stock st ON st.StockID = mhd.MutasiHandoverDetailStockID_To
|
|
||||||
WHERE mhd.MutasiHandoverDetailMutasiHandoverID = ?
|
|
||||||
AND mhd.MutasiHandoverDetailIsActive = 'Y'
|
|
||||||
ORDER BY mhd.MutasiHandoverDetailID ASC
|
|
||||||
";
|
|
||||||
$qry = $this->db->query($sql, array($id));
|
|
||||||
return $qry ? $qry->result_array() : array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_header()
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
$header = $this->_header_data;
|
|
||||||
|
|
||||||
// ── Judul utama ───────────────────────────────────────────────────────
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
|
||||||
$pdf->Cell($pageW, 8, 'PENERIMAAN MUTASI', 0, 1, 'L');
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
$pdf->SetLineWidth(0.5);
|
|
||||||
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
|
||||||
$pdf->Ln(2);
|
|
||||||
|
|
||||||
$startY = $pdf->GetY();
|
|
||||||
$halfW = $pageW / 2;
|
|
||||||
$lblW = 30;
|
|
||||||
$valW = $halfW - $lblW - 4;
|
|
||||||
|
|
||||||
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
|
||||||
$pdf->SetY($startY);
|
|
||||||
|
|
||||||
$leftItems = array(
|
|
||||||
array('Nomor Handover', $header['MutasiHandoverNumber'], true),
|
|
||||||
array('No. Request', $header['MutasiRequestNumber'] ?: '-', false),
|
|
||||||
array('Tgl Kirim', $this->_fmt_date($header['MutasiHandoverDate']), false),
|
|
||||||
array('Tgl Terima', $this->_fmt_date($header['MutasiHandoverReceiveDate']), false),
|
|
||||||
array('Status', $header['MutasiHandoverStatus'], false),
|
|
||||||
array('Kategori', $header['itemCategoryName'], false),
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($leftItems as $item) {
|
|
||||||
$pdf->SetX(15);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
if ($item[2]) {
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
} else {
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
}
|
|
||||||
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keterangan (Note) langsung di bawah Kategori
|
|
||||||
if (!empty($header['MutasiHandoverNote'])) {
|
|
||||||
$pdf->SetX(15);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->MultiCell($valW, 5, $header['MutasiHandoverNote'], 0, 'L');
|
|
||||||
}
|
|
||||||
$leftY = $pdf->GetY();
|
|
||||||
|
|
||||||
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
|
||||||
$pdf->SetY($startY);
|
|
||||||
$rightX = 15 + $halfW;
|
|
||||||
|
|
||||||
$rightItems = array(
|
|
||||||
array('Cabang Asal', $header['branch_asal_name']),
|
|
||||||
array('Cabang Tujuan', $header['branch_tujuan_name']),
|
|
||||||
array('Warehouse Tujuan', $header['WarehouseName'] ?: '-'),
|
|
||||||
array('Ruangan Tujuan', $header['M_RuanganName'] ?: '-'),
|
|
||||||
array('Diterima Oleh', $header['MutasiHandoverStatus'] === 'Received' ? $header['ReceiveByName'] : '-'),
|
|
||||||
array('Dibuat Oleh', $header['CreatedByName']),
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($rightItems as $item) {
|
|
||||||
$pdf->SetX($rightX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
|
||||||
}
|
|
||||||
|
|
||||||
$rightY = $pdf->GetY();
|
|
||||||
|
|
||||||
// Posisikan Y ke yang paling bawah + margin
|
|
||||||
$pdf->SetY(max($leftY, $rightY) + 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Data — Tabel detail item + ringkasan nilai
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_data($details)
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
$header = $this->_header_data;
|
|
||||||
|
|
||||||
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
|
||||||
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
|
||||||
// 8 + 72 + 15 + 15 + 22 + 22 + 26 = 180
|
|
||||||
$cols = array(
|
|
||||||
array('No', 8, 'C'),
|
|
||||||
array('Nama Item', 72, 'L'),
|
|
||||||
array('Unit', 15, 'C'),
|
|
||||||
array('Qty', 15, 'R'),
|
|
||||||
array('Nilai Buku', 22, 'R'),
|
|
||||||
array('Total', 22, 'R'),
|
|
||||||
array('Stock Tujuan', 26, 'C'),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Header kolom
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 7);
|
|
||||||
$pdf->SetFillColor(220, 220, 220);
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
foreach ($cols as $c) {
|
|
||||||
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
|
||||||
}
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
// Baris data
|
|
||||||
$pdf->SetLineWidth(0.2);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 7.5);
|
|
||||||
$pdf->SetFillColor(255, 255, 255);
|
|
||||||
$no = 1;
|
|
||||||
$total_val = 0;
|
|
||||||
|
|
||||||
foreach ($details as $d) {
|
|
||||||
$bookValue = floatval($d['MutasiHandoverDetailBookValue'] ?? 0);
|
|
||||||
$qty = floatval($d['MutasiHandoverDetailQty'] ?? 0);
|
|
||||||
$lineTotal = $qty * $bookValue;
|
|
||||||
$stockTo = $d['StockToNumber'] ?: '-';
|
|
||||||
|
|
||||||
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
|
||||||
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($qty), 1, 0, 'R');
|
|
||||||
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($bookValue), 1, 0, 'R');
|
|
||||||
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($lineTotal), 1, 0, 'R');
|
|
||||||
$pdf->Cell($cols[6][1], 6, $stockTo, 1, 0, 'C');
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
$total_val += $lineTotal;
|
|
||||||
$no++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Baris TOTAL
|
|
||||||
$span = array_sum(array_column(array_slice($cols, 0, 6), 1));
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
|
||||||
$pdf->SetFillColor(220, 220, 220);
|
|
||||||
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
|
||||||
$pdf->Cell($cols[6][1], 7, '', 1, 0, 'C', true);
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
// ── Ringkasan nilai (rata kanan) ──────────────────────────────────────
|
|
||||||
$pdf->Ln(3);
|
|
||||||
$summary = array(
|
|
||||||
array('Total Nilai Penerimaan', $this->_fmt_rp($header['MutasiHandoverTotalValue'])),
|
|
||||||
);
|
|
||||||
|
|
||||||
$cW1 = 50;
|
|
||||||
$cW2 = 40;
|
|
||||||
$offsetX = 15 + $this->_pageW - $cW1 - $cW2;
|
|
||||||
|
|
||||||
foreach ($summary as $s) {
|
|
||||||
$pdf->SetX($offsetX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
$pdf->Cell($cW1, 5, $s[0], 0, 0, 'L');
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
|
||||||
$pdf->Cell($cW2, 5, $s[1], 0, 1, 'R');
|
|
||||||
}
|
|
||||||
|
|
||||||
$pdf->Ln(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Syarat & Ketentuan
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_terms()
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
|
|
||||||
$terms = array(
|
|
||||||
'Penerimaan mutasi ini dilakukan berdasarkan dokumen handover (penyerahan) yang telah dikirim oleh cabang asal.',
|
|
||||||
'Penerima wajib memeriksa kesesuaian jumlah, jenis, dan kondisi barang dengan dokumen handover.',
|
|
||||||
'Setelah diterima, barang menjadi tanggung jawab cabang tujuan dan akan dicatat dalam stok tujuan.',
|
|
||||||
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan proses mutasi barang.',
|
|
||||||
);
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
foreach ($terms as $i => $t) {
|
|
||||||
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
|
||||||
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// HELPER: Format tampilan
|
|
||||||
// =========================================================================
|
|
||||||
private function _fmt_date($d)
|
|
||||||
{
|
|
||||||
if (!$d || $d === '0000-00-00') return '-';
|
|
||||||
return date('d-m-Y', strtotime($d));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_datetime($d)
|
|
||||||
{
|
|
||||||
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
|
||||||
return date('d-m-Y H:i', strtotime($d));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_num($n)
|
|
||||||
{
|
|
||||||
return number_format(floatval($n), 2, ',', '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_qty($n)
|
|
||||||
{
|
|
||||||
return number_format(floatval($n), 0, ',', '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_rp($n)
|
|
||||||
{
|
|
||||||
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,403 +0,0 @@
|
|||||||
<?php
|
|
||||||
defined('BASEPATH') or exit('No direct script access allowed');
|
|
||||||
|
|
||||||
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
|
||||||
// =============================================================================
|
|
||||||
class PengeluaranBarangFpdf extends FPDF
|
|
||||||
{
|
|
||||||
public $printUsername = '-';
|
|
||||||
public $printDate = '';
|
|
||||||
|
|
||||||
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
|
||||||
{
|
|
||||||
parent::__construct($orientation, $unit, $size);
|
|
||||||
// Daftarkan Arial Narrow
|
|
||||||
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
|
||||||
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Footer()
|
|
||||||
{
|
|
||||||
$pageW = $this->GetPageWidth() - 30; // margin 15+15
|
|
||||||
|
|
||||||
// -- Posisi: 20mm dari bawah halaman ----------------------------------
|
|
||||||
$this->SetY(-20);
|
|
||||||
|
|
||||||
// -- Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ---------------
|
|
||||||
$colSide = ($pageW - 40) / 2;
|
|
||||||
$colCenter = 40;
|
|
||||||
|
|
||||||
$this->SetFont('Arial_Narrow', '', 7);
|
|
||||||
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
|
||||||
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
|
||||||
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
|
||||||
|
|
||||||
// -- Baris 2: Tgl Print (kiri) ------------------------------------------
|
|
||||||
$this->SetFont('Arial_Narrow', '', 7);
|
|
||||||
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
|
||||||
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Controller
|
|
||||||
// =============================================================================
|
|
||||||
class Rpt_pengeluaran_barang extends MY_Controller
|
|
||||||
{
|
|
||||||
// -- Properti bersama antar fungsi PDF -------------------------------------
|
|
||||||
/** @var PengeluaranBarangFpdf */
|
|
||||||
private $_pdf;
|
|
||||||
private $_pageW;
|
|
||||||
private $_header_data;
|
|
||||||
private $_username;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
echo "Pengeluaran Barang Report API";
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// ENDPOINT: pdf
|
|
||||||
// GET/POST: id (T_ItemOutID), username (opsional)
|
|
||||||
// =========================================================================
|
|
||||||
public function pdf()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$id = intval($this->input->get_post('id'));
|
|
||||||
$username = trim($this->input->get_post('username') ?? '');
|
|
||||||
|
|
||||||
if ($id <= 0) {
|
|
||||||
$this->sys_error("ID tidak valid");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Ambil data header & detail dari DB ----------------------------
|
|
||||||
$header = $this->_get_header($id);
|
|
||||||
$details = $this->_get_detail($id);
|
|
||||||
|
|
||||||
// -- Inisialisasi FPDF custom --------------------------------------
|
|
||||||
$this->_pdf = new PengeluaranBarangFpdf('P', 'mm', 'A4');
|
|
||||||
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
|
||||||
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
|
||||||
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
|
||||||
$this->_header_data = $header;
|
|
||||||
$this->_username = $this->_pdf->printUsername;
|
|
||||||
|
|
||||||
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
|
||||||
$this->_pdf->SetMargins(15, 15, 15);
|
|
||||||
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
|
||||||
$this->_pdf->AddPage();
|
|
||||||
|
|
||||||
// -- Susun isi halaman ---------------------------------------------
|
|
||||||
$this->_pdf_header();
|
|
||||||
$this->_pdf_data($details);
|
|
||||||
$this->_pdf_terms();
|
|
||||||
|
|
||||||
// -- Output --------------------------------------------------------
|
|
||||||
$filename = 'IO_' . str_replace('/', '-', $header['T_ItemOutNumber']) . '.pdf';
|
|
||||||
header('Content-Type: application/pdf');
|
|
||||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
|
||||||
header('Cache-Control: private, max-age=0, must-revalidate');
|
|
||||||
header('Pragma: public');
|
|
||||||
echo $this->_pdf->Output('S');
|
|
||||||
} catch (Exception $exc) {
|
|
||||||
$this->sys_error($exc->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// DATABASE: Ambil data header
|
|
||||||
// =========================================================================
|
|
||||||
private function _get_header($id)
|
|
||||||
{
|
|
||||||
$sql = "
|
|
||||||
SELECT
|
|
||||||
io.*,
|
|
||||||
IFNULL(u.M_UserUsername, '') AS CreatedByName,
|
|
||||||
IFNULL(ur.M_UserUsername, '') AS ReceiveByName,
|
|
||||||
IFNULL(ua.M_UserUsername, '') AS ApprovedByName,
|
|
||||||
wh.WarehouseCode,
|
|
||||||
wh.WarehouseName,
|
|
||||||
wh.WarehouseType,
|
|
||||||
d.DivisionCode,
|
|
||||||
d.DivisionName
|
|
||||||
FROM t_item_out io
|
|
||||||
LEFT JOIN m_user u ON u.M_UserID = io.T_ItemOutUserID
|
|
||||||
LEFT JOIN m_user ur ON ur.M_UserID = io.T_ItemOutReceiveUserID
|
|
||||||
LEFT JOIN m_user ua ON ua.M_UserID = io.T_ItemOutApproveID
|
|
||||||
LEFT JOIN warehouse wh ON wh.WarehouseID = io.T_ItemOutWarehouseID
|
|
||||||
AND wh.WarehouseIsActive = 'Y'
|
|
||||||
LEFT JOIN division d ON d.DivisionID = io.T_ItemOutDivisionID
|
|
||||||
AND d.DivisionIsActive = 'Y'
|
|
||||||
WHERE io.T_ItemOutID = ?
|
|
||||||
AND io.T_ItemOutIsActive = 'Y'
|
|
||||||
LIMIT 1
|
|
||||||
";
|
|
||||||
$qry = $this->db->query($sql, array($id));
|
|
||||||
if (!$qry || $qry->num_rows() === 0) {
|
|
||||||
$this->sys_error("Data Pengeluaran Barang tidak ditemukan");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
return $qry->row_array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// DATABASE: Ambil data detail
|
|
||||||
// =========================================================================
|
|
||||||
private function _get_detail($id)
|
|
||||||
{
|
|
||||||
$sql = "
|
|
||||||
SELECT
|
|
||||||
iod.*,
|
|
||||||
i.M_ItemCode,
|
|
||||||
i.M_ItemDesc,
|
|
||||||
iu.ItemUnitName,
|
|
||||||
iu.ItemUnitCode,
|
|
||||||
rod.RequestItemOutDetailQty AS RequestQty,
|
|
||||||
rod.RequestItemOutDetailStatus AS RequestStatus
|
|
||||||
FROM t_item_out_detail iod
|
|
||||||
LEFT JOIN m_item i ON i.M_ItemID = iod.T_ItemOutDetailM_ItemID
|
|
||||||
LEFT JOIN itemunit iu ON iu.ItemUnitID = iod.T_ItemOutDetailItemUnitID
|
|
||||||
LEFT JOIN request_item_out_detail rod
|
|
||||||
ON rod.RequestItemOutDetailID = iod.T_ItemOutDetailRequestItemOutDetailID
|
|
||||||
AND rod.RequestItemOutDetailIsActive = 'Y'
|
|
||||||
WHERE iod.T_ItemOutDetailT_ItemOutID = ?
|
|
||||||
AND iod.T_ItemOutDetailIsActive = 'Y'
|
|
||||||
ORDER BY iod.T_ItemOutDetailID ASC
|
|
||||||
";
|
|
||||||
$qry = $this->db->query($sql, array($id));
|
|
||||||
return $qry ? $qry->result_array() : array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_header()
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
$header = $this->_header_data;
|
|
||||||
|
|
||||||
// -- Judul utama -------------------------------------------------------
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
|
||||||
$pdf->Cell($pageW, 8, 'PENGELUARAN BARANG (ITEM OUT)', 0, 1, 'L');
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
$pdf->SetLineWidth(0.5);
|
|
||||||
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
|
||||||
$pdf->Ln(2);
|
|
||||||
|
|
||||||
$startY = $pdf->GetY();
|
|
||||||
$halfW = $pageW / 2;
|
|
||||||
$lblW = 30;
|
|
||||||
$valW = $halfW - $lblW - 4;
|
|
||||||
|
|
||||||
// -- Kolom Kiri --------------------------------------------------------
|
|
||||||
$pdf->SetY($startY);
|
|
||||||
|
|
||||||
$leftItems = array(
|
|
||||||
array('Nomor IO', $header['T_ItemOutNumber'], true),
|
|
||||||
array('Tanggal', $this->_fmt_date($header['T_ItemOutDate']), false),
|
|
||||||
array('Status', $header['T_ItemOutStatus'], false),
|
|
||||||
array('Confirm', $header['T_ItemOutIsConfirm'] === 'Y' ? 'Ya' : 'Tidak', false),
|
|
||||||
array('Divisi', $header['DivisionName'] ?: '-', false),
|
|
||||||
array('Gudang', $header['WarehouseName'] ?: '-', false),
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($leftItems as $item) {
|
|
||||||
$pdf->SetX(15);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
if ($item[2]) {
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
} else {
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
}
|
|
||||||
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keterangan (Note) langsung di bawah field terakhir
|
|
||||||
if (!empty($header['T_ItemOutNote'])) {
|
|
||||||
$pdf->SetX(15);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->MultiCell($valW, 5, $header['T_ItemOutNote'], 0, 'L');
|
|
||||||
}
|
|
||||||
$leftY = $pdf->GetY();
|
|
||||||
|
|
||||||
// -- Kolom Kanan -------------------------------------------------------
|
|
||||||
$pdf->SetY($startY);
|
|
||||||
$rightX = 15 + $halfW;
|
|
||||||
|
|
||||||
$rightItems = array(
|
|
||||||
array('Dibuat Oleh', $header['CreatedByName'] ?: '-'),
|
|
||||||
array('Dibuat Tgl', $this->_fmt_datetime($header['T_ItemOutCreated'])),
|
|
||||||
array('Penerima', $header['ReceiveByName'] ?: '-'),
|
|
||||||
array('Disetujui Oleh', $header['ApprovedByName'] ?: '-'),
|
|
||||||
array('Tgl Approve', $header['T_ItemOutApproveDate'] ? $this->_fmt_datetime($header['T_ItemOutApproveDate']) : '-'),
|
|
||||||
array('Tgl Dikonfirmasi', $header['T_ItemOutIsConfirmDate'] ? $this->_fmt_datetime($header['T_ItemOutIsConfirmDate']) : '-'),
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($rightItems as $item) {
|
|
||||||
$pdf->SetX($rightX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
|
||||||
}
|
|
||||||
|
|
||||||
$rightY = $pdf->GetY();
|
|
||||||
|
|
||||||
// Posisikan Y ke yang paling bawah + margin
|
|
||||||
$pdf->SetY(max($leftY, $rightY) + 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Data — Tabel detail item
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_data($details)
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
|
|
||||||
// -- Definisi kolom: [label, lebar, align] -----------------------------
|
|
||||||
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
|
||||||
// 8 + 72 + 20 + 20 + 30 + 30 = 180
|
|
||||||
$cols = array(
|
|
||||||
array('No', 8, 'C'),
|
|
||||||
array('Nama Item', 72, 'L'),
|
|
||||||
array('Unit', 20, 'C'),
|
|
||||||
array('Qty', 20, 'R'),
|
|
||||||
array('Batch No.', 30, 'C'),
|
|
||||||
array('Qty Request', 30, 'R'),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Header kolom
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
|
||||||
$pdf->SetFillColor(220, 220, 220);
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
foreach ($cols as $c) {
|
|
||||||
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
|
||||||
}
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
// Baris data
|
|
||||||
$pdf->SetLineWidth(0.2);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
$pdf->SetFillColor(255, 255, 255);
|
|
||||||
$no = 1;
|
|
||||||
$total_qty = 0;
|
|
||||||
$total_req = 0;
|
|
||||||
|
|
||||||
foreach ($details as $d) {
|
|
||||||
$qty = floatval($d['T_ItemOutDetailQty'] ?? 0);
|
|
||||||
$qtyReq = floatval($d['T_ItemOutDetailRequestItemOutDetailID'] > 0 ? $qty : 0);
|
|
||||||
$batchNo = $d['T_ItemOutDetailItemBatchNo'] ?? '';
|
|
||||||
// Jika batch no berupa JSON array, decode untuk ditampilkan
|
|
||||||
$batchDisplay = $batchNo;
|
|
||||||
if (strpos($batchNo, '[') === 0) {
|
|
||||||
$decoded = json_decode($batchNo, true);
|
|
||||||
if (is_array($decoded) && count($decoded) > 0) {
|
|
||||||
$parts = array();
|
|
||||||
foreach ($decoded as $b) {
|
|
||||||
$parts[] = isset($b['batchNo']) ? $b['batchNo'] : (isset($b['BatchNo']) ? $b['BatchNo'] : (is_string($b) ? $b : '-'));
|
|
||||||
}
|
|
||||||
$batchDisplay = implode(', ', $parts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
|
||||||
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($qty), 1, 0, 'R');
|
|
||||||
$pdf->Cell($cols[4][1], 6, $batchDisplay, 1, 0, 'C');
|
|
||||||
$reqQty = isset($d['RequestQty']) ? floatval($d['RequestQty']) : 0;
|
|
||||||
$pdf->Cell($cols[5][1], 6, $reqQty > 0 ? $this->_fmt_qty($reqQty) : '-', 1, 0, 'R');
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
$total_qty += $qty;
|
|
||||||
if ($reqQty > 0) {
|
|
||||||
$total_req += $reqQty;
|
|
||||||
}
|
|
||||||
$no++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Baris TOTAL
|
|
||||||
$span = array_sum(array_column(array_slice($cols, 0, 4), 1));
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
|
||||||
$pdf->SetFillColor(220, 220, 220);
|
|
||||||
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
|
||||||
$pdf->Cell($cols[4][1], 7, '', 1, 0, 'C', true);
|
|
||||||
$pdf->Cell($cols[5][1], 7, $this->_fmt_qty($total_qty), 1, 0, 'R', true);
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
$pdf->Ln(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Syarat & Ketentuan
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_terms()
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
|
|
||||||
$terms = array(
|
|
||||||
'Barang yang dikeluarkan harus sesuai dengan jumlah dan spesifikasi yang tercantum dalam dokumen ini.',
|
|
||||||
'Penerima barang wajib memeriksa dan memverifikasi kesesuaian barang sebelum menerima.',
|
|
||||||
'Dokumen ini merupakan bukti sah pengeluaran barang dari gudang.',
|
|
||||||
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan administrasi perusahaan.',
|
|
||||||
);
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
foreach ($terms as $i => $t) {
|
|
||||||
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
|
||||||
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// HELPER: Format tampilan
|
|
||||||
// =========================================================================
|
|
||||||
private function _fmt_date($d)
|
|
||||||
{
|
|
||||||
if (!$d || $d === '0000-00-00') return '-';
|
|
||||||
return date('d-m-Y', strtotime($d));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_datetime($d)
|
|
||||||
{
|
|
||||||
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
|
||||||
return date('d-m-Y H:i', strtotime($d));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_num($n)
|
|
||||||
{
|
|
||||||
return number_format(floatval($n), 2, ',', '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_qty($n)
|
|
||||||
{
|
|
||||||
return number_format(floatval($n), 0, ',', '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_rp($n)
|
|
||||||
{
|
|
||||||
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,429 +0,0 @@
|
|||||||
<?php
|
|
||||||
defined('BASEPATH') or exit('No direct script access allowed');
|
|
||||||
|
|
||||||
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
|
||||||
// =============================================================================
|
|
||||||
class MutasiHandoverFpdf extends FPDF
|
|
||||||
{
|
|
||||||
public $printUsername = '-';
|
|
||||||
public $printDate = '';
|
|
||||||
|
|
||||||
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
|
||||||
{
|
|
||||||
parent::__construct($orientation, $unit, $size);
|
|
||||||
// Daftarkan Arial Narrow
|
|
||||||
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
|
||||||
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Footer()
|
|
||||||
{
|
|
||||||
$pageW = $this->GetPageWidth() - 30; // margin 15+15
|
|
||||||
|
|
||||||
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
|
||||||
$this->SetY(-20);
|
|
||||||
|
|
||||||
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
|
||||||
$colSide = ($pageW - 40) / 2;
|
|
||||||
$colCenter = 40;
|
|
||||||
|
|
||||||
$this->SetFont('Arial_Narrow', '', 7);
|
|
||||||
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
|
||||||
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
|
||||||
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
|
||||||
|
|
||||||
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
|
||||||
$this->SetFont('Arial_Narrow', '', 7);
|
|
||||||
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
|
||||||
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Controller
|
|
||||||
// =============================================================================
|
|
||||||
class Rpt_penyerahan_mutasi extends MY_Controller
|
|
||||||
{
|
|
||||||
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
|
||||||
/** @var MutasiHandoverFpdf */
|
|
||||||
private $_pdf;
|
|
||||||
private $_pageW;
|
|
||||||
private $_header_data;
|
|
||||||
private $_username;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
echo "Mutasi Handover (Penyerahan Mutasi) Report API";
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// ENDPOINT: pdf
|
|
||||||
// GET/POST: id (MutasiHandoverID), username (opsional)
|
|
||||||
// =========================================================================
|
|
||||||
public function pdf()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$id = intval($this->input->get_post('id'));
|
|
||||||
$username = trim($this->input->get_post('username') ?? '');
|
|
||||||
|
|
||||||
if ($id <= 0) {
|
|
||||||
$this->sys_error("ID tidak valid");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Ambil data header & detail dari DB ────────────────────────────
|
|
||||||
$header = $this->_get_header($id);
|
|
||||||
$details = $this->_get_detail($id);
|
|
||||||
|
|
||||||
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
|
||||||
$this->_pdf = new MutasiHandoverFpdf('P', 'mm', 'A4');
|
|
||||||
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
|
||||||
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
|
||||||
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
|
||||||
$this->_header_data = $header;
|
|
||||||
$this->_username = $this->_pdf->printUsername;
|
|
||||||
|
|
||||||
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
|
||||||
$this->_pdf->SetMargins(15, 15, 15);
|
|
||||||
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
|
||||||
$this->_pdf->AddPage();
|
|
||||||
|
|
||||||
// ── Susun isi halaman ─────────────────────────────────────────────
|
|
||||||
$this->_pdf_header();
|
|
||||||
$this->_pdf_data($details);
|
|
||||||
$this->_pdf_terms();
|
|
||||||
|
|
||||||
// ── Output ────────────────────────────────────────────────────────
|
|
||||||
$filename = 'PH_' . str_replace('/', '-', $header['MutasiHandoverNumber']) . '.pdf';
|
|
||||||
header('Content-Type: application/pdf');
|
|
||||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
|
||||||
header('Cache-Control: private, max-age=0, must-revalidate');
|
|
||||||
header('Pragma: public');
|
|
||||||
echo $this->_pdf->Output('S');
|
|
||||||
} catch (Exception $exc) {
|
|
||||||
$this->sys_error($exc->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// DATABASE: Ambil data header
|
|
||||||
// =========================================================================
|
|
||||||
private function _get_header($id)
|
|
||||||
{
|
|
||||||
$sql = "
|
|
||||||
SELECT
|
|
||||||
mh.*,
|
|
||||||
mr.MutasiRequestNumber,
|
|
||||||
ic.itemCategoryID,
|
|
||||||
ic.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,
|
|
||||||
IFNULL(u.M_UserUsername, '') AS CreatedByName,
|
|
||||||
IFNULL(ur.M_UserUsername, '') AS ReceiveByName,
|
|
||||||
CASE
|
|
||||||
WHEN wh.WarehouseType = 'B' THEN CONCAT(wh.WarehouseCode, ' ', wh.WarehouseName, ' - ', b.M_BranchName)
|
|
||||||
ELSE wh.WarehouseName
|
|
||||||
END AS WarehouseName,
|
|
||||||
r.M_RuanganName
|
|
||||||
FROM mutasi_handover mh
|
|
||||||
LEFT JOIN mutasi_request mr ON mr.MutasiRequestID = mh.MutasiHandoverMutasiRequestID
|
|
||||||
JOIN item_category ic ON ic.itemCategoryID = mh.MutasiHandoverItemCategoryID
|
|
||||||
AND ic.itemCategoryIsActive = 'Y'
|
|
||||||
JOIN m_branch a ON a.M_BranchID = mh.MutasiHandoverFromBranchID
|
|
||||||
AND a.M_BranchIsActive = 'Y'
|
|
||||||
JOIN m_branch b ON b.M_BranchID = mh.MutasiHandoverToBranchID
|
|
||||||
AND b.M_BranchIsActive = 'Y'
|
|
||||||
LEFT JOIN m_user u ON u.M_UserID = mh.MutasiHandoverUserID
|
|
||||||
LEFT JOIN m_user ur ON ur.M_UserID = mh.MutasiHandoverReceiveUserID
|
|
||||||
LEFT JOIN warehouse wh ON wh.WarehouseID = mh.MutasiHandoverReceiveWarehouseID
|
|
||||||
AND wh.WarehouseIsActive = 'Y'
|
|
||||||
LEFT JOIN m_ruangan r ON r.M_RuanganID = mh.MutasiHandoverReceiveM_RuanganID
|
|
||||||
AND r.M_RuanganIsActive = 'Y'
|
|
||||||
WHERE mh.MutasiHandoverID = ?
|
|
||||||
AND mh.MutasiHandoverIsActive = 'Y'
|
|
||||||
LIMIT 1
|
|
||||||
";
|
|
||||||
$qry = $this->db->query($sql, array($id));
|
|
||||||
if (!$qry || $qry->num_rows() === 0) {
|
|
||||||
$this->sys_error("Data Penyerahan Mutasi tidak ditemukan");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
return $qry->row_array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// DATABASE: Ambil data detail
|
|
||||||
// =========================================================================
|
|
||||||
private function _get_detail($id)
|
|
||||||
{
|
|
||||||
$sql = "
|
|
||||||
SELECT
|
|
||||||
mhd.*,
|
|
||||||
i.M_ItemCode,
|
|
||||||
i.M_ItemDesc,
|
|
||||||
iu.ItemUnitName,
|
|
||||||
iu.ItemUnitCode
|
|
||||||
FROM mutasi_handover_detail mhd
|
|
||||||
LEFT JOIN m_item i ON i.M_ItemID = mhd.MutasiHandoverDetailM_ItemID
|
|
||||||
LEFT JOIN itemunit iu ON iu.ItemUnitID = mhd.MutasiHandoverDetailItemUnitID
|
|
||||||
WHERE mhd.MutasiHandoverDetailMutasiHandoverID = ?
|
|
||||||
AND mhd.MutasiHandoverDetailIsActive = 'Y'
|
|
||||||
ORDER BY mhd.MutasiHandoverDetailID ASC
|
|
||||||
";
|
|
||||||
$qry = $this->db->query($sql, array($id));
|
|
||||||
return $qry ? $qry->result_array() : array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_header()
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
$header = $this->_header_data;
|
|
||||||
|
|
||||||
// ── Judul utama ───────────────────────────────────────────────────────
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
|
||||||
$pdf->Cell($pageW, 8, 'PENYERAHAN MUTASI (HANDOVER)', 0, 1, 'L');
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
$pdf->SetLineWidth(0.5);
|
|
||||||
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
|
||||||
$pdf->Ln(2);
|
|
||||||
|
|
||||||
$startY = $pdf->GetY();
|
|
||||||
$halfW = $pageW / 2;
|
|
||||||
$lblW = 30;
|
|
||||||
$valW = $halfW - $lblW - 4;
|
|
||||||
|
|
||||||
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
|
||||||
$pdf->SetY($startY);
|
|
||||||
|
|
||||||
$leftItems = array(
|
|
||||||
array('Nomor Handover', $header['MutasiHandoverNumber'], true),
|
|
||||||
array('No. Request', $header['MutasiRequestNumber'] ?: '-', false),
|
|
||||||
array('Tanggal', $this->_fmt_date($header['MutasiHandoverDate']), false),
|
|
||||||
array('Status', $header['MutasiHandoverStatus'], false),
|
|
||||||
array('Kategori', $header['itemCategoryName'], false),
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($leftItems as $item) {
|
|
||||||
$pdf->SetX(15);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
if ($item[2]) {
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
} else {
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
}
|
|
||||||
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keterangan (Note) langsung di bawah Status
|
|
||||||
if (!empty($header['MutasiHandoverNote'])) {
|
|
||||||
$pdf->SetX(15);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->MultiCell($valW, 5, $header['MutasiHandoverNote'], 0, 'L');
|
|
||||||
}
|
|
||||||
$leftY = $pdf->GetY();
|
|
||||||
|
|
||||||
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
|
||||||
$pdf->SetY($startY);
|
|
||||||
$rightX = 15 + $halfW;
|
|
||||||
|
|
||||||
$rightItems = array(
|
|
||||||
array('Cabang Asal', $header['branch_asal_name']),
|
|
||||||
array('Cabang Tujuan', $header['branch_tujuan_name']),
|
|
||||||
array('Warehouse Tujuan', $header['WarehouseName'] ?: '-'),
|
|
||||||
array('Ruangan Tujuan', $header['M_RuanganName'] ?: '-'),
|
|
||||||
array('Dibuat Oleh', $header['CreatedByName']),
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($rightItems as $item) {
|
|
||||||
$pdf->SetX($rightX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tanggal terima di kolom kanan
|
|
||||||
$pdf->SetX($rightX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, 'Tgl Terima', 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($valW, 5, $this->_fmt_date($header['MutasiHandoverReceiveDate']), 0, 1, 'L');
|
|
||||||
|
|
||||||
// Penerima di kolom kanan
|
|
||||||
if ($header['MutasiHandoverStatus'] === 'Received') {
|
|
||||||
$pdf->SetX($rightX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, 'Diterima Oleh', 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($valW, 5, $header['ReceiveByName'] ?: '-', 0, 1, 'L');
|
|
||||||
}
|
|
||||||
|
|
||||||
$rightY = $pdf->GetY();
|
|
||||||
|
|
||||||
// Posisikan Y ke yang paling bawah + margin
|
|
||||||
$pdf->SetY(max($leftY, $rightY) + 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Data — Tabel detail item + ringkasan nilai
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_data($details)
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
$header = $this->_header_data;
|
|
||||||
|
|
||||||
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
|
||||||
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
|
||||||
// 8 + 80 + 20 + 20 + 25 + 27 = 180
|
|
||||||
$cols = array(
|
|
||||||
array('No', 8, 'C'),
|
|
||||||
array('Nama Item', 80, 'L'),
|
|
||||||
array('Unit', 20, 'C'),
|
|
||||||
array('Qty', 20, 'R'),
|
|
||||||
array('Nilai Buku', 25, 'R'),
|
|
||||||
array('Total', 27, 'R'),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Header kolom
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
|
||||||
$pdf->SetFillColor(220, 220, 220);
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
foreach ($cols as $c) {
|
|
||||||
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
|
||||||
}
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
// Baris data
|
|
||||||
$pdf->SetLineWidth(0.2);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
$pdf->SetFillColor(255, 255, 255);
|
|
||||||
$no = 1;
|
|
||||||
$total_val = 0;
|
|
||||||
|
|
||||||
foreach ($details as $d) {
|
|
||||||
$bookValue = floatval($d['MutasiHandoverDetailBookValue'] ?? 0);
|
|
||||||
$qty = floatval($d['MutasiHandoverDetailQty'] ?? 0);
|
|
||||||
$lineTotal = $qty * $bookValue;
|
|
||||||
|
|
||||||
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
|
||||||
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($qty), 1, 0, 'R');
|
|
||||||
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($bookValue), 1, 0, 'R');
|
|
||||||
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($lineTotal), 1, 0, 'R');
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
$total_val += $lineTotal;
|
|
||||||
$no++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Baris TOTAL
|
|
||||||
$span = array_sum(array_column(array_slice($cols, 0, 5), 1));
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
$pdf->SetFillColor(220, 220, 220);
|
|
||||||
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
|
||||||
$pdf->Cell($cols[5][1], 7, $this->_fmt_rp($total_val), 1, 0, 'R', true);
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
// ── Ringkasan nilai (rata kanan) ──────────────────────────────────────
|
|
||||||
$pdf->Ln(3);
|
|
||||||
$summary = array(
|
|
||||||
array('Total Nilai Penyerahan', $this->_fmt_rp($header['MutasiHandoverTotalValue'])),
|
|
||||||
);
|
|
||||||
|
|
||||||
$cW1 = 50;
|
|
||||||
$cW2 = 40;
|
|
||||||
$offsetX = 15 + $this->_pageW - $cW1 - $cW2;
|
|
||||||
|
|
||||||
foreach ($summary as $s) {
|
|
||||||
$pdf->SetX($offsetX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
$pdf->Cell($cW1, 5, $s[0], 0, 0, 'L');
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
|
||||||
$pdf->Cell($cW2, 5, $s[1], 0, 1, 'R');
|
|
||||||
}
|
|
||||||
|
|
||||||
$pdf->Ln(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Syarat & Ketentuan
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_terms()
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
|
|
||||||
$terms = array(
|
|
||||||
'Penyerahan mutasi ini dilakukan berdasarkan dokumen mutasi yang telah disetujui sebelumnya.',
|
|
||||||
'Barang yang diserahkan harus sesuai dengan jumlah dan spesifikasi yang tercantum dalam dokumen ini.',
|
|
||||||
'Penerima barang wajib memeriksa dan memverifikasi kesesuaian barang sebelum menerima.',
|
|
||||||
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan proses mutasi barang.',
|
|
||||||
);
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
foreach ($terms as $i => $t) {
|
|
||||||
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
|
||||||
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// HELPER: Format tampilan
|
|
||||||
// =========================================================================
|
|
||||||
private function _fmt_date($d)
|
|
||||||
{
|
|
||||||
if (!$d || $d === '0000-00-00') return '-';
|
|
||||||
return date('d-m-Y', strtotime($d));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_datetime($d)
|
|
||||||
{
|
|
||||||
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
|
||||||
return date('d-m-Y H:i', strtotime($d));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_num($n)
|
|
||||||
{
|
|
||||||
return number_format(floatval($n), 2, ',', '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_qty($n)
|
|
||||||
{
|
|
||||||
return number_format(floatval($n), 0, ',', '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_rp($n)
|
|
||||||
{
|
|
||||||
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,391 +0,0 @@
|
|||||||
<?php
|
|
||||||
defined('BASEPATH') or exit('No direct script access allowed');
|
|
||||||
|
|
||||||
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
|
||||||
// =============================================================================
|
|
||||||
class RequestMutasiFpdf extends FPDF
|
|
||||||
{
|
|
||||||
public $printUsername = '-';
|
|
||||||
public $printDate = '';
|
|
||||||
|
|
||||||
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
|
||||||
{
|
|
||||||
parent::__construct($orientation, $unit, $size);
|
|
||||||
// Daftarkan Arial Narrow
|
|
||||||
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
|
||||||
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Footer()
|
|
||||||
{
|
|
||||||
$pageW = $this->GetPageWidth() - 30; // margin 15+15
|
|
||||||
|
|
||||||
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
|
||||||
$this->SetY(-20);
|
|
||||||
|
|
||||||
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
|
||||||
$colSide = ($pageW - 40) / 2;
|
|
||||||
$colCenter = 40;
|
|
||||||
|
|
||||||
$this->SetFont('Arial_Narrow', '', 7);
|
|
||||||
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
|
||||||
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
|
||||||
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
|
||||||
|
|
||||||
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
|
||||||
$this->SetFont('Arial_Narrow', '', 7);
|
|
||||||
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
|
||||||
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Controller
|
|
||||||
// =============================================================================
|
|
||||||
class Rpt_request_mutasi extends MY_Controller
|
|
||||||
{
|
|
||||||
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
|
||||||
/** @var RequestMutasiFpdf */
|
|
||||||
private $_pdf;
|
|
||||||
private $_pageW;
|
|
||||||
private $_header_data;
|
|
||||||
private $_username;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
echo "Request Mutasi Report API";
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// ENDPOINT: pdf
|
|
||||||
// GET/POST: id (MutasiRequestID), username (opsional)
|
|
||||||
// =========================================================================
|
|
||||||
public function pdf()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$id = intval($this->input->get_post('id'));
|
|
||||||
$username = trim($this->input->get_post('username') ?? '');
|
|
||||||
|
|
||||||
if ($id <= 0) {
|
|
||||||
$this->sys_error("ID tidak valid");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Ambil data header & detail dari DB ────────────────────────────
|
|
||||||
$header = $this->_get_header($id);
|
|
||||||
$details = $this->_get_detail($id);
|
|
||||||
|
|
||||||
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
|
||||||
$this->_pdf = new RequestMutasiFpdf('P', 'mm', 'A4');
|
|
||||||
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
|
||||||
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
|
||||||
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
|
||||||
$this->_header_data = $header;
|
|
||||||
$this->_username = $this->_pdf->printUsername;
|
|
||||||
|
|
||||||
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
|
||||||
$this->_pdf->SetMargins(15, 15, 15);
|
|
||||||
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
|
||||||
$this->_pdf->AddPage();
|
|
||||||
|
|
||||||
// ── Susun isi halaman ─────────────────────────────────────────────
|
|
||||||
$this->_pdf_header();
|
|
||||||
$this->_pdf_data($details);
|
|
||||||
$this->_pdf_terms();
|
|
||||||
|
|
||||||
// ── Output ────────────────────────────────────────────────────────
|
|
||||||
$filename = 'RM_' . str_replace('/', '-', $header['MutasiRequestNumber']) . '.pdf';
|
|
||||||
header('Content-Type: application/pdf');
|
|
||||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
|
||||||
header('Cache-Control: private, max-age=0, must-revalidate');
|
|
||||||
header('Pragma: public');
|
|
||||||
echo $this->_pdf->Output('S');
|
|
||||||
} catch (Exception $exc) {
|
|
||||||
$this->sys_error($exc->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// DATABASE: Ambil data header
|
|
||||||
// =========================================================================
|
|
||||||
private function _get_header($id)
|
|
||||||
{
|
|
||||||
$sql = "
|
|
||||||
SELECT
|
|
||||||
mr.*,
|
|
||||||
ic.itemCategoryID,
|
|
||||||
ic.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,
|
|
||||||
IFNULL(u.M_UserUsername, '') AS CreatedByName,
|
|
||||||
IFNULL(uv.M_UserUsername, '') AS VerifByName,
|
|
||||||
IFNULL(ua.M_UserUsername, '') AS ApprovedByName
|
|
||||||
FROM mutasi_request mr
|
|
||||||
JOIN item_category ic ON ic.itemCategoryID = mr.MutasiRequestItemCategoryID
|
|
||||||
JOIN m_branch a ON a.M_BranchID = mr.MutasiRequestFromBranchID
|
|
||||||
JOIN m_branch b ON b.M_BranchID = mr.MutasiRequestToBranchID
|
|
||||||
LEFT JOIN m_user u ON u.M_UserID = mr.MutasiRequestUserID
|
|
||||||
LEFT JOIN m_user uv ON uv.M_UserID = mr.MutasiRequestVerifUserID
|
|
||||||
LEFT JOIN m_user ua ON ua.M_UserID = mr.MutasiRequestApprovedUserID
|
|
||||||
WHERE mr.MutasiRequestID = ?
|
|
||||||
LIMIT 1
|
|
||||||
";
|
|
||||||
$qry = $this->db->query($sql, array($id));
|
|
||||||
if (!$qry || $qry->num_rows() === 0) {
|
|
||||||
$this->sys_error("Data Request Mutasi tidak ditemukan");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
return $qry->row_array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// DATABASE: Ambil data detail
|
|
||||||
// =========================================================================
|
|
||||||
private function _get_detail($id)
|
|
||||||
{
|
|
||||||
$sql = "
|
|
||||||
SELECT
|
|
||||||
mrd.*,
|
|
||||||
i.M_ItemCode,
|
|
||||||
i.M_ItemDesc,
|
|
||||||
iu.ItemUnitName,
|
|
||||||
iu.ItemUnitCode
|
|
||||||
FROM mutasi_request_detail mrd
|
|
||||||
LEFT JOIN m_item i ON i.M_ItemID = mrd.MutasiRequestDetailM_ItemID
|
|
||||||
LEFT JOIN itemunit iu ON iu.ItemUnitID = mrd.MutasiRequestDetailItemUnitID
|
|
||||||
WHERE mrd.MutasiRequestDetailMutasiRequestID = ?
|
|
||||||
AND mrd.MutasiRequestDetailIsActive = 'Y'
|
|
||||||
ORDER BY mrd.MutasiRequestDetailID ASC
|
|
||||||
";
|
|
||||||
$qry = $this->db->query($sql, array($id));
|
|
||||||
return $qry ? $qry->result_array() : array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_header()
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
$header = $this->_header_data;
|
|
||||||
|
|
||||||
// ── Judul utama ───────────────────────────────────────────────────────
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
|
||||||
$pdf->Cell($pageW, 8, 'REQUEST MUTASI REPORT (RM)', 0, 1, 'L');
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
$pdf->SetLineWidth(0.5);
|
|
||||||
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
|
||||||
$pdf->Ln(2);
|
|
||||||
|
|
||||||
$startY = $pdf->GetY();
|
|
||||||
$halfW = $pageW / 2;
|
|
||||||
$lblW = 30;
|
|
||||||
$valW = $halfW - $lblW - 4;
|
|
||||||
|
|
||||||
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
|
||||||
$pdf->SetY($startY);
|
|
||||||
|
|
||||||
$leftItems = array(
|
|
||||||
array('Nomor', $header['MutasiRequestNumber'], true),
|
|
||||||
array('Tanggal', $this->_fmt_date($header['MutasiRequestDate']), false),
|
|
||||||
array('Status', $header['MutasiRequestStatus'], false),
|
|
||||||
array('Kategori', $header['itemCategoryName'], false),
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($leftItems as $item) {
|
|
||||||
$pdf->SetX(15);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
if ($item[2]) {
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
} else {
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
}
|
|
||||||
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keterangan (Note) langsung di bawah Status
|
|
||||||
if (!empty($header['MutasiRequestNote'])) {
|
|
||||||
$pdf->SetX(15);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->MultiCell($valW, 5, $header['MutasiRequestNote'], 0, 'L');
|
|
||||||
}
|
|
||||||
$leftY = $pdf->GetY();
|
|
||||||
|
|
||||||
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
|
||||||
$pdf->SetY($startY);
|
|
||||||
$rightX = 15 + $halfW;
|
|
||||||
|
|
||||||
$rightItems = array(
|
|
||||||
array('Cabang Asal', $header['branch_asal_name']),
|
|
||||||
array('Cabang Tujuan', $header['branch_tujuan_name']),
|
|
||||||
array('Dibuat Oleh', $header['CreatedByName']),
|
|
||||||
array('Diverifikasi Oleh', $header['VerifByName'] ?: '-'),
|
|
||||||
array('Disetujui Oleh', $header['ApprovedByName'] ?: '-'),
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($rightItems as $item) {
|
|
||||||
$pdf->SetX($rightX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tanggal approvals di kolom kanan
|
|
||||||
$pdf->SetX($rightX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, 'Tgl Verifikasi', 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($valW, 5, $this->_fmt_datetime($header['MutasiRequestVerifDate']), 0, 1, 'L');
|
|
||||||
|
|
||||||
$pdf->SetX($rightX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, 'Tgl Approved', 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($valW, 5, $this->_fmt_datetime($header['MutasiRequestApprovedDate']), 0, 1, 'L');
|
|
||||||
|
|
||||||
$rightY = $pdf->GetY();
|
|
||||||
|
|
||||||
// Posisikan Y ke yang paling bawah + margin
|
|
||||||
$pdf->SetY(max($leftY, $rightY) + 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Data — Tabel detail item + ringkasan nilai
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_data($details)
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
$header = $this->_header_data;
|
|
||||||
|
|
||||||
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
|
||||||
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
|
||||||
// 8 + 80 + 20 + 20 + 25 + 27 = 180
|
|
||||||
$cols = array(
|
|
||||||
array('No', 8, 'C'),
|
|
||||||
array('Nama Item', 80, 'L'),
|
|
||||||
array('Unit', 20, 'C'),
|
|
||||||
array('Qty', 20, 'R'),
|
|
||||||
array('Nilai Buku', 25, 'R'),
|
|
||||||
array('Total', 27, 'R'),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Header kolom
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
|
||||||
$pdf->SetFillColor(220, 220, 220);
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
foreach ($cols as $c) {
|
|
||||||
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
|
||||||
}
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
// Baris data
|
|
||||||
$pdf->SetLineWidth(0.2);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
$pdf->SetFillColor(255, 255, 255);
|
|
||||||
$no = 1;
|
|
||||||
$total_val = 0;
|
|
||||||
|
|
||||||
foreach ($details as $d) {
|
|
||||||
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
|
||||||
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($d['MutasiRequestDetailQty']), 1, 0, 'R');
|
|
||||||
$bookValue = floatval($d['MutasiRequestDetailBookValue'] ?? 0);
|
|
||||||
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($bookValue), 1, 0, 'R');
|
|
||||||
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['MutasiRequestDetailQty'] * $bookValue), 1, 0, 'R');
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
$total_val += floatval($d['MutasiRequestDetailQty'] * $bookValue);
|
|
||||||
$no++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Baris TOTAL
|
|
||||||
$span = array_sum(array_column(array_slice($cols, 0, 5), 1));
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
$pdf->SetFillColor(220, 220, 220);
|
|
||||||
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
|
||||||
$pdf->Cell($cols[5][1], 7, $this->_fmt_rp($total_val), 1, 0, 'R', true);
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
$pdf->Ln(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Syarat & Ketentuan
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_terms()
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
|
|
||||||
$terms = array(
|
|
||||||
'Mutasi barang ini harus mendapatkan persetujuan dari pejabat berwenang sebelum proses mutasi dilakukan.',
|
|
||||||
'Barang yang dimutasi harus sesuai dengan spesifikasi dan jumlah yang tercantum dalam dokumen ini.',
|
|
||||||
'Proses mutasi dilakukan setelah barang diverifikasi dan disetujui oleh pihak terkait.',
|
|
||||||
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan proses mutasi barang.',
|
|
||||||
);
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
foreach ($terms as $i => $t) {
|
|
||||||
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
|
||||||
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// HELPER: Format tampilan
|
|
||||||
// =========================================================================
|
|
||||||
private function _fmt_date($d)
|
|
||||||
{
|
|
||||||
if (!$d || $d === '0000-00-00') return '-';
|
|
||||||
return date('d-m-Y', strtotime($d));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_datetime($d)
|
|
||||||
{
|
|
||||||
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
|
||||||
return date('d-m-Y H:i', strtotime($d));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_num($n)
|
|
||||||
{
|
|
||||||
return number_format(floatval($n), 2, ',', '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_qty($n)
|
|
||||||
{
|
|
||||||
return number_format(floatval($n), 0, ',', '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_rp($n)
|
|
||||||
{
|
|
||||||
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,410 +0,0 @@
|
|||||||
<?php
|
|
||||||
defined('BASEPATH') or exit('No direct script access allowed');
|
|
||||||
|
|
||||||
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
|
||||||
// =============================================================================
|
|
||||||
class RequestPengeluaranBarangFpdf extends FPDF
|
|
||||||
{
|
|
||||||
public $printUsername = '-';
|
|
||||||
public $printDate = '';
|
|
||||||
|
|
||||||
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
|
||||||
{
|
|
||||||
parent::__construct($orientation, $unit, $size);
|
|
||||||
// Daftarkan Arial Narrow
|
|
||||||
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
|
||||||
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Footer()
|
|
||||||
{
|
|
||||||
$pageW = $this->GetPageWidth() - 30; // margin 15+15
|
|
||||||
|
|
||||||
// -- Posisi: 20mm dari bawah halaman ----------------------------------
|
|
||||||
$this->SetY(-20);
|
|
||||||
|
|
||||||
// -- Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ---------------
|
|
||||||
$colSide = ($pageW - 40) / 2;
|
|
||||||
$colCenter = 40;
|
|
||||||
|
|
||||||
$this->SetFont('Arial_Narrow', '', 7);
|
|
||||||
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
|
||||||
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
|
||||||
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
|
||||||
|
|
||||||
// -- Baris 2: Tgl Print (kiri) ------------------------------------------
|
|
||||||
$this->SetFont('Arial_Narrow', '', 7);
|
|
||||||
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
|
||||||
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Controller
|
|
||||||
// =============================================================================
|
|
||||||
class Rpt_request_pengeluaran_barang extends MY_Controller
|
|
||||||
{
|
|
||||||
// -- Properti bersama antar fungsi PDF -------------------------------------
|
|
||||||
/** @var RequestPengeluaranBarangFpdf */
|
|
||||||
private $_pdf;
|
|
||||||
private $_pageW;
|
|
||||||
private $_header_data;
|
|
||||||
private $_username;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
echo "Request Pengeluaran Barang Report API";
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// ENDPOINT: pdf
|
|
||||||
// GET/POST: id (RequestItemOutID), username (opsional)
|
|
||||||
// =========================================================================
|
|
||||||
public function pdf()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$id = intval($this->input->get_post('id'));
|
|
||||||
$username = trim($this->input->get_post('username') ?? '');
|
|
||||||
|
|
||||||
if ($id <= 0) {
|
|
||||||
$this->sys_error("ID tidak valid");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Ambil data header & detail dari DB ----------------------------
|
|
||||||
$header = $this->_get_header($id);
|
|
||||||
$details = $this->_get_detail($id);
|
|
||||||
|
|
||||||
// -- Inisialisasi FPDF custom --------------------------------------
|
|
||||||
$this->_pdf = new RequestPengeluaranBarangFpdf('P', 'mm', 'A4');
|
|
||||||
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
|
||||||
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
|
||||||
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
|
||||||
$this->_header_data = $header;
|
|
||||||
$this->_username = $this->_pdf->printUsername;
|
|
||||||
|
|
||||||
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
|
||||||
$this->_pdf->SetMargins(15, 15, 15);
|
|
||||||
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
|
||||||
$this->_pdf->AddPage();
|
|
||||||
|
|
||||||
// -- Susun isi halaman ---------------------------------------------
|
|
||||||
$this->_pdf_header();
|
|
||||||
$this->_pdf_data($details);
|
|
||||||
$this->_pdf_terms();
|
|
||||||
|
|
||||||
// -- Output --------------------------------------------------------
|
|
||||||
$filename = 'RIO_' . str_replace('/', '-', $header['RequestItemOutNumber']) . '.pdf';
|
|
||||||
header('Content-Type: application/pdf');
|
|
||||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
|
||||||
header('Cache-Control: private, max-age=0, must-revalidate');
|
|
||||||
header('Pragma: public');
|
|
||||||
echo $this->_pdf->Output('S');
|
|
||||||
} catch (Exception $exc) {
|
|
||||||
$this->sys_error($exc->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// DATABASE: Ambil data header
|
|
||||||
// =========================================================================
|
|
||||||
private function _get_header($id)
|
|
||||||
{
|
|
||||||
$sql = "
|
|
||||||
SELECT
|
|
||||||
rio.*,
|
|
||||||
wh.WarehouseCode,
|
|
||||||
wh.WarehouseName,
|
|
||||||
wh.WarehouseType,
|
|
||||||
r.S_RegionalName,
|
|
||||||
d.DivisionCode,
|
|
||||||
d.DivisionName,
|
|
||||||
b.M_BranchName AS BranchName,
|
|
||||||
IFNULL(u.M_UserUsername, '') AS CreatedByName,
|
|
||||||
IFNULL(um.M_UserUsername, '') AS ManagerByName,
|
|
||||||
IFNULL(ua.M_UserUsername, '') AS ApprovedByName,
|
|
||||||
IFNULL(uv.M_UserUsername, '') AS VerifiedByName
|
|
||||||
FROM request_item_out rio
|
|
||||||
LEFT JOIN warehouse wh ON wh.WarehouseID = rio.RequestItemOutWarehouseID
|
|
||||||
AND wh.WarehouseIsActive = 'Y'
|
|
||||||
LEFT JOIN s_regional r ON r.S_RegionalID = rio.RequestItemOutS_RegionalID
|
|
||||||
AND r.S_RegionalIsActive = 'Y'
|
|
||||||
LEFT JOIN m_branch b ON b.M_BranchCode = rio.RequestItemOutM_BranchCode
|
|
||||||
AND b.M_BranchIsActive = 'Y'
|
|
||||||
LEFT JOIN division d ON d.DivisionID = rio.RequestItemOutDivisionID
|
|
||||||
AND d.DivisionIsActive = 'Y'
|
|
||||||
LEFT JOIN m_user u ON u.M_UserID = rio.RequestItemOutUserID
|
|
||||||
LEFT JOIN m_user um ON um.M_UserID = rio.RequestItemOutApprovedManagerUserID
|
|
||||||
LEFT JOIN m_user ua ON ua.M_UserID = rio.RequestItemOutApprovedUserID
|
|
||||||
LEFT JOIN m_user uv ON uv.M_UserID = rio.RequestItemOutVerifiedUserID
|
|
||||||
WHERE rio.RequestItemOutID = ?
|
|
||||||
AND rio.RequestItemOutIsActive = 'Y'
|
|
||||||
LIMIT 1
|
|
||||||
";
|
|
||||||
$qry = $this->db->query($sql, array($id));
|
|
||||||
if (!$qry || $qry->num_rows() === 0) {
|
|
||||||
$this->sys_error("Data Request Pengeluaran Barang tidak ditemukan");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
return $qry->row_array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// DATABASE: Ambil data detail
|
|
||||||
// =========================================================================
|
|
||||||
private function _get_detail($id)
|
|
||||||
{
|
|
||||||
$sql = "
|
|
||||||
SELECT
|
|
||||||
rod.*,
|
|
||||||
i.M_ItemCode,
|
|
||||||
i.M_ItemDesc,
|
|
||||||
iu.ItemUnitName,
|
|
||||||
iu.ItemUnitCode
|
|
||||||
FROM request_item_out_detail rod
|
|
||||||
LEFT JOIN m_item i ON i.M_ItemID = rod.RequestItemOutDetailM_ItemID
|
|
||||||
LEFT JOIN itemunit iu ON iu.ItemUnitID = rod.RequestItemOutDetailItemUnitID
|
|
||||||
WHERE rod.RequestItemOutDetailRequestItemOutID = ?
|
|
||||||
AND rod.RequestItemOutDetailIsActive = 'Y'
|
|
||||||
ORDER BY rod.RequestItemOutDetailID ASC
|
|
||||||
";
|
|
||||||
$qry = $this->db->query($sql, array($id));
|
|
||||||
return $qry ? $qry->result_array() : array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_header()
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
$header = $this->_header_data;
|
|
||||||
|
|
||||||
// -- Judul utama --------------------------------------------------------
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
|
||||||
$pdf->Cell($pageW, 8, 'REQUEST PENGELUARAN BARANG', 0, 1, 'L');
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
$pdf->SetLineWidth(0.5);
|
|
||||||
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
|
||||||
$pdf->Ln(2);
|
|
||||||
|
|
||||||
$startY = $pdf->GetY();
|
|
||||||
$halfW = $pageW / 2;
|
|
||||||
$lblW = 32;
|
|
||||||
$valW = $halfW - $lblW - 4;
|
|
||||||
|
|
||||||
// -- Kolom Kiri -----------------------------------------------------------
|
|
||||||
$pdf->SetY($startY);
|
|
||||||
|
|
||||||
$leftItems = array(
|
|
||||||
array('Nomor Request', $header['RequestItemOutNumber'], true),
|
|
||||||
array('Tanggal', $this->_fmt_date($header['RequestItemOutDate']), false),
|
|
||||||
array('Status', $header['RequestItemOutStatus'], false),
|
|
||||||
array('Divisi', $header['DivisionName'] ?: '-', false),
|
|
||||||
array('Gudang', $header['WarehouseName'] ?: '-', false),
|
|
||||||
array('Regional', $header['S_RegionalName'] ?: '-', false),
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($leftItems as $item) {
|
|
||||||
$pdf->SetX(15);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
if ($item[2]) {
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
} else {
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
}
|
|
||||||
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keterangan (Note)
|
|
||||||
if (!empty($header['RequestItemOutNote'])) {
|
|
||||||
$pdf->SetX(15);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->MultiCell($valW, 5, $header['RequestItemOutNote'], 0, 'L');
|
|
||||||
}
|
|
||||||
$leftY = $pdf->GetY();
|
|
||||||
|
|
||||||
// -- Kolom Kanan ----------------------------------------------------------
|
|
||||||
$pdf->SetY($startY);
|
|
||||||
$rightX = 15 + $halfW;
|
|
||||||
|
|
||||||
$rightItems = array(
|
|
||||||
array('Cabang', $header['BranchName'] ?: '-'),
|
|
||||||
array('Dibuat Oleh', $header['CreatedByName'] ?: '-'),
|
|
||||||
array('Dibuat Tgl', $this->_fmt_datetime($header['RequestItemOutCreated'])),
|
|
||||||
array('Approve Manager', $header['ManagerByName'] ?: '-'),
|
|
||||||
array('Tgl Appr. Manager',$header['RequestItemOutApprovedManagerDate'] ? $this->_fmt_datetime($header['RequestItemOutApprovedManagerDate']) : '-'),
|
|
||||||
array('Disetujui Oleh', $header['ApprovedByName'] ?: '-'),
|
|
||||||
array('Tgl Disetujui', $header['RequestItemOutApprovedDate'] ? $this->_fmt_datetime($header['RequestItemOutApprovedDate']) : '-'),
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($rightItems as $item) {
|
|
||||||
$pdf->SetX($rightX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verifikasi (hanya tampil jika ada)
|
|
||||||
if (!empty($header['RequestItemOutVerifiedDate'])) {
|
|
||||||
$pdf->SetX($rightX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, 'Diverifikasi Oleh', 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($valW, 5, $header['VerifiedByName'] ?: '-', 0, 1, 'L');
|
|
||||||
|
|
||||||
$pdf->SetX($rightX);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($lblW, 5, 'Tgl Verifikasi', 0, 0, 'L');
|
|
||||||
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 9);
|
|
||||||
$pdf->Cell($valW, 5, $this->_fmt_datetime($header['RequestItemOutVerifiedDate']), 0, 1, 'L');
|
|
||||||
}
|
|
||||||
|
|
||||||
$rightY = $pdf->GetY();
|
|
||||||
|
|
||||||
// Posisikan Y ke yang paling bawah + margin
|
|
||||||
$pdf->SetY(max($leftY, $rightY) + 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Data — Tabel detail item
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_data($details)
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
|
|
||||||
// -- Definisi kolom: [label, lebar, align] -------------------------------
|
|
||||||
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
|
||||||
// 8 + 72 + 20 + 25 + 25 + 30 = 180
|
|
||||||
$cols = array(
|
|
||||||
array('No', 8, 'C'),
|
|
||||||
array('Nama Item', 72, 'L'),
|
|
||||||
array('Unit', 20, 'C'),
|
|
||||||
array('Qty Request', 25, 'R'),
|
|
||||||
array('Qty Diterima', 25, 'R'),
|
|
||||||
array('Status', 30, 'C'),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Header kolom
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
|
||||||
$pdf->SetFillColor(220, 220, 220);
|
|
||||||
$pdf->SetDrawColor(0, 0, 0);
|
|
||||||
foreach ($cols as $c) {
|
|
||||||
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
|
||||||
}
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
// Baris data
|
|
||||||
$pdf->SetLineWidth(0.2);
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
$pdf->SetFillColor(255, 255, 255);
|
|
||||||
$no = 1;
|
|
||||||
$total_qty = 0;
|
|
||||||
$total_recv = 0;
|
|
||||||
|
|
||||||
foreach ($details as $d) {
|
|
||||||
$qty = floatval($d['RequestItemOutDetailQty'] ?? 0);
|
|
||||||
$recvQty = floatval($d['RequestItemOutDetailReceiveQty'] ?? 0);
|
|
||||||
$status = $d['RequestItemOutDetailStatus'] ?? '-';
|
|
||||||
|
|
||||||
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
|
||||||
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
|
||||||
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($qty), 1, 0, 'R');
|
|
||||||
$pdf->Cell($cols[4][1], 6, $this->_fmt_qty($recvQty), 1, 0, 'R');
|
|
||||||
$pdf->Cell($cols[5][1], 6, $status, 1, 0, 'C');
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
$total_qty += $qty;
|
|
||||||
$total_recv += $recvQty;
|
|
||||||
$no++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Baris TOTAL
|
|
||||||
$span = array_sum(array_column(array_slice($cols, 0, 3), 1));
|
|
||||||
$pdf->SetLineWidth(0.3);
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
|
||||||
$pdf->SetFillColor(220, 220, 220);
|
|
||||||
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
|
||||||
$pdf->Cell($cols[3][1], 7, $this->_fmt_qty($total_qty), 1, 0, 'R', true);
|
|
||||||
$pdf->Cell($cols[4][1], 7, $this->_fmt_qty($total_recv), 1, 0, 'R', true);
|
|
||||||
$pdf->Cell($cols[5][1], 7, '', 1, 0, 'C', true);
|
|
||||||
$pdf->Ln();
|
|
||||||
|
|
||||||
$pdf->Ln(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// PDF SECTION: Syarat & Ketentuan
|
|
||||||
// =========================================================================
|
|
||||||
private function _pdf_terms()
|
|
||||||
{
|
|
||||||
$pdf = $this->_pdf;
|
|
||||||
$pageW = $this->_pageW;
|
|
||||||
|
|
||||||
$terms = array(
|
|
||||||
'Request ini harus disetujui oleh atasan (manager) sebelum diproses lebih lanjut.',
|
|
||||||
'Barang yang diminta akan dikeluarkan sesuai dengan jumlah yang telah disetujui.',
|
|
||||||
'Apabila jumlah barang tidak tersedia, maka akan dilakukan pengeluaran sebagian (partial).',
|
|
||||||
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan administrasi perusahaan.',
|
|
||||||
);
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
|
||||||
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
|
||||||
|
|
||||||
$pdf->SetFont('Arial_Narrow', '', 8);
|
|
||||||
foreach ($terms as $i => $t) {
|
|
||||||
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
|
||||||
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
// HELPER: Format tampilan
|
|
||||||
// =========================================================================
|
|
||||||
private function _fmt_date($d)
|
|
||||||
{
|
|
||||||
if (!$d || $d === '0000-00-00') return '-';
|
|
||||||
return date('d-m-Y', strtotime($d));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_datetime($d)
|
|
||||||
{
|
|
||||||
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
|
||||||
return date('d-m-Y H:i', strtotime($d));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_num($n)
|
|
||||||
{
|
|
||||||
return number_format(floatval($n), 2, ',', '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_qty($n)
|
|
||||||
{
|
|
||||||
return number_format(floatval($n), 0, ',', '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _fmt_rp($n)
|
|
||||||
{
|
|
||||||
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user