1 (edited by stefan 12/13/2017 11:48:04 am)

Topic: Inventory purchasing transaction based report

I use this report for my own needs, it might be useful for others too.
It is based on rep306 in 2.4.RC1 distribution, the controls are exactly the same.

It follows the purchase operations, showing the item lines  and the delivery location.
The transactions are separated by line.

I have no time to make installation part, if there are volunteers - welcome!
I haven't removed some unnecessary code as I think others might use it for their needs.

Re: Inventory purchasing transaction based report

Here is the code:

<?php
/**********************************************************************
    Copyright (C) FrontAccounting, LLC.
    Released under the terms of the GNU General Public License, GPL, 
    as published by the Free Software Foundation, either version 3 
    of the License, or (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
    See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
***********************************************************************/ 
$page_security = 'SA_SUPPLIERANALYTIC';
// ----------------------------------------------------------------

// Creator:    Stefan Sotirov
// date_:    01-12-2017
// Title:    Inventory Purchasing - Transaction Based
//-----------------------------------------------------------------
// The report is based on rep306.php in FA 2.4.RC1 distribution and follows my own work needs.
// It might be useful for others too.
// All controls are the same as rep306
// If someone has free time, please make the installation part for others...
// There might be some minor errors after the cleaning, I haven't tested it in details
// ----------------------------------------------------------------
$path_to_root="..";

include_once($path_to_root . "/includes/session.inc");
include_once($path_to_root . "/includes/date_functions.inc");
include_once($path_to_root . "/includes/data_checks.inc");
include_once($path_to_root . "/includes/banking.inc");
include_once($path_to_root . "/gl/includes/gl_db.inc");
include_once($path_to_root . "/inventory/includes/db/items_category_db.inc");

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

print_inventory_purchase();

function getTransactions($category, $location, $fromsupp, $item, $from, $to, $loc2)
{
    $from = date2sql($from);
    $to = date2sql($to);
    $sql = "SELECT item.category_id,
            category.description AS cat_description,
            item.stock_id,
            item.description, item.inactive,
            move.loc_code,
            supplier.supplier_id,
            supplier.supp_name AS supplier_name,
            move.trans_no,
            move.tran_date,
            move.qty AS qty,
            move.price
        FROM ".TB_PREF."stock_moves move
                LEFT JOIN ".TB_PREF."supp_trans credit ON credit.trans_no=move.trans_no AND credit.type=move.type
                LEFT JOIN ".TB_PREF."grn_batch grn ON grn.id=move.trans_no AND 25=move.type
                LEFT JOIN ".TB_PREF."suppliers supplier ON IFNULL(grn.supplier_id, credit.supplier_id)=supplier.supplier_id,
            ".TB_PREF."stock_master item,
            ".TB_PREF."stock_category category
        WHERE item.stock_id=move.stock_id        
        AND item.category_id=category.category_id        
        AND move.tran_date>='$from'
        AND move.tran_date<='$to'        
        AND (move.type=".ST_SUPPRECEIVE." OR move.type=".ST_SUPPCREDIT.")
        AND (item.mb_flag='B' OR item.mb_flag='M')";
        if ($category != 0)
            $sql .= " AND item.category_id = ".db_escape($category);
        if ($location != '')
            
            $sql .= " AND move.loc_code = ".db_escape($location);
            
        
        if ($fromsupp != '')
            $sql .= " AND supplier.supplier_id = ".db_escape($fromsupp); 
        if ($item != '')
            $sql .= " AND item.stock_id = ".db_escape($item);
        $sql .= " ORDER BY move.tran_date, move.trans_no,
            supplier.supp_name, item.category_id, item.stock_id";
        
    return db_query($sql,"No transactions were returned");

}

function get_supp_inv_reference($supplier_id, $stock_id, $date)
{
    $sql = "SELECT trans.supp_reference
        FROM ".TB_PREF."supp_trans trans,
            ".TB_PREF."supp_invoice_items line,
            ".TB_PREF."grn_batch batch,
            ".TB_PREF."grn_items item
        WHERE trans.type=line.supp_trans_type
        AND trans.trans_no=line.supp_trans_no
        AND item.grn_batch_id=batch.id
        AND item.item_code=line.stock_id
        AND trans.supplier_id=".db_escape($supplier_id)."
        AND line.stock_id=".db_escape($stock_id)."
        AND trans.tran_date=".db_escape($date);
    $result = db_query($sql,"No transactions were returned");
    $row = db_fetch_row($result);
    if (isset($row[0]))
        return $row[0];
    else
        return '';
}

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

