<?php
class eventclass_journal_entry  extends TableEventsBase {
	
	function init() {
		$this->events = array(
	'BeforeEdit' => true,
	'BeforeDelete' => true,
	'BeforeAdd' => true,
	'OnPageLoad' => true,
	'AfterAdd' => true,
	'AfterEdit' => true 
);
		$this->fieldValues = array(
	'filterLimit' => array(
		 
	),
	'mapIcon' => array(
		 
	),
	'viewCustom' => array(
		 
	),
	'lookupWhere' => array(
		 
	),
	'viewFileText' => array(
		 
	),
	'defaultValue' => array(
		'exchange_rate' => array(
			'edit' => true 
		),
		'total_debit' => array(
			'edit' => true 
		),
		'total_credit' => array(
			'edit' => true 
		) 
	),
	'autoUpdateValue' => array(
		 
	),
	'uploadFolder' => array(
		 
	),
	'viewPluginInit' => array(
		 
	),
	'editPluginInit' => array(
		 
	) 
);
			}
		function BeforeEdit( &$values, &$sqlValues, $where, &$oldvalues, &$keys, &$message, $inline, $pageObject ) {
		// BuildLedger Finance - Journal Entry Before Edit
// Protects posted journals and preserves required system fields.

/* ============================================================
   Get Journal Entry ID
   ============================================================ */

$journalEntryId = 0;

if (!empty($keys["id"])) {
    $journalEntryId = (int)$keys["id"];
} elseif (!empty($oldvalues["id"])) {
    $journalEntryId = (int)$oldvalues["id"];
}

if ($journalEntryId <= 0) {
    $message = "Journal entry ID is missing.";
    return false;
}

/* ============================================================
   Posted Journal Header Lock
   ============================================================ */

$currentPostingStatus = "";

if (!empty($oldvalues["posting_status"])) {
    $currentPostingStatus = strtoupper($oldvalues["posting_status"]);
} else {

    $rsJournal = DB::Query("
        SELECT posting_status
        FROM journal_entry
        WHERE id = " . $journalEntryId . "
        LIMIT 1
    ");

    $journal = $rsJournal->fetchAssoc();

    if ($journal && !empty($journal["posting_status"])) {
        $currentPostingStatus = strtoupper($journal["posting_status"]);
    }
}

if ($currentPostingStatus == "POSTED") {
    $message = "This journal entry is already posted. You cannot edit it. Use reversal instead.";
    return false;
}

/* ============================================================
   Preserve System Fields
   ============================================================ */

if (!empty($oldvalues["journal_uuid"])) {
    $values["journal_uuid"] = $oldvalues["journal_uuid"];
}

if (!empty($oldvalues["journal_no"])) {
    $values["journal_no"] = $oldvalues["journal_no"];
}

if (!empty($oldvalues["company_id"])) {
    $values["company_id"] = $oldvalues["company_id"];
} else {

    $companyId = 0;

    if (!empty($_SESSION["company_id"])) {
        $companyId = (int)$_SESSION["company_id"];
    } elseif (!empty($values["company_id"])) {
        $companyId = (int)$values["company_id"];
    } elseif (!empty($values["branch_id"])) {

        $branchId = (int)$values["branch_id"];

        $rsBranch = DB::Query("
            SELECT company_id
            FROM branch
            WHERE id = " . $branchId . "
            LIMIT 1
        ");

        $branch = $rsBranch->fetchAssoc();

        if ($branch && !empty($branch["company_id"])) {
            $companyId = (int)$branch["company_id"];
        }
    }

    if ($companyId <= 0) {
        $companyId = 1;
    }

    $values["company_id"] = $companyId;
}

// Preserve created_by_platform_user_id.
// If old record is missing it, fix it using current session/fallback.
if (!empty($oldvalues["created_by_platform_user_id"])) {
    $values["created_by_platform_user_id"] = $oldvalues["created_by_platform_user_id"];
} else {

    $currentPlatformUserId = 0;

    if (!empty($_SESSION["platform_user_id"])) {
        $currentPlatformUserId = (int)$_SESSION["platform_user_id"];
    } elseif (!empty($_SESSION["UserID"]) && is_numeric($_SESSION["UserID"])) {
        $currentPlatformUserId = (int)$_SESSION["UserID"];
    }

    if ($currentPlatformUserId <= 0) {
        $currentPlatformUserId = 1;
    }

    $values["created_by_platform_user_id"] = $currentPlatformUserId;
}

// Preserve source fields
$values["source_transaction_type"] = $oldvalues["source_transaction_type"];
$values["source_transaction_id"] = $oldvalues["source_transaction_id"];
$values["source_transaction_uuid"] = $oldvalues["source_transaction_uuid"];

// Do not allow manual posting from Edit page
$values["posting_status"] = !empty($oldvalues["posting_status"])
    ? $oldvalues["posting_status"]
    : "UNPOSTED";

// Preserve approval status unless currently blank
if (!empty($oldvalues["approval_status"])) {
    $values["approval_status"] = $oldvalues["approval_status"];
} else {
    $values["approval_status"] = "NOT_SUBMITTED";
}

// Preserve posted audit fields
$values["posted_by_platform_user_id"] = $oldvalues["posted_by_platform_user_id"];
$values["posted_at"] = $oldvalues["posted_at"];

/* ============================================================
   Required Header Fields
   ============================================================ */

if (empty($values["accounting_period_id"])) {
    $values["accounting_period_id"] = $oldvalues["accounting_period_id"];
}

if (empty($values["accounting_period_id"])) {
    $message = "Accounting period is required.";
    return false;
}

if (empty($values["journal_date"])) {
    $message = "Journal date is required.";
    return false;
}

if (empty($values["journal_type"])) {
    $values["journal_type"] = !empty($oldvalues["journal_type"])
        ? $oldvalues["journal_type"]
        : "MANUAL";
}

if (empty($values["currency_code"])) {
    $values["currency_code"] = !empty($oldvalues["currency_code"])
        ? $oldvalues["currency_code"]
        : "PHP";
}

if (empty($values["exchange_rate"]) || (float)$values["exchange_rate"] <= 0) {
    $values["exchange_rate"] = !empty($oldvalues["exchange_rate"])
        ? $oldvalues["exchange_rate"]
        : 1;
}

/* ============================================================
   Period Lock Check
   Check both old and selected/new period.
   ============================================================ */

$periodIds = array();

if (!empty($oldvalues["accounting_period_id"])) {
    $periodIds[] = (int)$oldvalues["accounting_period_id"];
}

if (!empty($values["accounting_period_id"])) {
    $periodIds[] = (int)$values["accounting_period_id"];
}

$periodIds = array_unique($periodIds);

foreach ($periodIds as $checkAccountingPeriodId) {

    if ($checkAccountingPeriodId <= 0) {
        continue;
    }

    $rsPeriod = DB::Query("
        SELECT period_status
        FROM accounting_period
        WHERE id = " . $checkAccountingPeriodId . "
        LIMIT 1
    ");

    $period = $rsPeriod->fetchAssoc();

    if (!$period) {
        $message = "Accounting period was not found.";
        return false;
    }

    if (strtoupper($period["period_status"]) == "CLOSED") {
        $message = "This accounting period is already closed. You cannot edit transactions in this period.";
        return false;
    }
}

/* ============================================================
   Protect Auto-Computed Totals
   Totals should come from journal_entry_detail.
   ============================================================ */

unset($values["total_debit"]);
unset($values["total_credit"]);

return true;
		;
		return true;
	}

	function BeforeDelete( $where, &$deleted_values, &$message, $pageObject ) {
		/* ============================================================
   BuildLedger Finance - Journal Entry Before Delete
   Prevent delete if posted or period is closed
   ============================================================ */

$journalEntryId = 0;

if (!empty($deleted_values["id"])) {
    $journalEntryId = (int)$deleted_values["id"];
}

if ($journalEntryId <= 0) {
    $message = "Journal entry ID is missing.";
    return false;
}

/* ============================================================
   Check journal header
   ============================================================ */

$rsJournal = DB::Query("
    SELECT
        id,
        accounting_period_id,
        posting_status
    FROM journal_entry
    WHERE id = " . $journalEntryId . "
    LIMIT 1
");

$journal = $rsJournal->fetchAssoc();

if (!$journal) {
    $message = "Journal entry was not found.";
    return false;
}

/* ============================================================
   Block deleting posted journal entry
   ============================================================ */

if (strtoupper($journal["posting_status"]) == "POSTED") {
    $message = "This journal entry is already posted. You cannot delete it. Use reversal instead.";
    return false;
}

/* ============================================================
   Block deleting journal entry in closed period
   ============================================================ */

$accountingPeriodId = (int)$journal["accounting_period_id"];

if ($accountingPeriodId > 0) {

    $rsPeriod = DB::Query("
        SELECT period_status
        FROM accounting_period
        WHERE id = " . $accountingPeriodId . "
        LIMIT 1
    ");

    $period = $rsPeriod->fetchAssoc();

    if (!$period) {
        $message = "Accounting period was not found.";
        return false;
    }

    if (strtoupper($period["period_status"]) == "CLOSED") {
        $message = "This accounting period is already closed. You cannot delete this journal entry.";
        return false;
    }
}

return true;
		;
		return true;
	}

	function BeforeAdd( &$values, &$sqlValues, &$message, $inline, $pageObject ) {
		// BuildLedger Finance - Journal Entry Before Add
// Ensures required system fields are always populated.

/* ============================================================
   UUID
   ============================================================ */

if (empty($values["journal_uuid"])) {
    $rsUuid = DB::Query("SELECT UUID() AS uuid");
    $uuidData = $rsUuid->fetchAssoc();
    $values["journal_uuid"] = $uuidData["uuid"];
}

/* ============================================================
   Current platform user
   created_by_platform_user_id is NOT NULL
   ============================================================ */

$currentPlatformUserId = 0;

if (!empty($_SESSION["platform_user_id"])) {
    $currentPlatformUserId = (int)$_SESSION["platform_user_id"];
} elseif (!empty($_SESSION["UserID"]) && is_numeric($_SESSION["UserID"])) {
    $currentPlatformUserId = (int)$_SESSION["UserID"];
}

// Local fallback for development/testing
if ($currentPlatformUserId <= 0) {
    $currentPlatformUserId = 1;
}

$values["created_by_platform_user_id"] = $currentPlatformUserId;

/* ============================================================
   Company and Branch
   company_id is NOT NULL
   ============================================================ */

$companyId = 0;

if (!empty($_SESSION["company_id"])) {
    $companyId = (int)$_SESSION["company_id"];
} elseif (!empty($values["company_id"])) {
    $companyId = (int)$values["company_id"];
}

// If branch is selected, use its company_id
if ($companyId <= 0 && !empty($values["branch_id"])) {

    $branchId = (int)$values["branch_id"];

    $rsBranch = DB::Query("
        SELECT company_id
        FROM branch
        WHERE id = " . $branchId . "
        LIMIT 1
    ");

    $branch = $rsBranch->fetchAssoc();

    if ($branch && !empty($branch["company_id"])) {
        $companyId = (int)$branch["company_id"];
    }
}

// Fallback to first active company
if ($companyId <= 0) {

    $rsCompany = DB::Query("
        SELECT id
        FROM company
        WHERE status = 'ACTIVE'
        ORDER BY id
        LIMIT 1
    ");

    $company = $rsCompany->fetchAssoc();

    if ($company && !empty($company["id"])) {
        $companyId = (int)$company["id"];
    }
}

// Final local fallback
if ($companyId <= 0) {
    $companyId = 1;
}

$values["company_id"] = $companyId;

// Branch fallback from session
if (empty($values["branch_id"]) && !empty($_SESSION["branch_id"])) {
    $values["branch_id"] = (int)$_SESSION["branch_id"];
}

/* ============================================================
   Required Header Fields
   ============================================================ */

if (empty($values["accounting_period_id"])) {
    $message = "Accounting period is required.";
    return false;
}

if (empty($values["journal_date"])) {
    $values["journal_date"] = date("Y-m-d");
}

if (empty($values["journal_type"])) {
    $values["journal_type"] = "MANUAL";
}

if (empty($values["currency_code"])) {
    $values["currency_code"] = "PHP";
}

if (empty($values["exchange_rate"]) || (float)$values["exchange_rate"] <= 0) {
    $values["exchange_rate"] = 1;
}

/* ============================================================
   Period Lock Check
   ============================================================ */

$checkAccountingPeriodId = (int)$values["accounting_period_id"];

$rsPeriod = DB::Query("
    SELECT period_status
    FROM accounting_period
    WHERE id = " . $checkAccountingPeriodId . "
    LIMIT 1
");

$period = $rsPeriod->fetchAssoc();

if (!$period) {
    $message = "Accounting period was not found.";
    return false;
}

if (strtoupper($period["period_status"]) == "CLOSED") {
    $message = "This accounting period is already closed. You cannot add transactions in this period.";
    return false;
}

/* ============================================================
   Journal Number
   ============================================================ */

if (empty($values["journal_no"])) {
    $values["journal_no"] = "MJ-" . date("YmdHis") . "-" . mt_rand(100, 999);
}

/* ============================================================
   Default Status and Totals
   ============================================================ */

$values["approval_status"] = "NOT_SUBMITTED";
$values["posting_status"] = "UNPOSTED";

if (empty($values["total_debit"])) {
    $values["total_debit"] = 0;
}

if (empty($values["total_credit"])) {
    $values["total_credit"] = 0;
}

return true;
		;
		return true;
	}

	function AfterAdd( &$values, &$keys, $inline, $pageObject ) {
		/* ============================================================
   BuildLedger Finance - Recompute Journal Totals After Header Add
   ============================================================ */

$journalEntryId = 0;

if (!empty($keys["id"])) {
    $journalEntryId = (int)$keys["id"];
} elseif (!empty($values["id"])) {
    $journalEntryId = (int)$values["id"];
}

if ($journalEntryId > 0) {
    DB::Exec("
        UPDATE journal_entry je
        LEFT JOIN (
            SELECT
                journal_entry_id,
                COALESCE(SUM(debit_amount), 0) AS total_debit,
                COALESCE(SUM(credit_amount), 0) AS total_credit
            FROM journal_entry_detail
            WHERE journal_entry_id = " . $journalEntryId . "
            GROUP BY journal_entry_id
        ) d ON d.journal_entry_id = je.id
        SET
            je.total_debit = COALESCE(d.total_debit, 0),
            je.total_credit = COALESCE(d.total_credit, 0)
        WHERE je.id = " . $journalEntryId . "
    ");
}
		;
		
	}

	function AfterEdit( &$values, $where, &$oldvalues, &$keys, $inline, $pageObject ) {
		/* ============================================================
   BuildLedger Finance - Recompute Journal Totals After Header Edit
   ============================================================ */

$journalEntryId = 0;

if (!empty($keys["id"])) {
    $journalEntryId = (int)$keys["id"];
} elseif (!empty($oldvalues["id"])) {
    $journalEntryId = (int)$oldvalues["id"];
} elseif (!empty($values["id"])) {
    $journalEntryId = (int)$values["id"];
}

if ($journalEntryId > 0) {
    DB::Exec("
        UPDATE journal_entry je
        LEFT JOIN (
            SELECT
                journal_entry_id,
                COALESCE(SUM(debit_amount), 0) AS total_debit,
                COALESCE(SUM(credit_amount), 0) AS total_credit
            FROM journal_entry_detail
            WHERE journal_entry_id = " . $journalEntryId . "
            GROUP BY journal_entry_id
        ) d ON d.journal_entry_id = je.id
        SET
            je.total_debit = COALESCE(d.total_debit, 0),
            je.total_credit = COALESCE(d.total_credit, 0)
        WHERE je.id = " . $journalEntryId . "
    ");
}
		;
		
	}
	public function default_exchange_rate_efedit(  ) {
	$defaultValue = 1;
return $defaultValue;
}

public function default_total_debit_efedit(  ) {
	$defaultValue = 0;
return $defaultValue;
}

public function default_total_credit_efedit(  ) {
	$defaultValue = 0;
return $defaultValue;
}	

}


?>