1 (edited by albertolima 09/14/2016 06:44:05 pm)

Topic: Providing fix for Import Multiple Journal Entries module in v2.4rc1

Hi BB'ers,

I tried running the Import Multiple Journal Entries module on v2.4rc1.
It just wouldn't show anything after importing.
By enabling debug mode on the module file, I could see a php error on line 163, the module was using the function exists in /include/references.inc, which is now deprecated in v2.4rc1.

Error: Call to undefined method references::exists() in /var/www/html/fa24/modules/import_multijournalentries/import_multijournalentries.php on line 163

I have changed the code line to use the new function is_new_reference, in the new /include/references.inc file.
So this is the change to apply in order to get it running:

On line 163, file /modules/import_multijournalentries/import_multijournalentries.php, remove line:

if $Refs->exists($type, $reference)) {

And insert this line:

if (!($Refs->is_new_reference($reference,$type))) {

After that, you may import using multiple journal entries module.

I'll report this on Mantis to be updated on future versions of FA.

Rgds.
AL.

Committed.

Re: Providing fix for Import Multiple Journal Entries module in v2.4rc1

I have modified import_multiplejournalentries.php to add Journal Entries for Customers and Suppliers

<?php
/**********************************************
Author: Tom Hallman
Name: Import Multiple Journal Entries/Deposits/Payments v2.3
Free software under GNU GPL
***********************************************/
$page_security = 'SA_CSVMULTIJOURNALIMPORT';
$path_to_root="../..";

include_once($path_to_root . "/includes/ui/items_cart.inc");
include_once($path_to_root . "/gl/includes/db/gl_db_trans.inc");
include_once($path_to_root . "/includes/session.inc");
add_access_extensions();

// Turn these next two lines on for debugging
//error_reporting(E_ALL);
//ini_set("display_errors", "on");

//--------------------------------------------------------------------------------------------------

function init_entry(&$entry,$type,$date,$reference) // See gl/gl_journal::create_cart() & gl/gl_bank::handle_new_order()
{
    $entry = new items_cart($type);
    $entry->order_id = 0;
    $entry->tran_date = $date;
    $entry->reference = $reference;
    $entry->memo_ = 'Imported via \'Import Multiple Journal Entries\' plugin';
}

//--------------------------------------------------------------------------------------------------

function import_type_list_row($label, $name, $selected=null, $submit_on_change=false)
{
    $arr = array(
        ST_JOURNAL=> "Journal Entry",
        ST_BANKDEPOSIT=> "Deposit",
        ST_BANKPAYMENT=> "Payment"
    );

    echo "<tr><td class='label'>$label</td><td>";
    echo array_selector($name, $selected, $arr,
        array(
            'select_submit'=> $submit_on_change,
            'async' => false,
        ));
    echo "</td></tr>\n";
}

//--------------------------------------------------------------------------------------------------

function check_journal_entry(&$entry, $entryid)
{
    // Check that this journal entry adds up!
    if (abs($entry->gl_items_total()) > 0.0001)
    {
        display_error("Error: journal entry with entryid '$entryid' does not balance (import file: '{$_FILES['imp']['name']}')");
        return true;
    }
}

function write_trans($type, $entry, $curEntryId, $bank_account)
{
    if ($type == ST_JOURNAL)
    {
        if (!check_journal_entry($entry, $curEntryId));
            write_journal_entries($entry, false, false); // FA built-in function
    }
    elseif ($type == ST_BANKDEPOSIT || $type == ST_BANKPAYMENT) {
        add_bank_transaction($entry->trans_type, $bank_account, $entry, $entry->tran_date, // FA built-in function
            false, false, false, $entry->reference, $entry->memo_, false);
    }

}
//--------------------------------------------------------------------------------------------------

function get_dimension_id_from_reference($ref)
{
    if ($ref == null || trim($ref) == '')
        return 0;

    $sql = "SELECT id FROM ".TB_PREF."dimensions WHERE reference LIKE ".db_escape($ref);

    $result = db_query($sql, "could not get dimension from reference");

    $row = db_fetch_row($result);

    return $row[0];
}

//--------------------------------------------------------------------------------------------------
// Begin the UI
include_once($path_to_root . "/includes/ui.inc");

page("Import Multiple Journal Entries / Deposits / Payments");

// If the import button was selected, we'll process the form here.  (If not, skip to actual content below.)
if (isset($_POST['import']))
{
    if (isset($_FILES['imp']) && $_FILES['imp']['name'] != '')
    {
        $filename = $_FILES['imp']['tmp_name'];
        $sep = $_POST['sep'];
        $type = $_POST['type'];
        $bank_account = isset($_POST['bank_account']) ? $_POST['bank_account'] : "";

        // Open the file
        $fp = @fopen($filename, "r");
        if (!$fp)
        {
            display_error("Error opening file $filename");
        } else {

            // Initialize first entryid & date to be null so that a new one is established
            $curEntryId = $curDate = null;

            // Prepare the DB to receive the imported journal entries
            begin_transaction();

            // Process the import file
            $line = 0;
            $entryCount = 0;
            $error = false;
            $errCnt = 0;
            while ($data = fgetcsv($fp, 4096, $sep))
            {
                // Skip the first line, as it's a header
                if ($line++ == 0) continue;

                // Skip blank lines (which shouldn't happen in a well-formed CSV, but we'll be safe)
                if (count($data) == 1) continue;

                // Parse the row of data; Format: entryid,date,reference,accountcode,dimension1,dimension2,amount,memo
                list($entryid, $date, $reference, $code, $dim1_ref, $dim2_ref, $amt, $memo, $person_id) = $data;

                // If the entryid has changed, create the current journal entry (if there was one) and start a new one
                if ($entryid != $curEntryId) {

                    // Check that date is properly-formatted
                    if (!is_date($date)) {
                        display_error("Error: date '$date' not properly formatted (line $line in import file '{$_FILES['imp']['name']}')");
                        $error = true;
                    }

                    // Check that the date is in range
                    if (!is_date_in_fiscalyear($date)) {
                        display_error("Error: date not in fiscal year (line $line in import file '{$_FILES['imp']['name']}')");
                        $error = true;
                    }

                    // Assign a default reference if it is not specified
                    if ($reference == '') {
                        // If the entryid has shifted but date is the same, it needs another reference
                        if ($date == $curDate)
                            $refCount++;
                        else // else the entryid and date have shifted, so we can start with a new reference
                            $refCount = 1;
                        list($day, $month, $year) = explode_date_to_dmy($date);
                        $reference = "$month/$day-$refCount";
                    }

                    // Check that the reference is not in use
                    global $Refs;
                    if (!$Refs->is_new_reference($reference,$type)) {
                        display_error("Error: reference '$reference' is already in use (line $line in import file '{$_FILES['imp']['name']}')");
                        $error = true;
                    }

                    // All good! Initialize a new entry
                    if ($curEntryId != null) {
                        if (!$error)
                        {
                            write_trans($type, $entry, $curEntryId, $bank_account);
                            $entryCount++;
                        }
                    }
                    if ($error)
                        $errCnt++;
                    $error = false;
                    init_entry($entry,$type,$date,$reference);
                    $curEntryId = $entryid;
                    $curDate = $date;
                }

                if ($entryid == '') {
                    display_error("Error: entryid not specified (line $line in import file '{$_FILES['imp']['name']}')");
                    $error = true;
                }
                // Check that the account code exists
                if (get_gl_account($code) == null) {
                    display_error("Error: Could not find account code '$code' (line $line in import file '{$_FILES['imp']['name']}')");
                    $error = true;
                }
                // Check that dimension 1 exists
                $dim1 = get_dimension_id_from_reference($dim1_ref);
                if ($dim1_ref != '' && $dim1 == null) {
                    display_error("Error: Could not find dimension with reference '$dim1_ref' (line $line in import file '{$_FILES['imp']['name']}')");
                    $error = true;
                }
                // Check that dimension 2 exists
                $dim2 = get_dimension_id_from_reference($dim2_ref);
                if ($dim2_ref != '' && $dim2 == null) {
                    display_error("Error: Could not find dimension with reference '$dim2_ref' (line $line in import file '{$_FILES['imp']['name']}')");
                    $error = true;
                }

                if ($type == ST_BANKDEPOSIT)
                    $amt = -$amt;

                // Add to the journal entry / deposit / payment
                if (!$error)
                    $entry->add_gl_item($code, $dim1, $dim2, $amt, $memo,'',$person_id);
            }

            // Process final entries in the file
            if (!$error)
            {
                if ($curEntryId != null) {
                    write_trans($type, $entry, $curEntryId, $bank_account);
                    $entryCount++;
                }
            } else
                $errCnt++;

            @fclose($fp);

            // Commit import to database
            if (!$errCnt)
                commit_transaction();

            if ($type == ST_JOURNAL)
                $typeString = "journal entries";
            elseif ($type == ST_BANKDEPOSIT)
                $typeString = "deposits";
            elseif ($type == ST_BANKPAYMENT)
                $typeString = "payments";

            if (!$errCnt) {
                if ($entryCount > 0)
                    display_notification_centered("$entryCount $typeString have been imported.");
                else
                    display_error("Import file contained no $typeString.");
            }
        }
    }
    else
        display_error("No import file selected");
}

start_form(true);

start_table(TABLESTYLE2);

if (!isset($_POST['type']))
    $_POST['type'] = ST_JOURNAL;

if (!isset($_POST['sep']))
    $_POST['sep'] = ",";

    echo ' | ';
    echo "<a href=https://my.pakerp.net/modules/import_multijournalentries/Journal_Entry.cs>Click Here To Download Sample File For Import </a>";
    echo "<br> There should be no Comma (,) in any value in any column. Please double check before import";
    echo "<br> For Customers Opening Balance person_id shall contain debtor_no field value and code shall be Accounts Receivable Code.";
    echo "<br> For Suppliers Opening Balance person_id shall contain supplier_id field value and code shall be Accounts Payable Code.";

table_section_title("Import Settings");
import_type_list_row("Import Type:", 'type', $_POST['type'], true);
if ($_POST['type'] != ST_JOURNAL)
    bank_accounts_list_row( $_POST['type'] == ST_BANKPAYMENT ? _("From:") : _("To:"), 'bank_account', null, false);
text_row("Field Separator:", 'sep', $_POST['sep'], 2, 1);
label_row("Import File:", "<input type='file' id='imp' name='imp'>");

end_table(1);

submit_center('import', "Perform Import");//,true,false,'process',ICON_SUBMIT);

end_form();

end_page();

This is very helpful to record opening balances of all Trial Balance Accounts when shifting to FA from any other ERP.

Post's attachments

Import_MJ_Diffs.zip 7 kb, 17 downloads since 2018-05-01 

You don't have the permssions to download the attachments of this post.
www.boxygen.pk

Re: Providing fix for Import Multiple Journal Entries module in v2.4rc1

To me, importing customer/supplier (person) info into FA is deceptively simple.

1. To do this import, first one must know the person_id, which requires some kind of lookup by name.
2. By adding person_id, I am guessing that FA creates customer/supplier records.  If so, you will see these by doing customer/supplier inquiry.
3. Imported payments will have no FA invoices, so no allocations against invoices are made.
4. Thus, after the import, customer/supplier accounts will appear to have been overpaid, although the AR/AP G/L accounts should be correct.  But I would have guessed that this would have been the case even without the person_id, so I am confused at what trial balance account was fixed by adding person_id.

If this is not the case, and somehow your customer/supplier accounts appear correct after the import, you have discovered something that I do not know.

Otherwise, the question then becomes how to correct the customer/supplier accounts.  I don't have an easy answer.

A. Creating dummy customer/supplier invoices in FA may work, but I think that may double the sales and A/R G/L accounts, so may require a GJ entry to fix that.

B. What I did:

B.1. zero out the amounts in the customer trans db after the import to get zero balances. 

B.2. Double enter new payments from pre-import invoices into both FA and the old ERP.

B.3. FA payments were entered using a GJ entry against AR and the appropriate bank account so as not to affect the zero customer balance.

B.4 New invoices and payments were entered in FA and eventually the customer balances became correct.

B.5 update the suppler trans database to make all transactions allocated.

Re: Providing fix for Import Multiple Journal Entries module in v2.4rc1

I finally realized now what you are doing: importing opening balances from another ERP and dividing the AR/AP account balances into separate balances for each customer/supplier.  Thus your mod adding person_id to the import makes sense.  Future customer payments then can be applied against the AR established by the journal entry.  I tested this just to make sure it works and it does.  I am guessing that it works for AP as well.

Indeed, this approach is more intuitive than the one mentioned in the wiki and I recommend that the wiki be updated to mention this approach. 

Ignore my prior post because I was speaking to import transactions from another ERP (i.e. the entire general journal).   The problem with that style of import is that FA assigns counterparty to payments/AR but not to sales/AR, resulting in the overpaid issue as described.

Re: Providing fix for Import Multiple Journal Entries module in v2.4rc1

@Braath Waate you are right

www.boxygen.pk

Re: Providing fix for Import Multiple Journal Entries module in v2.4rc1

I want to import my opening balances for my customers, suppliers and inventory items during the current fiscal year. Utility named import multiple journal entries currently available in FA 2.4.* doesn't provide any sample csv format.

Any idea or suggestion on this.



Thanks
Usman Khan

Re: Providing fix for Import Multiple Journal Entries module in v2.4rc1

Read the docs/readme.txt in the module.