The Template (eg., Header2) function is executed only at the very end of the New page method and the the company/#/reporting/Header2.php if present will provide overrides for properties not defined in it and in doctext.inc and header2.inc or in cases where pre-defined property values in them are not overridden (like $this->formData['br_name']).

Any variables (need to global them) and properties referred to in the header2.inc and doctext.inc files that are not part of the core can be provided in the Header2.php file and assigned in header2.inc and doctext.inc only if absent.

If the Header2.pdf / Header.pdf files have more than one page, then each one is used in succession for the report and the last one for the remaining pages of the report.

Wikied "Watermarking and background / logo merging in reports". It now stands documented!

4,453

(4 replies, posted in Reporting)

In the new commit, to suppress Page numbering, comment out lines 144 to 147:

//        $this->NewLine(2);
//    
//        if ($this->pageNumber > 1)
//            $this->Text($mcol + 180, _("Page") . ' ' . $this->pageNumber);

@joe: Thanks for the OpenWriter file. Will be useful in documenting this feature.

English translation of Swedish "laboration": Laboratory / Experimental Work.

Anyone used the Header.php / Header2.php in the reporting/forms folder in the company/#/ folder?

4,455

(0 replies, posted in Reporting)

FA uses FPDI v1.2.1 released on 2008-09-11. The current version 1.5.2 was released on 2014-06-26. Anyone used the latest version of FPDI in their FA install? Any advantages and features?

@joe: Thanks for the doPDF tip. PDFCreator too generates small PDF files and is free but may try to install some nagware (optional) in the later versions.

Uploaded the Watermark PDF file as company/1/reporting/includes/forms/Header2.pdf (case sensitive - must be same name as HeaderTmpl with pdf extension) and attached the sample invoice PDFs generated.

If the Watermark file is formatted as PDF v1.5 and above, then we get a "Unexpected data in xref table" error. FPDI Commercial version can read PDF v1.5 and higher.

We can convert such files to PDF v1.4 format using PDFCreator and then use it in FA without errors. PDFCreator is a virtual print driver to generate PDF files.

MS Word 2007 => Page layout => Watermark => Custom Watermark => File => Save As => PDF or XPS
yields a PDF v1.5 format that needs to be converted as above before using it in FA.

Please note that there is no option to turn it on or off and if the watermark file is present, then it will be used for all reports that use the header template.

4,458

(4 replies, posted in Reporting)

@joe: Thanks. Very nice alternative real solution. Attached Screenshot.

Consequent on change in the header2.inc file in latest commit, the mod is also updated and attached here and updated in the wiki.

4,460

(21 replies, posted in Reporting)

You might also want to refer the php.ini max_input_vars setting to increasing it from the default of 1000 to 3000 or beyond as instructed in this thread.

4,461

(2 replies, posted in Reporting)

Thanks @joe: The sequencing of the header type assignment listed in the previous posts here is not necessary as the actual file inclusion of the header2.inc happens only when the new page method is called in line 944-945 of reporting/includes/pdf_report.inc. It still does no harm in keeping them together.

4,462

(4 replies, posted in Reporting)

Comment out lines 145 and 146 of reporting/includes/header2.inc (or place a copy of the file in the appropriate path in the company reporting folder):

        if ($this->pageNumber > 1)
            $this->Text($this->endLine - 35, _("Page") . ' ' . $this->pageNumber);

@joe: either a report form variable to suppress page numbers or a config variable/sys_prefs variable to be a flag for it would be nice - atleast going forward in FA v2.4.

4,463

(3 replies, posted in Installation)

You can judge by downloads from GeoIP based computation but it will be well off the mark. People download it off the Hg repo in Sourceforge, the Official Git mirror and my GitHub repo and it's 46 forks apart from pull only private forks and the official release sites.

You can judge by the forum signups but most are passive readers only.

You can judge by FA pkg repo downloads but most may never use extensions or just create their own.

Many may have used older versions and never upgraded or moved on to other packages. Others may have migrated into FA from other applications.

Hence this is a dynamic. Nobody knows and why should anyone care. Just tweak it to suit your needs!

FA is, well, just incomparable!

A HOWTO has been prepared in the Wiki on PHP mail() function using fake sendmail in Windows.

4,465

(18 replies, posted in Wish List)

Then you would definitely need to implement the Non Field DB Data and write your own function for filtering out the checks....

