Topic: Manufacturing Values Off By Small Amounts

I have some manufacturing g/l entries that are ending up inaccurate by a penny or two. Not all work orders do this, just some. Is this a PHP rounding issue? Should I just create a journal entry from my 1530 to 1510 periodically to clean up?

Accnt #     Accnt Name                 Debit     Credit
1510    Inventory                                 0.30    
1510    Inventory                                 0.55    
1510    Inventory                                 20.18    
1510    Inventory                                 5.99    
1510    Inventory                                 5.99    
1530    Stocks of Work In Prg         33.01        

Finished Product Receival     
           
1530    Stcks of Work In Prg                     33.00    
1510    Inventory                     33.00        

Re: Manufacturing Values Off By Small Amounts

Whilst a onetime cleanup using a journal adjustment entry is in order, the real solution going forward will be to increase the precision in php.ini from default 14 to 17.

An interesting discussion on this topic is here:
https://stackoverflow.com/questions/145 … oint-issue.

Re: Manufacturing Values Off By Small Amounts

Thanks @apmuthu, but that doesn't address my issue. Precision was at 14 and now at 17. Running FA v.2.4.7, PHP v.7.2.26. At 17, it still happens here.

4 (edited by paul 01/25/2020 02:41:52 am)

Re: Manufacturing Values Off By Small Amounts

I also tried precision set at 8, 20 and 40. All returned same, inaccurate, results in my test.

Re: Manufacturing Values Off By Small Amounts

Then play with the delta value in config.php

Re: Manufacturing Values Off By Small Amounts

Assuming you are referring to a literal term, I do not find a "delta" value in my FrontAccounting's config.php

Re: Manufacturing Values Off By Small Amounts

$config_allocation_settled_allowance value in config.php.

8 (edited by paul 01/25/2020 02:42:57 pm)

Re: Manufacturing Values Off By Small Amounts

