@apmuthu -  For custom header changes, we are allowing to collect from forms directory. And i am trying to bring the same feature to modules directory. I can't understand your point, How it will cause security issues.

@joe - If you think its not good practice, than lets takeout the forms directory and form files support in pdf_report.inc

We are allowing to connect custom reports. If it's giving security issues. That will also give security problems

There is a small change in the core of pdf_report.inc will  give us a good way to add template form from the module itself.

from the reporting/includes/pdf_report.inc:

function NewPage() 
    {
        global $installed_extensions, $path_to_root;
    
    
        if ($this->pageNumber==0)
        {
            // check if there is pdf header template for this report
            // and set if it is found
            $tmpl_pdf = find_custom_file("/reporting/forms/".$this->headerTmpl.".pdf");
            if ($tmpl_pdf) {
                $this->tmplSize = $this->setSourceFile($tmpl_pdf);
            } else {
                // include reports installed inside extension modules
                if (count($installed_extensions) > 0)
                {
                    $extensions = $installed_extensions;
                    foreach ($extensions as $ext)
                        if (($ext['active'] && $ext['type'] == 'extension')) {
                            $tmpl_pdf = find_custom_file($path_to_root.'/'.$ext['path']."/reporting/forms/".$this->headerTmpl.".pdf");
                            if ($tmpl_pdf) {
                                $this->tmplSize = $this->setSourceFile($tmpl_pdf);
                            }
                        }
                }
            }
        }

        $this->pageNumber++;
        parent::newPage();

        if ($this->tmplSize) {
            $this->row = $this->pageHeight - $this->topMargin; // reset row
            $id = $this->importPage(min($this->pageNumber, $this->tmplSize));
            $this->useTemplate($id);
        }

        // include related php file if any
        $tmpl_php = find_custom_file("/reporting/forms/".$this->headerTmpl.".php");
        if ($tmpl_php) {
            include($tmpl_php);
        }  else {
                // include reports installed inside extension modules
                if (count($installed_extensions) > 0)
                {
                    $extensions = $installed_extensions;
                    foreach ($extensions as $ext)
                        if (($ext['active'] && $ext['type'] == 'extension')) {
                            $tmpl_php = find_custom_file($path_to_root.'/'.$ext['path']."/reporting/forms/".$this->headerTmpl.".php");
                            if ($tmpl_php) {
                                $this->tmplSize = $this->setSourceFile($tmpl_php);
                            }
                        }
                }
            }

        if (method_exists($this, $this->headerTmpl))    // draw predefined page layout if any
            $this->{$this->headerTmpl}();
    }

This would help us to hook from the modules template to work on.

This is a good feature.

You can create it. But you need to make an option in the destination and follow it to make program to open it in html view

6

(1 replies, posted in Accounts Receivable)

It's simple dude. Create direct invoice and payment term should not be cash only.

And than goto customer payment. There you can make one payment with one bank partial amount. And than goto customer payment again and make the balance amount. But this time select another bank to complete it.

This way one invoice can be paid by two payments
Even more than 2 payment you can do for a single invoice

7

(3 replies, posted in Installation)

What's ur server configuration.  State here to understand the capacity to help you

8

(3 replies, posted in Development)

This is rare case. Usually people check the Salesmans sales history and balance. But if you want to maintain the balance of terminal. You need to bring the POS id into the debtor trans and stock moves table to get the total cost of a terminal and item details.

9

(7 replies, posted in Accounts Receivable)

Sometimes it happens. If you clear your browser cache the issue will be fixed. But I didn't get exact solution within Fa program itself.

10

(3 replies, posted in Development)

@notrinos,  I think it may help you.
We have a field in users table for pos. With that POS id will be saved in users table. User id will be entered inside audit trail. With that you can relate it by writing a join query

@joe and @itronics, check this with existing core.

The get_balance function also includes the voided payment or edited payment. Its better, we have to include the voided table to exclude the entries of voided amount.

here is my adjusted code.