Are you referring to various customer checks your receive or your checks to various suppliers you pay out? If it is the altter, then just make the check number with some start string as the reference for supplier payments and it will auto increment.

4,466

(3 replies, posted in Installation)

"scale of vendor FA?"
Do you mean - how many Vendors can FA handle?

"Market share of online accounting that FA has?"
Your guess is as good as mine. Maybe 0.0001% to 1% of all online accounting usage!
The ocean covers 2/3rds of the earth - where would you like to swim?

Just tested out the multiple contacts availability by setting the last parameter $default=false in the get_branch_contacts() function call in rep107.php. Did a dump of the $contacts array before the function call and the $rep->contactData property after the function call with the $default parameter set to true (single) and false (multiple) and attached the outputs herein.

Hence set the last parameter in get_branch_contacts() to false if you want multiple mailing and leave it at true for single email.

The sequence of customer and branch creation is as follows:
1. Sales => Add and Manage Customers => Added New Customer with email id.
2. Customer Branches => Select Customer => Edit Customer Branch => Contacts => Add 2 New Contacts For Branch
=> Invoice and General Type with email id
=> Invoice and Orders Type with email id
3. Sales => Direct Invoice => Make an invoice for the customer branch.
4. Sales => Customer and Sales Reports => Print Invoices =. Choose to email customers and select the newly created invoice and Display Print Invoice (after setting rep107.php last parameter in get_branch_contacts() to false).

Works as expected - emails to 3 different recipients but separate emails.

@joe: Your logic is sound. Tested it out as well and it corroborates well - the NewPage is the one that actually gives effect to  the Tmpl setting and it's sequence anywhere prior to it is immaterial.

What is the purpose of placing a Header2.pdf file in reporting/forms folder (possibly in the company folder)?

On New page creation in reports, the function setSourceFile() in reporting/includes/fpdi/fpdi.php is called and returns the number of pages in the above Header2.pdf file.

On New page creation in reports another possibility is to place a Header2.php file in reporting/forms folder (possibly in the company folder) as well - what does it do?

The file purchasing/includes/ui/po_ui.inc has a function display_po_header() that does the job. Reference is generally editable on new data entry only and not available to be editable afterwards (line 117).  Lines 177 to 182:

    if ($editable)
    {
        ref_row(_("Reference:"), 'ref');
    }
    else
    {
        hidden('ref', $order->reference);
        label_row(_("Reference:"), $order->reference);
    }

provide the form elements.

@joe: I stand corrected that the Tmpl inclusion is needed for other reasons. The $rep->SetHeaderType('Header2') "includes" the header2.inc and doctext.inc files. These included files refer to data obtained in SetCommonData() which is useful for including non field db data as illustrated in the wiki for Bin Location type of functionality.

In this instance in rep107.php (Invoicing), $contacts is populated with data from the get_branch_contacts() function and is passed on as an argument into the $rep->SetCommonData() method which in turn populates the $this->formData and $this->contactData properties which in turn is used to get the contacts to email the reports to. In fact the SetCommonData() method makes even a single email id into an array, ie., $this->contactData.

Will investigate further....

4,471

(3 replies, posted in Banking and General Ledger)

Thanks @bobloblian. The wiki has now been updated with your valuable in context suggestion.