function print_inventory_purchase()
{
    global $path_to_root;

    $from = $_POST['PARAM_0'];
    $to = $_POST['PARAM_1'];
    $category = $_POST['PARAM_2'];
    $location = $_POST['PARAM_3'];
    $fromsupp = $_POST['PARAM_4'];
    $item = $_POST['PARAM_5'];
    $comments = $_POST['PARAM_6'];
    $orientation = $_POST['PARAM_7'];
    $destination = $_POST['PARAM_8'];
    if ($destination)
        include_once($path_to_root . "/reporting/includes/excel_report.inc");
    else
        include_once($path_to_root . "/reporting/includes/pdf_report.inc");

    $orientation = ($orientation ? 'L' : 'P');
    $dec = user_price_dec();
    

    if ($category == ALL_NUMERIC)
        $category = 0;
    if ($category == 0)
        $cat = _('All');
    else
        $cat = get_category_name($category);

    if ($location == '')
        $loc = _('All');
    else
        $loc = get_location_name($location);
    
    if ($fromsupp == '')
        $froms = _('All');
    else
        $froms = get_supplier_name($fromsupp);

    if ($item == '')
        $itm = _('All');
    else
        $itm = $item;

    $cols = array(0, 60, 180, 225, 275, 400, 420, 465,    520);
    
    $headers = array(_('Item'), _('Description'), _('Date'), _('#'), _('Supplier'), _('Qty'), _('Unit Price'), _('Location'));
    if ($fromsupp != '')
        $headers[4] = '';

    $aligns = array('left',    'left',    'left', 'left', 'left', 'left', 'right', 'right');

    $params =   array(     0 => $comments,
                        1 => array('text' => _('Period'),'from' => $from, 'to' => $to),
                        2 => array('text' => _('Category'), 'from' => $cat, 'to' => ''),
                        3 => array('text' => _('Location'), 'from' => $loc, 'to' => ''),
                        4 => array('text' => _('Supplier'), 'from' => $froms, 'to' => ''),
                        5 => array('text' => _('Item'), 'from' => $itm, 'to' => ''));

    $rep = new FrontReport(_('Inventory Purchasing - Transaction Based'), "InventoryPurchasingReport", user_pagesize(), 9, $orientation);
    if ($orientation == 'L')
        recalculate_cols($cols);

    $rep->Font();
    
    $rep->Info($params, $cols, $headers, $aligns);
   
    $rep->NewPage();
    $rep->TextCol(1, 5, _("Note: The lines separate the transactions."));
    $rep->NewLine();
    
    $res = getTransactions($category, $location, $fromsupp, $item, $from, $to);

hidden ($total = $total_supp = $grandtotal = 0.0); //left if someone needs them for own needs
hidden ($total_qty = 0.0);
    $catt = $stock_description = $stock_id = $supplier_name = $event = '';
    
    while ($trans=db_fetch($res))
    {
        
        
        if ($event != $trans['trans_no'])
        {
                $rep->Line($rep->row - 2);
        }
        $event = $trans['trans_no'];
        $stock_id = $trans['stock_id'];
        $stock_description = $trans['description'];
        $curr = get_supplier_currency($trans['supplier_id']);
        $rate = get_exchange_rate_from_home_currency($curr, sql2date($trans['tran_date']));
        $trans['price'] *= $rate;
        $rep->NewLine();
        $trans['supp_reference'] = get_supp_inv_reference($trans['supplier_id'], $trans['stock_id'], $trans['tran_date']);
        $rep->fontSize -= 2;
        
        if ($fromsupp == ALL_TEXT)
        {
            $rep->TextCol(0, 1, $trans['stock_id']);
            $rep->TextCol(1, 2, $trans['description']._("  ").($trans['inactive']==1 ? " ("._("Inactive").")" : ""), -1);
            $rep->TextCol(2, 3, sql2date($trans['tran_date']));
            $rep->TextCol(3, 4, $trans['supp_reference'].("  "));
            $rep->TextCol(4, 5, $trans['supplier_name']._("  "));
        }
        else
        {
            $rep->TextCol(0, 1, $trans['stock_id']);
            $rep->TextCol(1, 2, $trans['description'].($trans['inactive']==1 ? " ("._("Inactive").")" : ""), -1);
            $rep->TextCol(2, 3, sql2date($trans['tran_date']));
            $rep->TextCol(3, 4, $trans['supp_reference']);
        }    
        $rep->AmountCol(5, 6, $trans['qty'], get_qty_dec($trans['stock_id']));
        $rep->AmountCol(6, 7, $trans['price'], $dec);
        $amt = $trans['qty'] * $trans['price'];
        $rep->TextCol(7, 8, _("  ").get_location_name($trans['loc_code']));
        
        $rep->fontSize += 2;


//------------Left if somebody needs them for own needs
    //    $total += $amt; 
    //    $total_supp += $amt;
    //    $grandtotal += $amt;
    //    $total_qty += $trans['qty'];
        
        
        
        
    }
    
    $rep->Line($rep->row - 2);
    

    $rep->Line($rep->row-4);
    $rep->NewLine(2);
    $rep->fontSize += 2;
    $rep->TextCol(0, 3, _("Report End"));
    $rep->Line($rep->row -3);
    $rep->Line($rep->row -5);

    $rep->End();
}