//----------------------------------------------------------------------------------------------------
function get_balance($account, $dimension, $dimension2, $from, $to, $from_incl=true, $to_incl=true) 
{
    $from_date = date2sql($from);
    $to_date = date2sql($to);

    $sql = "SELECT    SUM(IF(amount >= 0, amount, 0)) as debit, 
                    SUM(IF(amount < 0, -amount, 0)) as credit,
                    SUM(amount) as balance 
        FROM ".TB_PREF."gl_trans trans  LEFT JOIN ".TB_PREF."voided AS vd ON trans.type = vd.type AND trans.type_no = vd.id,"
            .TB_PREF."chart_master coa,"
            .TB_PREF."chart_types act_type, "
            .TB_PREF."chart_class act_class
        WHERE trans.account=coa.account_code  AND ISNULL(vd.id)
            AND coa.account_type=act_type.id 
        AND act_type.class_id=act_class.cid"
        ." AND ".($from_incl ? "tran_date >= '$from_date'" : "tran_date > IF(ctype>0 AND ctype<".CL_INCOME.", '0000-00-00', '$from_date')")
        ." AND ".($to_incl ? "tran_date <= '$to_date'" : "tran_date < '$to_date'")
        .($account == null ? '' : " AND account=".db_escape($account))
        .($dimension == 0 ? ''  : " AND dimension_id = ".($dimension<0 ? 0 : db_escape($dimension)))
        .($dimension2 == 0 ? '' : " AND dimension2_id = ".($dimension2<0 ? 0 : db_escape($dimension2)));

    $result = db_query($sql,"No general ledger accounts were returned");

    return db_fetch($result);
}

for other types.