@bobloblian: Let's see what line 978 onwards in reporting/includes/pdf_report.inc has:

                $contactData = array();
                if ($this->contactData)
                    foreach($this->contactData as $contact)
                        if (!empty($contact['email']))
                            $contactData[] = $contact;

                if(!count($contactData)) {
                    $this->SetLang(user_language());
                    display_warning(sprintf(_("You have no email contact defined for this type of document for '%s'."), $this->formData['recipient_name']));
                } else {
                    $sent = $try = 0;

Only if there was no email available would you get the error stated

You have no email contact defined for this type of document for 'Computerisms'.

Therefore in the incoming $this->contactData itself, there would be no such record with email contact details and that narrows it down to the output of the get_branch_contacts() function. A check on with and without the last parameter being false will reveal that when it is true, the defaults have kicked in and not the appropriate contact for the specified action type. Try adding more than one contact to the branch where you choose it to be of invoice type (rep107.php) and then see what happens on making the last parameter false.

Please note that you will need tobackportsome report fixes from FA 2.4 since the SetCommonData() method needs to precede the Header2() call in reports that call it. This is necessary because the property $this->contactData is assigned from the $contact in line 409 and the latter comes from the said method SetCommonData() which in turn gets it from the get_branch_contacts() function call in rep107.php a couple of lines earlier.

@joe: the backports of the repXXX.php files done on 2015-01-21 is hence necessary.

4,473

(18 replies, posted in Wish List)

Add your "Check" payment terms in Setup => Payment Terms menu.

Your extra fields:
1. Check Owner Name (anyone other than the customer can be entered in the memo / comments field)
2. Pay to the Order of (anyone other than the Company whose Accounts is being maintained in FA can be similarly entered in the memo / comments field)
3. Check Number can be entered using the comments field and better still using the Non Field DB Data concept discussed in the Wiki.

Whilst getting all contacts and using it for emailing (To, Cc, Bcc, etc) is fine, getting only one contact is important for report printing and for use in the FA user interface screens.

Currently, the function get_branch_contacts is used in:

sales/includes/ui/sales_order_ui.inc
repXXX.php
where XXX in 103 (commented out), 107 (Invoice), 108 (commented out), 109  through to 113.

In the extensions, rep_email_customers calls it in modules/reporting/rep_email_customers/includes/customer_emailer.inc with the last parameter as false (no defaults). Also, when the second parameter ($action) is set to null as in this file, all contacts accrue.

In sales/includes/ui/sales_order_ui.inc the following construct in lines 112-114:

    $contact = get_branch_contacts($branch_id, 'order', $customer_id);
    $order->set_branch($branch_id, $myrow["tax_group_id"],
    $myrow["tax_group_name"], @$contact["phone"], @$contact["email"]);

expect to have defaults (missing last parameter assumed $default as true) and restricted to the 'orders' type alone and is used as a single contact for populating the branch details alone.

The standard repXXX.php listed above use the following constructs:

rep107.php:
$contacts = get_branch_contacts($branch['branch_code'], 'invoice', $branch['debtor_no'], true);

rep109.php:
$contacts = get_branch_contacts($branch['branch_code'], 'order', $branch['debtor_no'], true);

rep110.php:
$contacts = get_branch_contacts($branch['branch_code'], 'delivery', $branch['debtor_no'], true);

rep111.php:
$contacts = get_branch_contacts($branch['branch_code'], 'order', $branch['debtor_no'], true);

rep112.php:
$contacts = get_branch_contacts($myrow['branch_code'], 'invoice', $myrow['debtor_no']);

rep113.php:
$contacts = get_branch_contacts($branch['branch_code'], 'invoice', $branch['debtor_no'], true);

which makes last parameter $default to be true but allows for (but currently does not obtain) multiple contacts in subsequent emailing usage alone.

Either we determine it to be a single contact (count elements in array), or choose only the first one for the sales/includes/ui/sales_order_ui.inc and all other places we need single contacts or make a new function called get_branch_contact (singular) with the current code in it and make new content for the existing function get_branch_contacts (plural) for usage where multiple contacts are needed.

As far as emailing is concerned, we can make the first contact as the "To" recipient and all others as the "Cc" recipients if they exist!

Way forward is to be decided - all your thoughts on this is welcome before a patch is forwarded to @joe.

Hence currently, no code change is required except for setting the last parameter as false in reports that need to be emailed to multiple entities!

In includes/current_user.inc, the following function is defined:

//
//    Search $needle in $haystack or in $haystack[][$valuekey]
//    returns $needle found or null.
//
function array_search_value($needle, $haystack, $valuekey=null)
{
    foreach($haystack as $key => $value) {
        $val = isset($valuekey) ? @$value[$valuekey] : $value;
        if ($needle == $val){
            return $value;
        }
    }
    return null;
}

This function is used by function get_branch_contacts in sales/includes/db/branches_db.inc (this file has another similarly named function prefixed with an underscore that is neither used in the FA core nor in any extension).

At the very end of the function get_branch_contacts we find that only one element is returned because of a return within the loop:

    foreach($defs as $type) {

        if ($n = array_search_value($type, $results, 'ext_type'))

            return $n;
    
    }

If this value is captured in a separate array if it is not empty, then that array would have all the necessary contacts.

This is clearly a bug.

@joe: please update accordingly in FA 2.3 and into FA 2.4.

PS: The error in includes/ui/simple_crud_class.inc is tolerated because of the "@" prefixing the assignment. A check for the variable's existence before assignment would remedy it and it is needed in more than one place in the same function!