$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...

Here it is, it works on the identical reflines for Sales Invoices and Credit Notes.
Maybe it's too simple, but that's what I needed and I'm happy with it.

CAUTION - I haven't made data checks as I use alone this system.
For the moment it is not impossible to manually create Sales Invoice and Credit Note with same numbers.
I mean if you change the displayed reference number...

Also note, here it is with mb_strlen

This is the changed part in _parse_next function:

                $prefix = $match[1];
        $postfix = $match[3];

        $db_info = get_systype_db_info($type);
        $trans_table = $db_info[0];
        $type_fld = $db_info[1];
        $tno_fld = $db_info[2];
        $ref_fld = $db_info[3];
        $type_sec = '';                                   // change starts here
       
        if($type== ST_CUSTCREDIT || $type== ST_SALESINVOICE)   
        {
        $type_sec = '10,11';                        // don't laugh, it works fine smile
        }
        else
        {
        $type_sec= $type;
        }

        // retrieve last ref number in the refline from original transaction table
        $sql = "SELECT MAX(CAST(SUBSTR($ref_fld, ".(mb_strlen($prefix)+1).",LENGTH($ref_fld)-".(mb_strlen($postfix)+mb_strlen($prefix)).") AS UNSIGNED))"
                ." FROM `$trans_table` tbl
                    LEFT JOIN ".TB_PREF."voided v ON tbl.`$tno_fld`=v.id AND v.type in ($type_sec)"
                ." WHERE ISNULL(v.id)"
                .($type_fld ? " AND tbl.`$type_fld`in ($type_sec)" : '')
                ." AND `$ref_fld` REGEXP ".db_escape('^'.preg_quote($prefix).'[0-9]*'.preg_quote($postfix).'$');
        $result = db_query($sql, 'cannot retrieve last reference');
        $result = db_fetch_row($result);

28

(3 replies, posted in Reporting)

Open /reporting/rep107.php

than find line 270, it looks like this:

$rep->TextCol(3, 7, _("Included") . " " . $tax_type_name . _("Amount") . ": " . $DisplayTax, -2);

replace it with this:

$rep->TextCol(3, 6, _("Included") . " " . $tax_type_name . _("Amount") . ": " , -2);
$rep->TextCol(6, 7,  $DisplayTax, -2);

save the change

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

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();
}

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.

I gave no feedback, but changing a little the function _parse_next works fine...

apmuthu wrote:

Commissions off the books or amount set aside for possible contractual reasons / bullying the supplier!

:-) :-) :-)

Here they made a "Flat taxing" - if you are in a out of tax hypothesis, somebody has to collect the tax for you and pay it.
If you are a person, not entity and you sell to an entity, the person is charged with the same rate as the "profit" tax for the entity. And it's all in the books. :-)

gj6n68 wrote:

Hello,

Have you looked at quick entries?

I have done something similar to what you are looking for using quick entries for vat on items acquired from EU, where I have to pay local vat on these items.


Hi, and thank you. I have to try, are the stock quantities adjusted with quick entries?

This must be a question to more experienced users, not that much about coding I think.

I have PURCHASE operations for items that typically have 0 taxes.
However for some certain suppliers at this standard pricing, I have to withhold some percent on the resulting amount and pay it as tax (but not to the supplier).


One solution that comes to my mind is removing the negative rate data check for tax rates.
However I am not sure whether to expect complications this way...

Any ready work around???

Thanks for saving my time.

I guess this is an user issue, but I just can't get it.

I have to organize kind of exotic disassembling process.

The only certain thing is the input quantity. Let's say soil - it will always be named like this and will always have the same elements, but never with the same proportions.
You put 1 ton in and you don't know how much big stones, small stones, sand and other unusable dirt will you get.

And when I finish the dedicated 1 ton, I have to close the order with the produced fractions, as much as they are.

Can I use the Manufacturing with such logic or not?

I want to unite the references of Sales Invoices and Credit Notes.

Example: Invoice 1, Invoice 2, Credit Note 3, Invoice 4, Credit Note 5....

I can manually put the needed number, but that's not the point.
What must I do?

2.4.RC1

It works with one day, but sets next date. I work this way now, changing manually the date when creating invoice.