case 'INVOICE':
                    $IV = $type_shortcuts[ST_SALESINVOICE];
                    $ref = ($SysPrefs->print_invoice_no() == 1 ? "trans_no" : "reference");
                    $sql = "SELECT concat(debtor_trans.trans_no, '-', debtor_trans.type) AS TNO,
                                concat('$IV ', debtor_trans.$ref,' ', debtor.name) as IName
                        FROM ".TB_PREF."debtors_master debtor,"
                            .TB_PREF."debtor_trans debtor_trans LEFT JOIN ".TB_PREF."voided AS vd ON debtor_trans.type=vd.type AND debtor_trans.trans_no=vd.id
                        WHERE debtor_trans.type=".ST_SALESINVOICE." AND debtor.debtor_no=debtor_trans.debtor_no AND ISNULL(vd.id)
                        ORDER BY debtor_trans.trans_no DESC";
                    return combo_input($name, '', $sql, 'TNO', 'IName',array('order'=>false));

                case 'CREDIT':
                    $CN = $type_shortcuts[ST_CUSTCREDIT];
                    $ref = ($SysPrefs->print_invoice_no() == 1 ? "trans_no" : "reference");
                    $sql = "SELECT concat(debtor_trans.trans_no, '-', debtor_trans.type) AS TNO,
                                concat('$CN ', debtor_trans.$ref,' ', debtor.name) as IName
                        FROM ".TB_PREF."debtors_master debtor,"
                            .TB_PREF."debtor_trans debtor_trans LEFT JOIN ".TB_PREF."voided AS vd ON debtor_trans.type=vd.type AND debtor_trans.trans_no=vd.id
                        WHERE debtor_trans.type=".ST_CUSTCREDIT." AND debtor.debtor_no=debtor_trans.debtor_no AND ISNULL(vd.id)
                        ORDER BY debtor_trans.trans_no DESC";
                    return combo_input($name, '', $sql, 'TNO', 'IName',array('order'=>false));

                case 'DELIVERY':
                    $DN = $type_shortcuts[ST_CUSTDELIVERY];
                    $sql = "SELECT    concat(debtor_trans.trans_no, '-', debtor_trans.type) AS TNO,
                                concat(debtor_trans.trans_no, ' $DN ', debtor.name) as IName
                        FROM ".TB_PREF."debtors_master debtor,"
                            .TB_PREF."debtor_trans debtor_trans LEFT JOIN ".TB_PREF."voided AS vd ON debtor_trans.type=vd.type AND debtor_trans.trans_no=vd.id
                        WHERE debtor_trans.type=".ST_CUSTDELIVERY." AND debtor.debtor_no=debtor_trans.debtor_no AND ISNULL(vd.id)
                        ORDER BY debtor_trans.trans_no DESC";
                    return combo_input($name, '', $sql, 'TNO', 'IName',array('order'=>false));


                case 'REMITTANCE':
                    $BP = $type_shortcuts[ST_BANKPAYMENT];
                    $SP = $type_shortcuts[ST_SUPPAYMENT];
                    $CN = $type_shortcuts[ST_SUPPCREDIT];
                    $ref = ($SysPrefs->print_invoice_no() == 1 ? "trans_no" : "reference");
                    $sql = "SELECT concat(trans.trans_no, '-',trans.type) AS TNO,
                                concat(trans.$ref, IF(type=".ST_BANKPAYMENT.", ' $BP ', IF(type=".ST_SUPPAYMENT.", ' $SP ', ' $CN ')), supplier.supp_name) as IName
                            FROM ".TB_PREF."suppliers supplier, "
                                .TB_PREF."supp_trans trans  LEFT JOIN ".TB_PREF."voided AS vd ON trans.type=vd.type AND trans.trans_no=vd.id
                            WHERE trans.type IN(".ST_BANKPAYMENT.",".ST_SUPPAYMENT.",".ST_SUPPCREDIT.")    AND supplier.supplier_id=trans.supplier_id AND ISNULL(vd.id)
                            ORDER BY trans.trans_no DESC";
                    return combo_input($name, '', $sql, 'TNO', 'IName',array('order'=>false));

                case 'RECEIPT':
                    $BD = $type_shortcuts[ST_BANKDEPOSIT];
                    $CP = $type_shortcuts[ST_CUSTPAYMENT];
                    $ref = ($SysPrefs->print_invoice_no() == 1 ? "trans_no" : "reference");
                    $sql = "SELECT concat(trans.trans_no, '-', trans.type) AS TNO,
                                concat(trans.$ref, IF(trans.type=".ST_BANKDEPOSIT.", ' $BD ', ' $CP '), debtor.name) as IName
                        FROM ".TB_PREF."debtors_master debtor,"
                            .TB_PREF."debtor_trans trans LEFT JOIN ".TB_PREF."voided AS vd ON trans.type=vd.type AND trans.trans_no=vd.id
                        WHERE trans.type IN(".ST_BANKDEPOSIT.",".ST_CUSTPAYMENT.",".ST_CUSTCREDIT.") AND debtor.debtor_no=trans.debtor_no AND ISNULL(vd.id)
                        ORDER BY trans.trans_no DESC";
                    return combo_input($name, '', $sql, 'TNO', 'IName',array('order'=>false));

A good issue, @joe looks like we have to add voided table in it.

it sholud be like this for sales invoice

case 'INVOICE':
                    $IV = $type_shortcuts[ST_SALESINVOICE];
                    $ref = ($SysPrefs->print_invoice_no() == 1 ? "trans_no" : "reference");
                    $sql = "SELECT concat(debtor_trans.trans_no, '-', debtor_trans.type) AS TNO,
                                concat('$IV ', debtor_trans.$ref,' ', debtor.name) as IName
                        FROM ".TB_PREF."debtors_master debtor,"
                            .TB_PREF."debtor_trans debtor_trans LEFT JOIN ".TB_PREF."voided AS vd ON debtor_trans.type=vd.type AND debtor_trans.trans_no=vd.id
                        WHERE debtor_trans.type=".ST_SALESINVOICE." AND debtor.debtor_no=debtor_trans.debtor_no AND ISNULL(vd.id)
                        ORDER BY debtor_trans.trans_no DESC";
                    return combo_input($name, '', $sql, 'TNO', 'IName',array('order'=>false));

15

(8 replies, posted in Report Bugs here)

There is no smtp configured to send emails on prompt time.  If you wish to add smtp feature you have to change the default main function with phpmailer to deliver mails immediately.

16

(1 replies, posted in Reporting)

