<?php
class eventclass_journal_entry_detail  extends TableEventsBase {
	
	function init() {
		$this->events = array(
	'BeforeAdd' => true,
	'BeforeEdit' => true,
	'BeforeDelete' => true,
	'AfterAdd' => true,
	'AfterEdit' => true,
	'AfterDelete' => true 
);
		$this->fieldValues = array(
	'filterLimit' => array(
		 
	),
	'mapIcon' => array(
		 
	),
	'viewCustom' => array(
		 
	),
	'lookupWhere' => array(
		 
	),
	'viewFileText' => array(
		 
	),
	'defaultValue' => array(
		 
	),
	'autoUpdateValue' => array(
		 
	),
	'uploadFolder' => array(
		 
	),
	'viewPluginInit' => array(
		 
	),
	'editPluginInit' => array(
		 
	) 
);
			}
		function BeforeAdd( &$values, &$sqlValues, &$message, $inline, $pageObject ) {
		/* ============================================================
   BuildLedger Finance - Journal Entry Detail Before Add
   Auto line number + validation
   ============================================================ */

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

/* Required parent header */
if (empty($values["journal_entry_id"])) {
    $message = "Journal entry header is missing.";
    return false;
}

$journalEntryId = (int)$values["journal_entry_id"];

/* Required account */
if (empty($values["account_id"])) {
    $message = "Please select an account.";
    return false;
}

$values["account_id"] = (int)$values["account_id"];

/* ============================================================
   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;
}

if (strtoupper($journal["posting_status"]) == "POSTED") {
    $message = "Cannot add lines to a posted journal entry.";
    return false;
}

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

$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 add journal detail lines.";
        return false;
    }
}

/* ============================================================
   Auto Line Number
   Important: line_no must not be typeable by user
   ============================================================ */

if (empty($values["line_no"]) || (int)$values["line_no"] <= 0) {
    $rsLine = DB::Query("
        SELECT COALESCE(MAX(line_no), 0) + 1 AS next_line_no
        FROM journal_entry_detail
        WHERE journal_entry_id = " . $journalEntryId . "
    ");

    $lineData = $rsLine->fetchAssoc();
    $values["line_no"] = (int)$lineData["next_line_no"];
}

/* ============================================================
   Clean Amounts
   ============================================================ */

$values["debit_amount"] = !empty($values["debit_amount"])
    ? round((float)str_replace(",", "", $values["debit_amount"]), 4)
    : 0;

$values["credit_amount"] = !empty($values["credit_amount"])
    ? round((float)str_replace(",", "", $values["credit_amount"]), 4)
    : 0;

$values["foreign_debit_amount"] = !empty($values["foreign_debit_amount"])
    ? round((float)str_replace(",", "", $values["foreign_debit_amount"]), 4)
    : 0;

$values["foreign_credit_amount"] = !empty($values["foreign_credit_amount"])
    ? round((float)str_replace(",", "", $values["foreign_credit_amount"]), 4)
    : 0;

/* ============================================================
   Validate Debit / Credit
   ============================================================ */

if ($values["debit_amount"] <= 0 && $values["credit_amount"] <= 0) {
    $message = "Please enter either Debit or Credit amount.";
    return false;
}

if ($values["debit_amount"] > 0 && $values["credit_amount"] > 0) {
    $message = "A journal line cannot have both Debit and Credit amount. Please enter only one side.";
    return false;
}

return true;
		;
		return true;
	}

	function BeforeEdit( &$values, &$sqlValues, $where, &$oldvalues, &$keys, &$message, $inline, $pageObject ) {
		/* ============================================================
   BuildLedger Finance - Journal Entry Detail Before Edit
   Prevent edit if parent journal is posted or period is closed
   ============================================================ */

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

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

$journalEntryId = (int)$values["journal_entry_id"];

/* ============================================================
   Check parent journal
   ============================================================ */

$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;
}

if (strtoupper($journal["posting_status"]) == "POSTED") {
    $message = "Cannot edit lines of a posted journal entry.";
    return false;
}

/* ============================================================
   Period lock check
   ============================================================ */

$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 edit journal detail lines.";
        return false;
    }
}