Re: Inventory purchasing transaction based report

this is a great report and in my opinion should be one of the default reports in FA.
Thanks fort sharing.

Re: Inventory purchasing transaction based report

The report can be rep310.php with appropriate inclusions in the report request forms. Whitespace synch has been done with respect to rep306.php (since it is based upon it) in FA 2.4.3+ as on date.

Screenshots and files for inclusion into the core attached.

@stefan: please verify if it works well at your end and whether it needs some fixes / enhancements.
@joe: see if can be included if it serves some useful purpose.

Post's attachments

reporting_310.zip 41.7 kb, 9 downloads since 2017-12-13 

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

5 (edited by stefan 12/14/2017 07:14:01 am)

Re: Inventory purchasing transaction based report

I am glad you like it. smile
I'll be quite busy these few days, but I'll give some feedback when I can.

Re: Inventory purchasing transaction based report

Report modified slightly and committed to stable.

Joe

Re: Inventory purchasing transaction based report

@joe: Nice work removing _("  ") (how did I miss it and why did @stefan put it in?). Also consolidating the comments and removing $loc2 (why did @stefan put it in?) apart from NewLine() and font size adjustments.

8 (edited by stefan 12/15/2017 09:18:37 am)

Re: Inventory purchasing transaction based report

$loc2  it was for other use, I didn't see it's still in here.

_("  ")  - if you are an active user and have cells with long content, you wouldn't remove it, trust me...

The readability of the report changes significantly if you have long data. With no spaces it might be torturing.

I am actually a manager, interested in development - not really a developer, so I made it knowing the way I look into the reports.

In fact this was also the purpose of "Report End" - often printed similar reports are put together in one tray and if one is 45 pages, and the next 17, it is much easier when you have a mark on the pages. Otherwise you have a tray with same pages and you lose time and efforts to recognize what is the needed part...

Re: Inventory purchasing transaction based report

If you have problem reading the reports you can print them in landscape mode.

The core reports should follow the standards mostly.

Joe

Re: Inventory purchasing transaction based report

I'm not arguing, just explaining - in landscape mode you have print costs double...
I don't mind if it is without spaces.

Re: Inventory purchasing transaction based report

well done...
a very needed and essential report.

Thanks stefan.

Re: Inventory purchasing transaction based report

The effect of the Report End is achieved if the last ruled line is bolded or is a double bold line.

The spaces should not be implemented as a translatable string even if you use it. The column widths and their paddings are better adjusted instead.

Re: Inventory purchasing transaction based report

The report stands corrected and committed into the core now as rep310.php.

Post's attachments

rep310.png 19 kb, file has never been downloaded. 

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

Re: Inventory purchasing transaction based report

Is this report available as downloadable extension?

Re: Inventory purchasing transaction based report

It is now part of the core.

See the original inclusion commit and the subsequent enhancement commit

Re: Inventory purchasing transaction based report

Okay fine.

I have copied rep310.php in the reporting folder but I cannot see it in FA 2.4.3.

Re: Inventory purchasing transaction based report

This report is new and was not there in the release. Also the original inclusion had another file that is necessary.

Re: Inventory purchasing transaction based report

Would you please point me which another file is required and where to copy it?

Re: Inventory purchasing transaction based report

this is the file you need to update.
reports_main.php

Post's attachments

reports.png 31.1 kb, file has never been downloaded. 

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

Re: Inventory purchasing transaction based report

(The part of Allah) جزاک اللہ خیراً