The GD extension is needed . Just enable and  restart your server apache to take effect

You can keep it. Just check at the bottom of pdf_reports .inc.  as you can see the files of 3mins old will be deleted and recreated new PDF in it

@sikumbang - the translation is  always giving some problems. Especially the utf-8 supported languages. 

There are possible fixes.
1. Your Linux system must be updated with locale.
2. Apache should be enabled with gettext
3. Some fa translations are mismatched with strings in fa. Especially I  can tell one thing. From login page the password was not fetched the string properly with po file.

4. There are bugs in translation file as well.  Truncate it by removing duplicate entries unnecessary commented lines.

19

(7 replies, posted in Announcements)

@Joe if you create a separate repo for development  and provide access to other developers who are active in fa  development.  It would be more productive and more time saving for us  to merge our changes into the core. The final version  you can test and release it to community benefit

Sure I will write my part of changes and bug fixes and ideas too.

ok.So when it will be released  officially.

Even, we can pass the same currency to

 get_diff_in_home_currency($supp_trans->supplier_id, $old_date, $date_, $old_value,     $taxfree_line, $currency); 

this will reduce a bit more

function get_diff_in_home_currency($supplier, $old_date, $date, $amount1, $amount2,$currency=null)
{
    $dec = user_price_dec();
    price_decimal_format($amount2, $dec);
if($currency == null)
    $currency = get_supplier_currency($supplier);
    $ex_rate = get_exchange_rate_to_home_currency($currency, $old_date);
    $amount1 = $amount1 / $ex_rate;
    $ex_rate = get_exchange_rate_to_home_currency($currency, $date);
    $amount2 = $amount2 / $ex_rate;
    $diff = $amount2 - $amount1;
    //return round2($diff, $dec);
    return $diff;
}

As i have seen some queries which unnecesaarily runs within loops or its called multiple times to pass it to another data. There is one recent one I am bring here to update the core makes simple.

/purchasing/includes/db/invoice_db.inc

From the add_supp_invoice function, there is items line foreach which has a function inside it

$currency = get_supplier_currency($supp_trans->supplier_id);

This actually no point to run within items loop, just imagine, if the user add 50 items in one invoice and tries to save. this query runs 49 times unnecessarily.  and also one more thing with the same function.

From this function

function add_gl_trans_supplier($type, $type_no, $date_, $account, $dimension, $dimension2,  
    $amount, $supplier_id, $err_msg="", $rate=0, $memo="")
{
    if ($err_msg == "")
        $err_msg = "The supplier GL transaction could not be inserted";    
        
    return add_gl_trans($type, $type_no, $date_, $account, $dimension, $dimension2, $memo, 
        $amount, get_supplier_currency($supplier_id), 
        PT_SUPPLIER, $supplier_id, $err_msg, $rate);
}

This is acutally calls more than once for a single item. during the same invoice process. here looks this code. 

get_supplier_currency($supplier_id), 

it runs more than 100 times as of my above example.  So its better take out this and pass one more parameter in the

 add_gl_trans_supplier

like this

 add_gl_trans_supplier($type, $type_no, $date_, $account, $dimension, $dimension2,  
    $amount, $supplier_id, $err_msg="", $rate=0, $memo="", $currency=null){
      if ($err_msg == "")
        $err_msg = "The supplier GL transaction could not be inserted";    
    if($currency == null )
        $currrency = get_supplier_currency($supplier_id);
    return add_gl_trans($type, $type_no, $date_, $account, $dimension, $dimension2, $memo, 
        $amount, $currency, 
        PT_SUPPLIER, $supplier_id, $err_msg, $rate);
}

. This will simplify more than 150 query load to server when we submit 50 items invoice.

@Joe,And @Janusz, Hope you guys get the point.

24

(27 replies, posted in Wish List)

We will add it to next core update. @Joe  consider it for next release

This is quite interesting one. I have done similar thing for a FA user. He has more than 1,00,000 items. He brought to with three filtering to narrow down the results to get it. You need to enable search items list from company setup and customize the pop-up search file to capable of filters