function writetrans($dtacc, $ctacc, $date, $refnum, $amount, $details)
{
    # validate input
    require_lib("validate");
    $v = new validate();
    $v->isOk($ctacc, "num", 1, 50, "Invalid Account to be Credited.");
    $v->isOk($dtacc, "num", 1, 50, "Invalid Account to be Debited.");
    $v->isOk($date, "date", 1, 14, "Invalid date.");
    $v->isOk($refnum, "num", 1, 50, "Invalid reference number.");
    $v->isOk($amount, "float", 1, 20, "Invalid Amount.");
    $v->isOk($details, "string", 0, 255, "Invalid Details.");
    # display errors, if any
    if ($v->isError()) {
        $write = "";
        $errors = $v->getErrors();
        foreach ($errors as $e) {
            $write .= "<li class=err>" . $e["msg"];
        }
        $write .= "<p><input type=button onClick='JavaScript:history.back();' value='&laquo; Correct submission'>";
        return $write;
    }
    # date format
    $date = explode("-", $date);
    $date = $date[2] . "-" . $date[1] . "-" . $date[0];
    # begin sql transaction
    # pglib_transaction ("BEGIN") or errDie("Unable to start a database transaction.",SELF);
    // Insert the records into the transect table
    db_conn(PRD_DB);
    $sql = "INSERT INTO transect(debit, credit, date, refnum, amount, author, details, div) VALUES('{$dtacc}', '{$ctacc}', '{$date}', '{$refnum}', '{$amount}', '" . USER_NAME . "', '{$details}', '" . USER_DIV . "')";
    $transRslt = db_exec($sql) or errDie("Unable to insert Transaction  details to database", SELF);
    # begin sql transaction
    # pglib_transaction ("BEGIN") or errDie("Unable to start a database transaction.",SELF);
    // Update the balances by adding appropriate values to the trial_bal Table
    core_connect();
    $ctbal = "UPDATE trial_bal SET credit = (credit + '{$amount}') WHERE accid = '{$ctacc}' AND div = '" . USER_DIV . "'";
    $dtbal = "UPDATE trial_bal SET debit = (debit + '{$amount}') WHERE accid  = '{$dtacc}' AND div = '" . USER_DIV . "'";
    $ctbalRslt = db_exec($ctbal) or errDie("Unable to update credit balance for credited account.", SELF);
    $dtbalRslt = db_exec($dtbal) or errDie("Unable to update debit balance for debited account.", SELF);
    # commit sql transaction
    # pglib_transaction ("COMMIT") or errDie("Unable to finish a database transaction.",SELF);
    ledgerCT($ctacc, $dtacc, $date, 'CREDIT', $details, $amount);
    ledgerDT($dtacc, $ctacc, $date, 'DEBIT', $details, $amount);
}
/**
 * writes a transaction into the general ledger
 *
 * @param int $dtacc debit account id
 * @param int $ctacc credit account id
 * @param string $date
 * @param int $refnum
 * @param float $amount
 * @param string $details description for ledger entry
 */