/* ============================================================
   Preserve line no if hidden / empty
   ============================================================ */

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

/* ============================================================
   Required account
   ============================================================ */

if (empty($values["account_id"])) {
    $message = "Please select an account.";
    return false;
}

$values["account_id"] = (int)$values["account_id"];

/* ============================================================
   Clean and validate amounts
   ============================================================ */

$values["debit_amount"] = !empty($values["debit_amount"])
    ? round((float)$values["debit_amount"], 4)
    : 0;

$values["credit_amount"] = !empty($values["credit_amount"])
    ? round((float)$values["credit_amount"], 4)
    : 0;

if ($values["debit_amount"] <= 0 && $values["credit_amount"] <= 0) {
    $message = "Please enter either Debit or Credit amount.";
    return false;
}

if ($values["debit_amount"] > 0 && $values["credit_amount"] > 0) {
    $message = "A journal line cannot have both Debit and Credit amount. Please enter only one side.";
    return false;
}

$values["foreign_debit_amount"] = !empty($values["foreign_debit_amount"])
    ? round((float)$values["foreign_debit_amount"], 4)
    : 0;

$values["foreign_credit_amount"] = !empty($values["foreign_credit_amount"])
    ? round((float)$values["foreign_credit_amount"], 4)
    : 0;

return true;
		;
		return true;
	}

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

if (empty($deleted_values["journal_entry_id"])) {
    $message = "Journal entry header is missing.";
    return false;
}

$journalEntryId = (int)$deleted_values["journal_entry_id"];

/* ============================================================
   Check parent journal
   ============================================================ */

$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;
}

if (strtoupper($journal["posting_status"]) == "POSTED") {
    $message = "Cannot delete lines of a posted journal entry.";
    return false;
}

/* ============================================================
   Period lock check
   ============================================================ */

$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 journal detail lines.";
        return false;
    }
}

return true;
		;
		return true;
	}

	function AfterAdd( &$values, &$keys, $inline, $pageObject ) {
		/* ============================================================
   BuildLedger Finance - Recompute Journal Entry Totals
   For journal_entry_detail After Add/Edit/Delete
   ============================================================ */

$journalEntryId = 0;

if (isset($values) && !empty($values["journal_entry_id"])) {
    $journalEntryId = (int)$values["journal_entry_id"];
}

if ($journalEntryId <= 0 && isset($oldvalues) && !empty($oldvalues["journal_entry_id"])) {
    $journalEntryId = (int)$oldvalues["journal_entry_id"];
}

if ($journalEntryId <= 0 && isset($deleted_values) && !empty($deleted_values["journal_entry_id"])) {
    $journalEntryId = (int)$deleted_values["journal_entry_id"];
}

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

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

$journalEntryId = 0;

if (isset($values) && !empty($values["journal_entry_id"])) {
    $journalEntryId = (int)$values["journal_entry_id"];
}

if ($journalEntryId <= 0 && isset($oldvalues) && !empty($oldvalues["journal_entry_id"])) {
    $journalEntryId = (int)$oldvalues["journal_entry_id"];
}

if ($journalEntryId <= 0 && isset($deleted_values) && !empty($deleted_values["journal_entry_id"])) {
    $journalEntryId = (int)$deleted_values["journal_entry_id"];
}

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

	function AfterDelete( $where, &$deleted_values, &$message, $pageObject ) {
		/* ============================================================
   BuildLedger Finance - Recompute Journal Entry Totals
   For journal_entry_detail After Add/Edit/Delete
   ============================================================ */

$journalEntryId = 0;

if (isset($values) && !empty($values["journal_entry_id"])) {
    $journalEntryId = (int)$values["journal_entry_id"];
}

if ($journalEntryId <= 0 && isset($oldvalues) && !empty($oldvalues["journal_entry_id"])) {
    $journalEntryId = (int)$oldvalues["journal_entry_id"];
}

if ($journalEntryId <= 0 && isset($deleted_values) && !empty($deleted_values["journal_entry_id"])) {
    $journalEntryId = (int)$deleted_values["journal_entry_id"];
}

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

}


?>