I saw this option, but thought it was for discrepancies while receiving a purchase order if pricing was too far off of the entered amount. But, I did change the value (not knowing it's potential) with no change to my manufacturing issue. The values I tested with other than the 0.005 were 0.505 and 5.505 - Manufacturing amount inaccuracies are still produced.

Re: Manufacturing Values Off By Small Amounts

Try this piece of code in a test php file:

<?php
if (1.7 >= 17 * 0.1) {
  echo '1.7 is greater than or equal to ' . 17 * 0.1;
} else {
  echo '1.7 is NOT greater than or equal to ' . 17 * 0.1;
}

echo "<br>\n" . (0.1 + 0.2);

?>

In XAMPP 1.7.3 (PHP 5.3.1) we get:

1.7 is NOT greater than or equal to 1.7000000000000002
0.30000000000000004

This is because native operator are indeed interpreted in base 2, and most base 10 decimal converts badly in base 2.

If you need precision, you need to either only manipulate integers (converts perfectly to base 2) or use a dedicated lib such as bcmath (checkout the wrapper to ease bcmath usage Math).

Ref as of 2 months ago:
https://stackoverflow.com/questions/58744298/php-floating-point-multiplication-and-comparison-issue

Ref as of nearly 11 years ago:
https://stackoverflow.com/questions/588004/is-floating-point-math-broken

Ref in PHP.net:
https://bugs.php.net/bug.php?id=74534

Floating point arithmetic for programmers

Re: Manufacturing Values Off By Small Amounts

With the test php file, I get:

1.7 is NOT greater than or equal to 1.7000000000000002
0.30000000000000004

  I don't need super fine precision. I would like consistency. If I'm taking $33.01 out of inventory for manufacturing, I need $33.01 taken from manufacturing back into inventory. Maybe part of my problem is the difference from my vendors unit of 1 equals 1152 units in my inventory. Standard costs are shown at 4 decimal places.

11 (edited by paul 01/26/2020 11:47:29 pm)

Re: Manufacturing Values Off By Small Amounts

I just entered four work orders from yesterday. Only one was accurate from inventory through work in progress back into inventory. Two others were off by one penny. One other one was off by 2 pennies. Each one is not much, but with up to 400 work orders a month, it starts to add up.

Re: Manufacturing Values Off By Small Amounts

This is an FA bug, sort of, and it affects my site as well, but I haven't gotten around to fixing it yet.  And yes, a journal entry is probably the only way to address it without fixing the code.

When FA closes a work order, it calls work_order_produce() which first creates the Finished Product Requirements.   The g/l created by each requirement eventually calls add_gl_trans().  Note the rounding in this function:

function add_gl_trans($type, $trans_id, $date_, $account, $dimension, $dimension2, $memo_,
    $amount, $currency=null, $person_type_id=null, $person_id=null, $err_msg="", $rate=0)
{
    global $SysPrefs;

    $date = date2sql($date_);
    if ($currency != null)
    {
        if ($rate == 0)
            $amount_in_home_currency = to_home_currency($amount, $currency, $date_);
        else
            $amount_in_home_currency = round2($amount * $rate,  user_price_dec());
    }
    else
        $amount_in_home_currency = round2($amount, user_price_dec());

OK, so each requirement is rounded, and then added up.

But wait, there is more to do.  work_order_produce() then sums up the Finished Product Recieval:

        // 1. calculate sums of material/labour/overhead costs

        // sum collected BOM material & labour costs (no way for separate overhead here for now - needs flag in bom or stock_master)
        $bom = get_wo_requirements($woid);
        $m_cost = $l_cost = 0;
        while ($component = db_fetch($bom))
        {
            if (!is_service($component["mb_flag"]))
                $m_cost += $component['unit_cost']*$component['units_issued'];
            else
                $l_cost += $component['unit_cost']*$component['units_issued'];
        }

        // add additional material issues
        $issues = get_additional_issues($woid);
        while ($issue = db_fetch($issues))
        {
            if (!is_service($issue["mb_flag"]))
                $m_cost += $issue['unit_cost']*$issue['qty_issued'];
            else
                $l_cost += $issue['unit_cost']*$issue['qty_issued'];
        }

        // and additional costs
        $o_cost = get_gl_wo_cost($woid, WO_OVERHEAD);
        $l_cost += get_gl_wo_cost($woid, WO_LABOUR);

        $total_cost = $o_cost + $m_cost + $l_cost;

        add_gl_trans_std_cost(ST_WORKORDER, $woid, $date_, $product['wip_account'],
            0, 0, $memo, -$total_cost);

        add_gl_trans_std_cost(ST_WORKORDER, $woid, $date_, $product['inventory_account'],
            0, 0, $memo, $total_cost);

So if all units were able to be manufactured, the calculation should be the same.

Except for the lack of rounding in this code.

So if it disturbs you to see these rounding errors, what can you do?  Well, you could try rounding m_cost and l_cost like in add_gl_trans.  Maybe try:

          if (!is_service($issue["mb_flag"]))
                $m_cost += round2($issue['unit_cost']*$issue['qty_issued'], user_price_dec());
            else
                $l_cost += round2($issue['unit_cost']*$issue['qty_issued'], user_price_dec());

I haven't tried this, so it might not work.  But this is first thing I would try.

Re: Manufacturing Values Off By Small Amounts

@joe: How do we handle such rounding errors in a standardised way to avoid adjustment journal entries?

Re: Manufacturing Values Off By Small Amounts

I don't know. We have tried to do our best by using the DELTA factor.
We can await @Braath Waate's approach by @paul testing it.

/Joe

Re: Manufacturing Values Off By Small Amounts

The rounding modification didn't help my issue. I modified manufacturing/includes/db/work_order_produce_items_db.inc by replacing lines starting at line 65 with @Braathe's suggestion. I still see the differences.

  I have no problem adding a journal entry to clean up. I was more concerned that I was doing something wrong or I setup something wrong and I wanted to correct that. Maybe most people just let this run wild and don't address it at all. I'm not trying to make more work to do, just wanting to follow best practices with the tools available.

  Thank you very much for the insight and suggestions.

Re: Manufacturing Values Off By Small Amounts

Just for the record, round2() is mainly needed starting at line 55 to sum up the the boms.  Line 65 is just the additional materials.

Re: Manufacturing Values Off By Small Amounts

Thanks Braathe. I blew right past the main section. After applying your modifications, it DOES address my problem with rounding. Thank you very much.

Re: Manufacturing Values Off By Small Amounts

I have made many changes to FrontAccounting the past 6 months. I have rough notes of these changes. Probably 99% of those changes have been offered from many of you via this forum.

  What is the best way to backup and restore these changes when a new version becomes available? I imagine some of the changes I made to 2.4.7 may already be incorporated in the next version.

Re: Manufacturing Values Off By Small Amounts

I suggest making a fork of the FA project on github, and adding your changes in, perhaps with help from a 3-way diff tool.  Then as new changes are made in FA, you can sync your fork with the upstream code.  Often the new changes are incorporated without any additional effort but sometimes there are conflicts, but then you run git mergetool to help determine how to proceed.