function writetrans($dtacc, $ctacc, $date, $refnum, $amount, $details)
{
    global $MONPRD, $PRDMON;
    $amount = sprint($amount);
    if ($amount < 0.01) {
        return;
    }
    # validate input
    require_lib("validate");
    $v = new validate();
    $v->isOk($ctacc, "num", 1, 50, "Invalid Account to be Credited ({$ctacc}) for transaction \"{$details}\".");
    $v->isOk($dtacc, "num", 1, 50, "Invalid Account to be Debited ({$dtacc}) for transaction \"{$details}\".");
    $v->isOk($date, "date", 1, 14, "Invalid date for transaction \"{$details}\".");
    $v->isOk($refnum, "string", 1, 50, "Invalid reference number for transaction \"{$details}\".");
    $v->isOk($amount, "float", 1, 40, "Invalid amount {$amount} for transaction \"{$details}\".");
    $details = str_replace(":", " ", $details);
    $v->isOk($details, "string", 0, 2048, "Invalid Details [{$details}].");
    # Date format
    $date = explode("-", $date);
    // $day ,$mon , $year
    if (checkdate($date[1], $date[0], $date[2])) {
        $mon = $date[1];
        $yr = $date[2];
        $date = "{$date['2']}-{$date['1']}-{$date['0']}";
        // $year, $mon, $day
    } elseif (checkdate($date[1], $date[2], $date[0])) {
        $mon = $date[1];
        $yr = $date[0];
        $date = "{$date['0']}-{$date['1']}-{$date['2']}";
    } else {
        $v->addError("", "Invalid date for transaction. " . (DEBUG > 0 ? "\"{$details}\"" : ""));
    }
    if (isset($yr)) {
        $curyr = getActiveFinYear();
        if ($yr > $curyr || $yr == $curyr && $mon > $PRDMON[12]) {
            $v->addError("", "Cannot do transaction in future financial year. " . (DEBUG > 0 ? "\"{$details}\"" : ""));
        }
    }
    if (floatval($amount) == floatval(0)) {
        return;
    }
    if ($v->isError()) {
        $OUTPUT = $v->genErrors();
        $OUTPUT .= "<p><input type='button' onclick='javascript:history.back();' value='&laquo; Correct submission'></p>";
        pglib_transaction("ROLLBACK");
        require "template.php";
    }
    if (!accExist($dtacc)) {
        $dtacc = getErrAcc();
        $details = $details . " - Debit account was not found, transaction has been posted to error account.";
        db_connect();
        $Sql = "INSERT INTO req (sender, recipient, message, timesent, viewed) VALUES ('SYSTEM', '', 'Debit account was not found for transaction with Ref No. {$refnum}, transaction has been posted to error account.', CURRENT_TIMESTAMP, 0)";
        $Rslt = db_exec($Sql) or errDie("Unable to add to database.", SELF);
    }
    if (!accExist($ctacc)) {
        $ctacc = getErrAcc();
        $details = $details . " - Credit account was not found, transaction has been posted to error account.";
        db_connect();
        $Sql = "INSERT INTO req (sender, recipient, message, timesent, viewed) VALUES ('SYSTEM', '', 'Credit account was not found for transaction with Ref No. {$refnum}, transaction has been posted to error account.', CURRENT_TIMESTAMP, 0)";
        $Rslt = db_exec($Sql) or errDie("Unable to add to database.", SELF);
    }
    # Get account information
    $dacc = getAcc($dtacc);
    $cacc = getAcc($ctacc);
    $sdate = date("Y-m-d");
    list($PRD_DB, $PRD_NAME) = getPRD($date);
    list($CUR_PRD_DB, $CUR_PRD_NAME) = getPRD(date("Y-m-d"));
    # Insert the records into the transect table
    //if (PRD_STATE != "py") {
    db_conn($PRD_DB);
    $sql = "\n\t\t\tINSERT INTO transect (\n\t\t\t\tdebit, daccname, dtopacc, daccnum , credit,\n\t\t\t\tcaccname, ctopacc, caccnum, date, refnum, \n\t\t\t\tamount, author, details, div, sdate, custom_refnum\n\t\t\t) VALUES (\n\t\t\t\t'{$dtacc}', '{$dacc['accname']}', '{$dacc['topacc']}', '{$dacc['accnum']}', '{$ctacc}', \n\t\t\t\t'{$cacc['accname']}', '{$cacc['topacc']}', '{$cacc['accnum']}', '{$date}', '" . getrefnum() . "', \n\t\t\t\t'{$amount}', '" . USER_NAME . "', '{$details}', '" . USER_DIV . "', '{$sdate}', '{$refnum}'\n\t\t\t)";
    $transRslt = db_exec($sql) or errDie("Unable to insert Transaction  details to database", SELF);
    //}
    # Update the balances by adding appropriate values to the trial_bal Table
    core_connect();
    # Begin sql transaction
    # pglib_transaction ("BEGIN") or errDie("Unable to start a database transaction.",SELF);
    if (PRD_STATE != "py") {
        $ctbal = "UPDATE trial_bal SET credit = (credit + '{$amount}')\n\t\t\t\tWHERE accid = '{$ctacc}' AND period>='{$MONPRD[$PRD_DB]}' AND div = '" . USER_DIV . "'";
        $dtbal = "UPDATE trial_bal SET debit = (debit + '{$amount}')\n\t\t\t\tWHERE accid  = '{$dtacc}' AND period>='{$MONPRD[$PRD_DB]}' AND div = '" . USER_DIV . "'";
        $ctbalRslt = db_exec($ctbal) or errDie("Unable to update credit balance for credited account.", SELF);
        $dtbalRslt = db_exec($dtbal) or errDie("Unable to update debit balance for debited account.", SELF);
    } else {
        $ctbal = "UPDATE trial_bal SET credit = (credit + '{$amount}')\n\t\t\t\tWHERE accid = '{$ctacc}' AND period<'1' AND div = '" . USER_DIV . "'";
        //FP MOVEMENT FIX
        //					AND (acctype='I' OR acctype='E')";
        $dtbal = "UPDATE trial_bal SET debit = (debit + '{$amount}')\n\t\t\t\tWHERE accid  = '{$dtacc}' AND period<'1' AND div = '" . USER_DIV . "'";
        //FP MOVEMENT FIX
        //					AND (acctype='I' OR acctype='E')";
        $ctbalRslt = db_exec($ctbal) or errDie("Unable to update credit balance for credited account.", SELF);
        $dtbalRslt = db_exec($dtbal) or errDie("Unable to update debit balance for debited account.", SELF);
    }
    if (PRD_STATE == "py") {
        db_conn(YR_DB);
        $ctbal = "UPDATE year_balance SET credit=(credit+'{$amount}') WHERE accid='{$ctacc}'";
        $dtbal = "UPDATE year_balance SET debit=(debit+'{$amount}') WHERE accid='{$dtacc}'";
        //db_exec($ctbal) or errDie("Error updating previous year balance (CT).");
        //db_exec($dtbal) or errDie("Error updating previous year balance (DT).");
    }
    # commit sql transaction
    # pglib_transaction ("COMMIT") or errDie("Unable to finish a database transaction.",SELF);
    // insert into audit db
    if (PRD_STATE == "py") {
        $audit_db = YR_NAME . "_audit";
        //		$start_prd = 1;
        //FP WHY UPDATE WHOLE OF PREVIOUS YEAR ????
        $start_prd = $MONPRD[$PRD_DB];
        $actyear = PYR_NAME;
    } else {
        $audit_db = "audit";
        $start_prd = $MONPRD[$PRD_DB];
        $actyear = YR_NAME;
    }
    db_conn($audit_db);
    $sql = "\n\t\tINSERT INTO " . $PRD_NAME . " (\n\t\t\tdebit, credit, date, refnum, amount, \n\t\t\tauthor, details, div, actyear, custom_refnum\n\t\t) VALUES (\n\t\t\t'{$dtacc}', '{$ctacc}', '{$date}', '" . getrefnum() . "', '{$amount}', \n\t\t\t'" . USER_NAME . "', '{$details}', '" . USER_DIV . "', '{$actyear}', '{$refnum}'\n\t\t)";
    $transRslt = db_exec($sql) or errDie("Unable to insert Transaction  details to database", SELF);
    if (true || $MONPRD[$PRD_DB] < $MONPRD[$CUR_PRD_DB]) {
        for ($iPRD = $start_prd; $iPRD <= 12; ++$iPRD) {
            //print "wt: $iPRD - $PRDMON[$iPRD] - $PRD_DB<Br>";
            $iPRD_NAME = date("F", mktime(0, 0, 0, $PRDMON[$iPRD], 1, 2000));
            db_conn(YR_DB);
            $ctbal = "UPDATE " . $iPRD_NAME . " SET credit = (credit + '{$amount}') WHERE accid = '{$ctacc}' AND div = '" . USER_DIV . "'";
            $dtbal = "UPDATE " . $iPRD_NAME . " SET debit = (debit + '{$amount}') WHERE accid  = '{$dtacc}' AND div = '" . USER_DIV . "'";
            $ctbalRslt = db_exec($ctbal) or errDie("Unable to update credit balance for credited account.", SELF);
            $dtbalRslt = db_exec($dtbal) or errDie("Unable to update debit balance for debited account.", SELF);
        }
        # Update opening balances for current period
        if (PRD_STATE != "py") {
            db_conn($CUR_PRD_DB);
            $ctbal = "UPDATE openbal SET credit = (credit + '{$amount}') WHERE accid = '{$ctacc}' AND div = '" . USER_DIV . "'";
            $dtbal = "UPDATE openbal SET debit = (debit + '{$amount}') WHERE accid  = '{$dtacc}' AND div = '" . USER_DIV . "'";
            $ctbalRslt = db_exec($ctbal) or errDie("Unable to update credit balance for credited account.", SELF);
            $dtbalRslt = db_exec($dtbal) or errDie("Unable to update debit balance for debited account.", SELF);
        }
    }
    //errDie("done");
    if (PRD_STATE != "py") {
        # Record vat transactions
        core_connect();
        $sql = "SELECT accnum FROM salesacc WHERE name = 'VATIN' AND div = '" . USER_DIV . "'";
        $vatRslt = db_exec($sql);
        if (pg_numrows($vatRslt) > 0) {
            $vat = pg_fetch_array($vatRslt);
            $vatacc = $vat['accnum'];
            if ($vatacc == $ctacc) {
                db_connect();
                $sql = "INSERT INTO vatrec (edate, ref, amount, descript, div,chrgvat) VALUES ('{$date}', '{$refnum}', '{$amount}', 'VAT : {$details}', '" . USER_DIV . "', 'VATIN')";
                $stmntRslt = db_exec($sql) or errDie("Unable to insert statement record in Cubit.", SELF);
            } elseif ($vatacc == $dtacc) {
                db_connect();
                $sql = "INSERT INTO vatrec(edate, ref, amount, descript, div,chrgvat) VALUES('{$date}', '{$refnum}', '-{$amount}', 'VAT : {$details}', '" . USER_DIV . "','VATIN')";
                $stmntRslt = db_exec($sql) or errDie("Unable to insert statement record in Cubit.", SELF);
            }
        }
        core_connect();
        $sql = "SELECT accnum FROM salesacc WHERE name = 'VATOUT' AND div = '" . USER_DIV . "'";
        $vatRslt = db_exec($sql);
        if (pg_numrows($vatRslt) > 0) {
            $vat = pg_fetch_array($vatRslt);
            $vatacc = $vat['accnum'];
            if ($vatacc == $ctacc) {
                db_connect();
                $sql = "INSERT INTO vatrec(edate, ref, amount, descript, div,chrgvat) VALUES('{$date}', '{$refnum}', '{$amount}', 'VAT : {$details}', '" . USER_DIV . "','VATOUT')";
                $stmntRslt = db_exec($sql) or errDie("Unable to insert statement record in Cubit.", SELF);
            } elseif ($vatacc == $dtacc) {
                db_connect();
                $sql = "INSERT INTO vatrec(edate, ref, amount, descript, div,chrgvat) VALUES('{$date}', '{$refnum}', '-{$amount}', 'VAT : {$details}', '" . USER_DIV . "','VATOUT')";
                $stmntRslt = db_exec($sql) or errDie("Unable to insert statement record in Cubit.", SELF);
            }
        }
    }
    if (PRD_STATE == "py") {
        ledgerCT_py($ctacc, $dtacc, $date, $refnum, $details, $amount);
        ledgerDT_py($dtacc, $ctacc, $date, $refnum, $details, $amount);
        writetrans_update_py($dtacc, $ctacc, $amount, $PRD_DB);
    }
    ledgerCT($ctacc, $dtacc, $date, $refnum, $details, $amount);
    ledgerDT($dtacc, $ctacc, $date, $refnum, $details, $amount);
    $vatacc1 = gethook("accnum", "salesacc", "name", "VAT", "VAT");
}