add pembuatan jurnal pi cicilan order asset
This commit is contained in:
@@ -0,0 +1,432 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* JurnalPiCicilanOrderAset
|
||||
*
|
||||
* Endpoint scheduler untuk membuat jurnal PI cicilan order aset.
|
||||
* Controller ini dibuat agar bisa dipanggil via cURL dari proses generator.
|
||||
*/
|
||||
class JurnalPiCicilanOrderAset extends MY_Controller
|
||||
{
|
||||
var $db;
|
||||
|
||||
public function index()
|
||||
{
|
||||
echo "Jurnal PI Cicilan Order Aset";
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
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 = isset($para["userID"]) ? (int) $para["userID"] : 0;
|
||||
$jurnalNo = $this->generateJournalNumber();
|
||||
if ($jurnalNo === false || $jurnalNo == "") {
|
||||
throw new Exception("Gagal generate nomor jurnal.");
|
||||
}
|
||||
|
||||
$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) {
|
||||
throw new Exception("Nilai debit/credit tidak boleh negatif pada detail ke-" . ($idx + 1));
|
||||
}
|
||||
$totalDebit += $debit;
|
||||
$totalCredit += $credit;
|
||||
}
|
||||
|
||||
if (round($totalDebit, 2) !== round($totalCredit, 2)) {
|
||||
throw new Exception("Total debit dan credit harus sama. Debit={$totalDebit}, Credit={$totalCredit}");
|
||||
}
|
||||
|
||||
$this->db->trans_begin();
|
||||
|
||||
$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.");
|
||||
exit;
|
||||
}
|
||||
|
||||
$jurnalID = $this->db->insert_id();
|
||||
$createdAddonCount = 0;
|
||||
|
||||
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));
|
||||
exit;
|
||||
}
|
||||
|
||||
$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));
|
||||
exit;
|
||||
}
|
||||
|
||||
$jurnalTxID = $this->db->insert_id();
|
||||
|
||||
$addonValue = isset($detail["addonValue"]) ? trim($detail["addonValue"]) : "";
|
||||
$mItemID = isset($detail["mItemID"]) ? (int) $detail["mItemID"] : 0;
|
||||
$addonCode = isset($detail["addonCode"]) && $detail["addonCode"] != "" ? trim($detail["addonCode"]) : "PICICIL";
|
||||
|
||||
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));
|
||||
exit;
|
||||
}
|
||||
$createdAddonCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->db->trans_status() === false) {
|
||||
$this->db->trans_rollback();
|
||||
$this->sys_error_db("Transaksi jurnal gagal.");
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->db->trans_commit();
|
||||
|
||||
$this->sys_ok([
|
||||
"jurnalID" => $jurnalID,
|
||||
"jurnalNo" => $jurnalNo,
|
||||
"detailCount" => count($details),
|
||||
"addonCount" => $createdAddonCount
|
||||
]);
|
||||
} catch (Exception $exc) {
|
||||
$this->sys_error($exc->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function CreatePiInstallmentJournal()
|
||||
{
|
||||
$this->CreateJournal();
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
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"];
|
||||
}
|
||||
|
||||
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"];
|
||||
}
|
||||
|
||||
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"];
|
||||
}
|
||||
|
||||
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"];
|
||||
}
|
||||
|
||||
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"];
|
||||
}
|
||||
|
||||
private function getEligiblePurchaseOrderAssetContracts($startDate, $endDate)
|
||||
{
|
||||
$sql = "SELECT
|
||||
c.PurchaseOrderAssetContractID,
|
||||
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,
|
||||
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
|
||||
JOIN purchase_order po
|
||||
ON po.PurchaseOrderID = c.PurchaseOrderAssetContractPurchaseOrderID
|
||||
AND po.PurchaseOrderIsActive = 'Y'
|
||||
AND po.PurchaseOrderStatus = 'Approved'
|
||||
LEFT JOIN warehouse wh
|
||||
ON wh.WarehouseID = po.PurchaseOrderWarehouseID
|
||||
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
|
||||
LEFT JOIN m_branch
|
||||
ON m_branch.M_BranchID = wh.WarehouseM_BranchID
|
||||
AND m_branch.M_BranchIsActive = 'Y'
|
||||
LEFT JOIN m_branch_companydetail
|
||||
ON m_branch_companydetail.M_BranchCompanyDetailM_BranchCode = m_branch.M_BranchCode
|
||||
AND m_branch_companydetail.M_BranchCompanyDetailIsActive = 'Y'
|
||||
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
|
||||
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) <= ?
|
||||
ORDER BY c.PurchaseOrderAssetContractID ASC";
|
||||
|
||||
$qry = $this->db->query($sql, [$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();
|
||||
}
|
||||
|
||||
private function isValidDate($tanggal)
|
||||
{
|
||||
$d = DateTime::createFromFormat("Y-m-d", $tanggal);
|
||||
return $d && $d->format("Y-m-d") === $tanggal;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user