Just some people do not pay enough attention to change it, I'm trying to make it automatic.

I have to make Same day BANK payment terms for invoicing. When I try to create them they become immediately cash sales - it seems the 0 days is for cash and negative numbers for prepayments.

The question: If i make the "Same day BANK payment" as Cash payment in the payment term list, will I get into trouble later on? Is the "Cash" word visible somewhere across the GL postings or reports, as it is the way of transferring funds fixed in the payment terms list for all same day payments?

Solution: replace 'strlen' with 'mb_strlen' and everything works fine...

"The prefix field is defined as CHAR in the original sql - why did you change it to VARCHAR?" - To avoid blocking problems with cyrilic alphabet characters.

In the actual statement the prefix is displayed 1:1

This query in includes/references.inc returns 0 when prefix is longer... When prefix is short it returns number

// retrieve last ref number in the refline from original transaction table
$sql = "SELECT MAX(CAST(SUBSTR($ref_fld, ".(strlen($prefix)+1).",LENGTH($ref_fld)-".(strlen($postfix)+strlen($prefix)).") AS UNSIGNED))"
                ." FROM `$trans_table` tbl
                    LEFT JOIN ".TB_PREF."voided v ON tbl.`$tno_fld`=v.id AND v.type=$type"
                ." WHERE ISNULL(v.id)"
                .($type_fld ? " AND tbl.`$type_fld`=$type" : '')
                ." AND `$ref_fld` REGEXP ".db_escape('^'.preg_quote($prefix).'[0-9]*'.preg_quote($postfix).'$');

Yes, it's 2.4.rc1 reflines table.

It is increased to 12. All refs are recorded and recalled correctly, but the auto increment of reflines with prefix longer than 5 characters is not working.

It looks like this and with the short prefixes works perfect, so i guess this is hard-coded somewhere else about the auto increment, and I can't find where.

Here is the DB table config:

`prefix` varchar(12) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',

I need to change the size of the prefix of the reflines. I have changed the size of DB cell and it is joined, recorded and displayed with the number correctly.
However, when the prefix is with more than 5 characters, the number after the prefix does not auto increase. I can't find where to change the prefix size for the auto increment purposes. It seems to be done in /includes/references.inc but I am not good enough to handle this my self.

I need the long prefixes for Sales Orders and Delivery Notes

46

(5 replies, posted in Setup)

What says the debugger?

Update:

In /includes/current_user.inc I added this:

function amount_format($number) {  return number_format2($number, 2); }

At the sub-totals and totals of this file I have replaced price_format with amount_format

Than in /includes/ui/ui_view.inc in the functions:
display_customer_trans_tax_details
display_supp_trans_tax_details
display_edit_tax_items
I replaced all occurrences of "user_price_dec()" with "2" and the relevant "price_format" with "amount_format"

For the moment looks fine. I can use prices with .00001 and the line_totals are the same. The sub-total, the taxes and the total are .01 (rounded to cent).

update: IT'S NOT GOOD !!!

Sorry, both ways it doesn't not work.

168-169 changed to
$line_total = round($stock_item->qty_dispatched * $stock_item->price * (1 - $stock_item->discount_percent), 2);
solves the Sub-total, but not the Total and Taxes.

222 this solves Sub-total
$display_sub_total = round($total + input_num('freight_cost'), 2);

227 this solves the Total
$display_total = round(($total + input_num('freight_cost') + $tax_total), 2);

only simple tests are done, but looks to work correct on the Sales Order.

My central issue are the taxes, and they are still not ready

I am just a beginner, so it might take time.
It seems "user_price_dec" has to be replaced with "2" at many places, mainly in .inc files

Thanks a lot!!!
This much I can edit smile

I guess this question is directed to more experienced users.

I need to have prices per unit with 4 digits after decimal and all amounts rounded to cent (second digit after dec.).
This is especially valid for taxes and totals.

I think I have tried all combinations of Display Setup and Company Setup/Round Calculated Prices.
(The last seems to be for Price lists calculations etc., not for direct sales input)

The only idea I have is changing the unit of measure, but it leads to consequential issues.
Any other idea will be appreciated smile