Cost handling in purchasing module fixed.
authorJanusz Dobrowolski <janusz@frontaccounting.eu>
Mon, 15 Jul 2019 18:28:14 +0000 (20:28 +0200)
committerJanusz Dobrowolski <janusz@frontaccounting.eu>
Mon, 19 Aug 2019 10:41:58 +0000 (12:41 +0200)
14 files changed:
gl/includes/db/gl_db_trans.inc
purchasing/includes/db/grn_db.inc
purchasing/includes/db/invoice_db.inc
purchasing/includes/db/po_db.inc
purchasing/includes/po_class.inc
purchasing/includes/purchasing_db.inc
purchasing/includes/supp_trans_class.inc
purchasing/includes/ui/invoice_ui.inc
purchasing/supplier_credit.php
purchasing/supplier_invoice.php
reporting/rep204.php
reporting/rep305.php
taxes/tax_calc.inc
taxes/tax_rules.inc

index 229ba2d1d8dd6fe7b72ef5c8808c7dbc5cd9ae40..15e2c84a36f2f023e46454b2d84e8dd16bd89c2d 100644 (file)
@@ -483,13 +483,15 @@ function add_trans_tax_details($trans_type, $trans_no, $tax_id, $rate, $included
 
 function get_trans_tax_details($trans_type, $trans_no)
 {
-    $sql = "SELECT tax_details.*, tax_type.name AS tax_type_name, tax_type.rate AS rate
-        FROM ".TB_PREF."trans_tax_details tax_details INNER JOIN 
-        ".TB_PREF."tax_types tax_type ON tax_type.id = tax_details.tax_type_id
+    $sql = "SELECT tax_details.*, SUM(tax_details.amount) amount, SUM(tax_details.net_amount) as net_amount,
+            tax_type.name AS tax_type_name, tax_type.rate AS rate
+        FROM ".TB_PREF."trans_tax_details tax_details
+         LEFT JOIN ".TB_PREF."tax_types tax_type ON tax_type.id = tax_details.tax_type_id
         WHERE 
                 trans_type = ".db_escape($trans_type)."
             AND trans_no = ".db_escape($trans_no)."
-            AND (net_amount != 0 OR amount != 0)";
+            AND (net_amount != 0 OR amount != 0)
+        GROUP BY tax_type_id";
 
     return db_query($sql, "The transaction tax details could not be retrieved");
 }
index 26b5bc7e58a35afdfea7b6ff166021c6926a540c..c303933fc95f5ef79ab2408ccf870558b8b8ecdc 100644 (file)
@@ -121,43 +121,41 @@ function write_grn(&$po)
                {
                        $stock_gl_code = get_stock_gl_code($order_line->stock_id);
 
-                       /*Update sales_order_details for the new quantity received and the standard cost used for postings to GL 
-                         and recorded in the stock movements for FIFO/LIFO stocks valuations*/
+                       //------------------------------------------------------------------------------------------------------
+                       if ($order_line->qty_received == 0)
+                       {
+                               /* This must be the first receipt of goods against this PO line. */
+                               /* Store provisional cost used in GL posting - inventory is updated to actual cost later when invoice is received */
+                               $order_line->unit_cost = round2($order_line->taxfree_charge_value($po) / $po->ex_rate / $order_line->quantity, user_price_dec());
+                       }
+
                        //------------------- update average material cost and clearing account --------------------------------
                        if (is_inventory_item($order_line->stock_id))
                        {
                                if ($clearing_act)
-                                       $total += add_gl_trans_supplier(ST_SUPPRECEIVE, $grn, $date_, $stock_gl_code["inventory_account"],
-                                               $stock_gl_code['dimension_id'], $stock_gl_code['dimension2_id'],
-                                           $order_line->taxfree_charge_value($po), $po->supplier_id, 0, $order_line->stock_id);
+                                       $total += add_gl_trans_std_cost(ST_SUPPRECEIVE, $grn, $date_, $stock_gl_code["inventory_account"],
+                                               $stock_gl_code['dimension_id'], $stock_gl_code['dimension2_id'], $order_line->stock_id,
+                                           $order_line->unit_cost*$order_line->quantity, PT_SUPPLIER, $po->supplier_id);
+
                                update_average_material_cost($po->supplier_id, $order_line->stock_id, $order_line->price,
                                        $order_line->quantity, $date_);
                        }
-                       //------------------------------------------------------------------------------------------------------
-                       if ($order_line->qty_received == 0)
-                       {
-                               /*This must be the first receipt of goods against this line */
-                               /*Need to get the standard cost as it is now so we can process GL jorunals later*/
-                               $order_line->unit_cost = get_unit_cost($order_line->stock_id);
-                       }
-                       // Update the purchase data table
-                       add_or_update_purchase_data($po->supplier_id, $order_line->stock_id, $order_line->price, 
-                               $order_line->item_description); 
 
-                       /*Need to insert a grn item */ // also need to check for over-receive.(within allowance)
+                       /* Need to insert a grn item */ // also need to check for over-receive.(within allowance)
                        if ($order_line->quantity + $order_line->qty_received > $order_line->qty_ordered)
                                $order_line->qty_ordered = $order_line->quantity + $order_line->qty_received;
 
+                       /* Store line details and update po_line */
                        $grn_item = write_grn_item($grn, $order_line->po_item_id,
-                               $order_line->stock_id, $order_line->item_description, $order_line->quantity, $order_line->grn_item_id);
+                               $order_line->stock_id, $order_line->item_description, $order_line->quantity, $order_line->grn_item_id, $order_line->unit_cost);
 
                        $po->line_items[$line_no]->grn_item_id = $grn_item;
                        /* Update location stock records - NB  a po cannot be entered for a service/kit parts done automatically */
                        add_stock_move(ST_SUPPRECEIVE, $order_line->stock_id, $grn, $po->Location, $date_, "",
                                $order_line->quantity, $order_line->unit_cost, $order_line->taxfree_charge_value($po)/$order_line->quantity);
 
-               } /*quantity received is != 0 */
-       } /*end of order_line loop */
+               } /* quantity received is != 0 */
+       }
 
        if ($clearing_act && $total != 0.0) {
                $accs = get_supplier_accounts($po->supplier_id);
@@ -170,6 +168,7 @@ function write_grn(&$po)
 
        $po->trans_no = $grn;
        hook_db_postwrite($po, ST_SUPPRECEIVE);
+
        commit_transaction();
 
        return $grn;
@@ -208,7 +207,7 @@ function update_grn_batch($grn, $reference, $location, $date_)
 }
 //-------------------------------------------------------------------------------------------------------------
 
-function write_grn_item($grn_batch_id, $po_detail_item, $item_code, $description, $quantity_received, $grn_item_id)
+function write_grn_item($grn_batch_id, $po_detail_item, $item_code, $description, $quantity_received, $grn_item_id, $unit_cost)
 {
        if ($grn_item_id)
                $sql = "UPDATE ".TB_PREF."grn_items SET qty_recd=".db_escape($quantity_received)
@@ -223,7 +222,8 @@ function write_grn_item($grn_batch_id, $po_detail_item, $item_code, $description
 
        $sql = "UPDATE ".TB_PREF."purch_order_details po,
                        (SELECT SUM(qty_recd) received FROM ".TB_PREF."grn_items grn WHERE po_detail_item=".db_escape($po_detail_item).") grn
-        SET po.quantity_received = grn.received
+        SET po.quantity_received = grn.received,
+            po.std_cost_unit =".db_escape($unit_cost)."
         WHERE po_detail_item = ".db_escape($po_detail_item);
        db_query($sql, "a purchase order details record could not be updated. This receipt of goods has not been processed ");
 
@@ -262,24 +262,23 @@ function set_grn_item_credited(&$entered_grn, $supplier, $transno, $date)
        $myrow = db_fetch($result);
 
        $sql = "UPDATE ".TB_PREF."purch_order_details
-        SET quantity_received = quantity_received + "
+        SET quantity_received = quantity_received - "
                .db_escape($entered_grn->this_quantity_inv).",
-        quantity_ordered = quantity_ordered + "
+        quantity_ordered = quantity_ordered - "
         .db_escape($entered_grn->this_quantity_inv).",
-        qty_invoiced = qty_invoiced + ".db_escape($entered_grn->this_quantity_inv).",
-        std_cost_unit=".db_escape($mcost).",
+        qty_invoiced = qty_invoiced - ".db_escape($entered_grn->this_quantity_inv).",
         act_price=".db_escape($entered_grn->chg_price)."
         WHERE po_detail_item = ".$myrow["po_detail_item"];
        db_query($sql, "a purchase order details record could not be updated. This receipt of goods has not been processed ");
 
        //$sql = "UPDATE ".TB_PREF."grn_items SET qty_recd=0, quantity_inv=0 WHERE id=$entered_grn->id";
-       $sql = "UPDATE ".TB_PREF."grn_items SET qty_recd=qty_recd+".db_escape($entered_grn->this_quantity_inv)
-       .",quantity_inv=quantity_inv+".db_escape($entered_grn->this_quantity_inv)
+       $sql = "UPDATE ".TB_PREF."grn_items SET qty_recd=qty_recd-".db_escape($entered_grn->this_quantity_inv)
+       .",quantity_inv=quantity_inv-".db_escape($entered_grn->this_quantity_inv)
        ." WHERE id=".db_escape($entered_grn->id);
        db_query($sql);
 
     add_stock_move(ST_SUPPCREDIT, $entered_grn->item_code, $transno, $myrow['loc_code'], $date, "",
-               $entered_grn->this_quantity_inv, $mcost, $entered_grn->chg_price);
+       -$entered_grn->this_quantity_inv, $mcost, $entered_grn->chg_price);
 }
 
 function get_grn_items($grn_batch_id=0, $supplier_id="", $outstanding_only=false,
@@ -338,7 +337,7 @@ function get_grn_items($grn_batch_id=0, $supplier_id="", $outstanding_only=false
 
 // get the details for a given grn item
 
-function get_grn_item_detail($grn_item_no)
+function get_grn_item($grn_item_no)
 {
        $sql = "SELECT grn.*, po.unit_price, grn.qty_recd - grn.quantity_inv AS QtyOstdg,
                po.std_cost_unit
@@ -370,8 +369,7 @@ function read_grn_items_to_order($grn_batch, &$order)
                        $order->add_to_order($myrow["item_code"],
                                $myrow["qty_recd"],$myrow["description"], $myrow["unit_price"],
                                sql2date($myrow["req_del_date"]), $myrow["quantity_inv"],
-                               $myrow["quantity_received"], $myrow["quantity_ordered"], $myrow["id"], $myrow["po_detail_item"]);
-
+                               $myrow["quantity_received"], $myrow["quantity_ordered"], $myrow["id"], $myrow["po_detail_item"], $myrow["std_cost_unit"]);
                } /* line po from purchase order details */
        } //end of checks on returned data set
 }
index de085139e636d597f468dfe5a9c3c4a9ea8c609b..07e87eb0810620fb56026ba7ad657a0ae06a6216 100644 (file)
@@ -175,11 +175,6 @@ function add_supp_invoice(&$supp_trans)  //, $already_voided=false, $allocs=null
        $net_total = 0;
        foreach($supp_trans->grn_items as $item)
        {
-       if ($trans_type == ST_SUPPCREDIT)
-               {
-                       $item->this_quantity_inv = -$item->this_quantity_inv;
-                       set_grn_item_credited($item, $supp_trans->supplier_id, $invoice_id, $date_);
-               }
                $item_gl = $item->gl_amounts;
 
                $stock_gl_code = get_stock_gl_code($item->item_code);
@@ -195,16 +190,14 @@ function add_supp_invoice(&$supp_trans)  //, $already_voided=false, $allocs=null
                         {
                                if ($value['Deductible'])
                                {       // GL: VAT deductible
-                               $gl_cart->add_gl_item($value['purchasing_gl_code'], 0, 0, $value['Deductible']+$value['Adjust'],  //FIXME: 'Adjust' ?
-                                               $value['Payable'] ? sprintf(_('Internal invoice %s input tax'), $supp_trans->reference) : '');
+                                       $gl_cart->add_gl_item($value['purchasing_gl_code'], 0, 0, $value['Deductible']+$value['Adjust']);
                                        // GL: VAT adjustment due to vat factor
                                        if ($value['Adjust'])
                                                $gl_cart->add_gl_item(get_company_pref('tax_adjustments_act'), 0, 0, -$value['Adjust']);
                                }
                                if ($value['Payable']) // reverse charge/intracommunity aquisition
                                {
-                                       $gl_cart->add_gl_item($value['sales_gl_code'], 0, 0, -$value['Payable'],
-                                       sprintf(_('Internal invoice %s input tax'), $supp_trans->reference));
+                                       $gl_cart->add_gl_item($value['sales_gl_code'], 0, 0, -$value['Payable']);
                                }
                                // GL: AP account (vat part)
                                if ($value['Value'])
@@ -220,62 +213,47 @@ function add_supp_invoice(&$supp_trans)  //, $already_voided=false, $allocs=null
                                        $value['tax_type_id'], $value['rate'], $supp_trans->tax_included, $value['Value'],
                                        $item_gl['Net'], $supp_trans->ex_rate, $date_, $supp_trans->supp_reference, TR_INPUT, $supp_trans->tax_group_id, $vat_category);
 
-                                       // $value['Deductible'], ???
-
-                               $tax_total += $value['Value'];
-
                                $line_tax += $value['Payable'] ? $value['Payable'] : $value['Value'];
                        }
                }
+
                // GL: AP account (net)
                $gl_cart->add_gl_item($supplier["payable_account"], 0, 0, -$item_gl['Net'], '', '', $supp_trans->supplier_id);
+
+               $tax_total += $item_gl['Tax'];
                $net_total += $item_gl['Net'];
 
                // cost line value
                $taxfree_line =  $item_gl['Cost'];
 
-               $old = update_supp_received_items_for_invoice($item->id, $item->po_detail_item,
-                       $item->this_quantity_inv, $item->chg_price);
-
-               // Since the standard cost is always calculated on basis of the po unit_price,
-               // this is also the price that should be the base of calculating the price diff.
-               // In cases where there is two different po invoices on the same delivery with different unit prices this will not work either
-               $old_price = $old[2];
-
-               /*
-                       If statement is removed. Should always check for deliveries nomatter if there has been a price change. 
-               */
-               $old_date = sql2date($old[1]);
-
                if (!is_inventory_item($item->item_code))
                {
-                       $gl_cart->add_gl_item($supplier["purchase_account"] ? $supplier["purchase_account"] : $stock_gl_code["cogs_account"], $dimension, $dimension2,  $taxfree_line);
-
+                       $gl_cart->add_gl_item($supplier["purchase_account"] ? $supplier["purchase_account"] : $stock_gl_code["cogs_account"], $dimension, $dimension2, $taxfree_line);
+
+               } elseif ($trans_type != ST_SUPPCREDIT) {
+                       $gl_cart->add_gl_item($stock_gl_code["inventory_account"], $dimension, $dimension2, $taxfree_line, _('Return to supplier'));
+                       // we must use invoice value here to preserve proper inventory valuation,
+                       // but if the purchase changed average cost, and any item was sold between invoice and credit,
+                       // the average will not return to the previous one. To fix this additional cost update should be made here to compensate cogs difference on items sold.
+                       update_average_material_cost(null, $item->item_code, $item_gl['Cost']/$item->this_quantity_inv, -$item->this_quantity_inv, $date_);
                } else {
 
-                       $val = split_item_price($item->item_code, $item->this_quantity_inv * $old_price, 
-                                 $supp_trans->tax_group_id, $supp_trans->tax_included);
-
-                       $GRN_value = $val['Cost'];
-
-                       $diff = get_diff_in_home_currency($supp_trans->supplier_id, $old_date, $date_, $GRN_value,
-                               $taxfree_line);
+                       // calculate difference between clearing cost and actual cost
+                       $diff = $item_gl['Cost'] - $item->std_cost_unit*$item->this_quantity_inv;
 
-                       // update average cost with per item part of difference (between invoice value and value set on po/grn)
                        update_average_material_cost(null, $item->item_code,
-                               $diff/$item->this_quantity_inv, $item->this_quantity_inv, null, true, "add_supp_invoice $trans_type:$invoice_id");
+                               $diff/$item->this_quantity_inv, $item->this_quantity_inv, null, true);
 
-                       if ($clearing_act)      // no postings on GRN, so post full net value
+                       if ($clearing_act)
                        {
-                               //Add GL transaction for GRN Provision in case of difference
-                               // material was already posted due GRN; post differences in value
-                               if ($diff != 0)
+                               if ($diff != 0) // if value on invoice differs from those posted on GRN receive, post the difference
                                {
 
                                        $gl_cart->add_gl_item($stock_gl_code["inventory_account"],                      // cart is in supplier currency, so need to fix by ex_rate here
                                                $dimension, $dimension2, $diff/$gl_cart->rate, _('GRN Provision')); // subject to rounding errors?
+
                                        $gl_cart->add_gl_item($clearing_act,
-                                               $dimension, $dimension2, -$diff/$gl_cart->rate, _('GRN Provision'));
+                                               $dimension, $dimension2, -$diff/$gl_cart->rate);
 
                                        //Chaitanya
                                        //If QOH is 0 or negative then update_average_material_cost will be skipped
@@ -308,7 +286,7 @@ function add_supp_invoice(&$supp_trans)  //, $already_voided=false, $allocs=null
                                }
                                $gl_cart->add_gl_item($clearing_act, $dimension, $dimension2, $taxfree_line);
                        }
-                       else
+                       else  // no postings on GRN, so post full cost here
                                $gl_cart->add_gl_item($stock_gl_code["inventory_account"], $dimension, $dimension2,     $taxfree_line);
 
                }
@@ -317,20 +295,25 @@ function add_supp_invoice(&$supp_trans)  //, $already_voided=false, $allocs=null
 //          add_actual_cost($item->order_price, $item->item_code);
 //        }
 
-               add_or_update_purchase_data($supp_trans->supplier_id, $item->item_code, $item->chg_price); 
+       if ($trans_type == ST_SUPPCREDIT)
+                       set_grn_item_credited($item, $supp_trans->supplier_id, $invoice_id, $date_);
+               else {
+                       add_or_update_purchase_data($supp_trans->supplier_id, $item->item_code, $item->chg_price); 
 
+                       update_supp_received_items_for_invoice($item->id, $item->po_detail_item,
+                               $item->this_quantity_inv, $item->chg_price);
+               }
+
+               $qty = ($trans_type==ST_SUPPCREDIT ? 1 : -1)*$item->this_quantity_inv;
                add_supp_invoice_item($trans_type, $invoice_id, $item->item_code,
-                       $item->item_description, 0,     $item->chg_price, $line_tax/$item->this_quantity_inv,
-                       $item->this_quantity_inv, $item->id, $item->po_detail_item);
+                       $item->item_description, 0,     $item->chg_price, $line_tax/$qty, $qty, $item->id, $item->po_detail_item);
     } // grn_items
 
+
     /*GL Items are straight forward - just do the debit postings to the GL accounts specified -
     the credit is to creditors control act */
     foreach ($supp_trans->gl_codes as $entered_gl_code)
     {
-               if ($trans_type == ST_SUPPCREDIT)
-                       $entered_gl_code->amount = -$entered_gl_code->amount;
-
                $memo_ = $entered_gl_code->memo_;
 
                $index = is_tax_account($entered_gl_code->gl_code);
@@ -338,8 +321,6 @@ function add_supp_invoice(&$supp_trans)  //, $already_voided=false, $allocs=null
                {
                        $gl_cart->add_gl_item($entered_gl_code->gl_code, $entered_gl_code->gl_dim, $entered_gl_code->gl_dim2, $entered_gl_code->amount);
                        // store tax details if the gl account is a tax account
-                       if ($trans_type == ST_SUPPCREDIT)
-                               $entered_gl_code->amount = -$entered_gl_code->amount;
                        add_gl_tax_details($entered_gl_code->gl_code, 
                                $trans_type, $invoice_id, $entered_gl_code->amount,
                                $supp_trans->ex_rate, $date_, $supp_trans->supp_reference, $supp_trans->tax_included, null, $supp_trans->tax_group_id);
@@ -355,6 +336,12 @@ function add_supp_invoice(&$supp_trans)  //, $already_voided=false, $allocs=null
                        $entered_gl_code->gl_dim, $entered_gl_code->gl_dim2);
     }
 
+       if ($trans_type == ST_SUPPCREDIT) {             // reverse postings if this is credit note
+               foreach($gl_cart->gl_items as &$line)
+                       $line->amount = -$line->amount;
+               $net_total = -$net_total;
+               $tax_total = -$tax_total;
+       }
        $gl_cart->reduce_gl();  // minimize GL lines
 
        $gl_cart->write_gl(false); // don't check balances here: we are working on two (maybe unbalanced) carts
index f48621fad266b85dd176d30a2321eafbbf4a9145..e7257e00183af926618210051d0797df1df9492b 100644 (file)
@@ -238,7 +238,7 @@ function read_po_items($order_no, &$order, $open_items_only=false)
                        $myrow["quantity_ordered"],$myrow["description"],
                $myrow["unit_price"], sql2date($myrow["delivery_date"]),
                        $myrow["qty_invoiced"], $myrow["quantity_received"],
-                       $myrow["quantity_ordered"], 0, $myrow["po_detail_item"]);
+                       $myrow["quantity_ordered"], 0, $myrow["po_detail_item"], $myrow["std_cost_unit"]);
         } /* line po from purchase order details */
     } //end of checks on returned data set
 }
index 54ae516474d7424bda75467470b447346bf54f5b..22a9274bf4278c9621d89e6ee5a07283b14d82f5 100644 (file)
@@ -69,10 +69,10 @@ class purch_order
                $this->tax_area = $tax_area;
        }
        
-       function add_to_order($stock_id, $qty, $item_descr, $price, $req_del_date, $qty_inv, $qty_recd, $qty_ordered=0, $grn_item_id=0, $po_item_id=0)
+       function add_to_order($stock_id, $qty, $item_descr, $price, $req_del_date, $qty_inv, $qty_recd, $qty_ordered=0, $grn_item_id=0, $po_item_id=0, $unit_cost=0)
        {
                $this->line_items[] = new po_line_details($stock_id, $item_descr, $qty, $price,
-                       $req_del_date, $qty_inv, $qty_recd, $qty_ordered, $grn_item_id, $po_item_id);
+                       $req_del_date, $qty_inv, $qty_recd, $qty_ordered, $grn_item_id, $po_item_id, $unit_cost);
        }
 
        function update_order_item($line_no, $qty, $price, $req_del_date, $description="")
@@ -207,7 +207,7 @@ class purch_order
                                        {
                                                $diff = $tax['Override'] - $tax['Value'];
                                                $this->line_items[$id]->gl_amounts[0]['Value'] += $diff;
-                                               if ($this->vat_category() != VC_NONDEDUCT)
+                                               if ($line->vat_category != VC_NONDEDUCT)
                                                        $this->line_items[$id]->gl_amounts[0]['Deductible'] += $diff;
                                                else
                                                        $this->line_items[$id]->gl_amounts['Cost'] += $diff;
@@ -247,7 +247,7 @@ class po_line_details
        var $gl_amounts;        // splited line value (after call to split_line_value method)
 
        function __construct($stock_item, $item_descr, $qty, $prc, $req_del_date, 
-               $qty_inv, $qty_recd, $qty_ordered=0, $grn_item_id=0, $po_item_id=0)
+               $qty_inv, $qty_recd, $qty_ordered=0, $grn_item_id=0, $po_item_id=0, $unit_cost=0)
        {
                $this->stock_id = $stock_item;
                $item_row = get_item($stock_item);
@@ -265,7 +265,7 @@ class po_line_details
                $this->units = $item_row["units"];
                $this->qty_received = $qty_recd;
                $this->qty_inv = $qty_inv;
-               $this->unit_cost =0;
+               $this->unit_cost = $unit_cost;
                $this->grn_item_id = $grn_item_id;
                $this->vat_category = $item_row["vat_category"];
                $this->qty_ordered = $qty_ordered;
@@ -289,7 +289,7 @@ class po_line_details
         $vat_factor = 1;
 
                return $this->gl_amounts = split_item_price($this->stock_id, $this->price*$this->quantity, $cart->tax_group_id, $cart->tax_included, 
-                       ST_SUPPINVOICE, $vat_factor, $cart->tran_date);
+                       ST_SUPPINVOICE, $vat_factor);
        }
   
 }
index 53d73dbc2f7a69b3de9581655db520d57022f531..eb4a1ac47057284908b04e82a7e4f79c7e3a7be8 100644 (file)
@@ -194,6 +194,7 @@ function add_direct_supp_trans($cart)
                $inv->add_grn_to_trans($line->grn_item_id, $line->po_item_id, $line->stock_id,
                        $line->item_description, $line->quantity, 0, $line->quantity,
                        $line->price, $line->price, true, get_unit_cost($line->stock_id), '');
+
                $total += round2(($line->quantity * $line->price), user_price_dec());
        }
        $inv->tax_overrides = $cart->tax_overrides;
index 31b00b8a42bb65f9b0845771f8e6297a3fc8936d..59d0e5c298ad59be0e60e375b894e1a8ca6d1eed 100644 (file)
@@ -213,11 +213,11 @@ class supp_trans
                        if ($tax['Value'] != 0 && isset($tax['Override']) && ($tax['Value'] != $tax['Override']))
                        {
                                foreach($this->grn_items as $id => $line)
-                                       if ($line->gl_amounts[0]['tax_type_id'] == $tax_id) // assumed single tax rate on item, so always gl_mount[0] is valid
+                                       if ($line->gl_amounts[0]['tax_type_id'] == $tax_id) // assumed single tax rate on item, so always gl_amounts[0] is valid
                                        {
                                                $diff = $tax['Override'] - $tax['Value'];
                                                $this->grn_items[$id]->gl_amounts[0]['Value'] += $diff;
-                                               if ($this->vat_category() != VC_NONDEDUCT)
+                                               if ($line->vat_category != VC_NONDEDUCT)
                                                        $this->grn_items[$id]->gl_amounts[0]['Deductible'] += $diff;
                                                else
                                                        $this->grn_items[$id]->gl_amounts['Cost'] += $diff;
@@ -300,7 +300,7 @@ all the info to do the necessary entries without looking up ie additional querie
         $vat_factor = 1;
 
                return $this->gl_amounts = split_item_price($this->item_code, $this->chg_price*$this->this_quantity_inv, $cart->tax_group_id, $cart->tax_included, 
-                       ST_SUPPINVOICE, $vat_factor, $cart->tran_date);
+                       ST_SUPPINVOICE, $vat_factor);
        }
 }
 
index 8299aa0e1ab7a2191db506816bb7c3dd2f507f23..2e9520e708db3103a68b5aacf833e1e1fb639ace 100644 (file)
@@ -386,12 +386,6 @@ function display_grn_items_for_selection(&$supp_trans, $k)
 
                        $n = $myrow["id"];
                        label_cell(get_trans_view_str(ST_SUPPRECEIVE, $myrow["grn_batch_id"]), "nowrap align='right'");
-                       hidden('qty_recd'.$n, $myrow["qty_recd"]);
-               hidden('item_code'.$n, $myrow["item_code"]);
-               hidden('item_description'.$n, $myrow["description"]);
-               hidden('prev_quantity_inv'.$n, $myrow['quantity_inv']);
-               hidden('order_price'.$n, $myrow['unit_price']);
-               hidden('po_detail_item'.$n, $myrow['po_detail_item']);
                label_cell(get_trans_view_str(ST_PURCHORDER, $myrow["purch_order_no"]), "nowrap align='right'");
             label_cell($myrow["item_code"]);
             label_cell($myrow["description"]);
index 461c80443496d3c64ca223dd2e8aa77d1c2266b0..cbb10a8d4ba4158efd6e0fb2e0eda4add40a8714 100644 (file)
@@ -236,10 +236,7 @@ function handle_commit_credit_note()
        if (!check_data())
                return;
 
-       if (isset($_POST['invoice_no']))
-               $invoice_no = add_supp_invoice($_SESSION['supp_trans'], $_POST['invoice_no']);
-       else
-               $invoice_no = add_supp_invoice($_SESSION['supp_trans']);
+       $invoice_no = add_supp_invoice($_SESSION['supp_trans']);
 
     $_SESSION['supp_trans']->clear_items();
     unset($_SESSION['supp_trans']);
@@ -270,7 +267,7 @@ function check_item_data($n)
                set_focus('ChgPrice'.$n);
                return false;
        }
-
+       
        return true;
 }
 
@@ -278,11 +275,12 @@ function commit_item_data($n)
 {
        if (check_item_data($n))
        {
+               $item = get_grn_item($n);
                $_SESSION['supp_trans']->add_grn_to_trans($n,
-               $_POST['po_detail_item'.$n], $_POST['item_code'.$n],
-               $_POST['item_description'.$n], $_POST['qty_recd'.$n],
-               $_POST['prev_quantity_inv'.$n], input_num('This_QuantityCredited'.$n),
-               $_POST['order_price'.$n], input_num('ChgPrice'.$n));
+               $item['po_detail_item'], $item['item_code'],
+               $item['description'], $item['qty_recd'],
+               $item['quantity_inv'], input_num('This_QuantityCredited'.$n),
+               $item['unit_price'], input_num('ChgPrice'.$n), $item['std_cost_unit']);
                reset_tax_input();
        }
 }
index e75ec45c76ffee42926d70a64a84feea4f6e36e0..0ac3052d97c3867e6cb436804900e78421cf800d 100644 (file)
@@ -246,6 +246,14 @@ function check_item_data($n)
 {
        global $SysPrefs;
 
+       $item = get_grn_item($n);
+
+       if (!$item)
+       {
+               display_error( _("Invalid GRN item selected."));
+               return false;
+       }
+
        if (!check_num('this_quantity_inv'.$n, 0) || input_num('this_quantity_inv'.$n)==0)
        {
                display_error( _("The quantity to invoice must be numeric and greater than zero."));
@@ -263,10 +271,8 @@ function check_item_data($n)
        $margin = $SysPrefs->over_charge_allowance();
        if ($SysPrefs->check_price_charged_vs_order_price == True)
        {
-               if ($_POST['order_price'.$n]!=input_num('ChgPrice'.$n)) {
-                    if ($_POST['order_price'.$n]==0 ||
-                               input_num('ChgPrice'.$n)/$_POST['order_price'.$n] >
-                           (1 + ($margin/ 100)))
+               if ($item['unit_price'] != input_num('ChgPrice'.$n)) {
+                    if ($item['unit_price'] == 0 || input_num('ChgPrice'.$n)/$item['unit_price'] > (1 + ($margin/ 100)))
                    {
                        display_error(_("The price being invoiced is more than the purchase order price by more than the allowed over-charge percentage. The system is set up to prohibit this. See the system administrator to modify the set up parameters if necessary.") .
                        _("The over-charge percentage allowance is :") . $margin . "%");
@@ -276,9 +282,9 @@ function check_item_data($n)
                }
        }
 
-       if ($SysPrefs->check_qty_charged_vs_del_qty == true && ($_POST['qty_recd'.$n] != $_POST['prev_quantity_inv'.$n]))
+       if ($SysPrefs->check_qty_charged_vs_del_qty == true && ($item['qty_recd'] != $item['quantity_inv']))
        {
-               if (input_num('this_quantity_inv'.$n) / ($_POST['qty_recd'.$n] - $_POST['prev_quantity_inv'.$n]) >
+               if (input_num('this_quantity_inv'.$n) / ($item['qty_recd'] - $item['quantity_inv']) >
                        (1+ ($margin / 100)))
                {
                        display_error( _("The quantity being invoiced is more than the outstanding quantity by more than the allowed over-charge percentage. The system is set up to prohibit this. See the system administrator to modify the set up parameters if necessary.")
@@ -288,17 +294,23 @@ function check_item_data($n)
                }
        }
 
-       return true;
+       $item['quantity'] = input_num('this_quantity_inv'.$n);
+       $item['chg_price'] = input_num('ChgPrice'.$n);
+
+       return $item;
 }
 
 function commit_item_data($n)
 {
-       if (check_item_data($n))
+       $item  = check_item_data($n);
+       if ($item)
        {
-               $_SESSION['supp_trans']->add_grn_to_trans($n, $_POST['po_detail_item'.$n],
-                       $_POST['item_code'.$n], $_POST['item_description'.$n], $_POST['qty_recd'.$n],
-                       $_POST['prev_quantity_inv'.$n], input_num('this_quantity_inv'.$n),
-                       $_POST['order_price'.$n], input_num('ChgPrice'.$n));
+               $_SESSION['supp_trans']->add_grn_to_trans($n,
+               $item['po_detail_item'], $item['item_code'],
+               $item['description'], $item['qty_recd'],
+               $item['quantity_inv'], $item['quantity'],
+               $item['unit_price'], $item['chg_price'], $item['std_cost_unit']);
+
                reset_tax_input();
        }
 }
@@ -315,9 +327,9 @@ if (isset($_POST['InvGRNAll']))
 {
        foreach($_POST as $postkey=>$postval )
     {
-               if (strpos($postkey, "qty_recd") === 0)
+               if (strpos($postkey, "this_quantity_inv") === 0)
                {
-                       $id = substr($postkey, strlen("qty_recd"));
+                       $id = substr($postkey, strlen("this_quantity_inv"));
                        $id = (int)$id;
                        commit_item_data($id);
                }
index 51fbf012d66c5182f1752500694e54818bbf2f1b..cc8b536298e88c629e4dc30accd80d68c0b62746 100644 (file)
@@ -37,7 +37,6 @@ function getTransactions($fromsupp)
                        item.description,
                        qty_recd,
                        quantity_inv,
-                       std_cost_unit,
                        act_price,
                        unit_price
                FROM ".TB_PREF."grn_items item,
@@ -102,7 +101,7 @@ function print_outstanding_GRN()
        $SuppTot_Val=0;
        $res = getTransactions($fromsupp);
 
-       While ($GRNs = db_fetch($res))
+       while ($GRNs = db_fetch($res))
        {
                $dec2 = get_qty_dec($GRNs['item_code']);
                if ($Supplier != $GRNs['supplier_id'])
@@ -126,9 +125,9 @@ function print_outstanding_GRN()
                $rep->AmountCol(3, 4, $GRNs['qty_recd'], $dec2);
                $rep->AmountCol(4, 5, $GRNs['quantity_inv'], $dec2);
                $QtyOstg = $GRNs['qty_recd'] - $GRNs['quantity_inv'];
-               $Value = ($GRNs['qty_recd'] - $GRNs['quantity_inv']) * $GRNs['act_price'];
+               $Value = ($GRNs['qty_recd'] - $GRNs['quantity_inv']) * $GRNs['unit_price'];
                $rep->AmountCol(5, 6, $QtyOstg, $dec2);
-               $rep->AmountCol(6, 7, $GRNs['act_price'], $dec);
+               $rep->AmountCol(6, 7, $GRNs['unit_price'], $dec);
                $rep->AmountCol(7, 8, $Value, $dec);
                $Tot_Val += $Value;
                $SuppTot_Val += $Value;
index a6f8a9bc6a57ca4635cc1c09a7149309ef59f5b7..89b417e1fd834be024d6a191017140df75756db9 100644 (file)
@@ -171,8 +171,8 @@ function print_grn_valuation()
                        $trans['unit_price'] *= $rate;
                        $rep->TextCol(4, 5, "--");
                        $rep->AmountCol(5, 6, $trans['qty_recd'] - $trans['quantity_inv'], $qdec);
-                       $rep->AmountCol(7, 8, $trans['unit_price'], $dec);
-                       $amt = round2(($trans['qty_recd'] - $trans['quantity_inv']) * $trans['unit_price'], $dec);
+                       $rep->AmountCol(7, 8, $trans['std_cost_unit'], $dec);
+                       $amt = round2(($trans['qty_recd'] - $trans['quantity_inv']) * $trans['std_cost_unit'], $dec);
                        $rep->AmountCol(8, 9, $amt, $dec);
                        $total += $amt;
                        $qtotal += $trans['qty_recd'] - $trans['quantity_inv'];
index 323f92e0ad845711eb7a43797306716450c59891..84aa9ce6372595ca380371e985178753dea4dace 100644 (file)
@@ -95,8 +95,8 @@ function get_base_taxdata($stock_id, $group_id)
                $amount - price/value to be splitted
                $tax_group - entity tax group
                $tax_included - whether value includes all taxes
-               $vat_factor - 0-1; tax deduction factor
-               $allow_reverse - option for invoice - whether to honour reverse charging
+               $vat_factor - 0-1; tax deduction factor (purchases, not used for now; depends on whthere it is related to exempt or taxed sales)
+               $allow_reverse - option for invoice - whether to honour reverse charging (depends on customer tax status)
 
        Returned array contains calculated values for GL postings and tax registration:
                'Net' - value without tax,
@@ -107,16 +107,26 @@ function get_base_taxdata($stock_id, $group_id)
        and (with numeric keys) detailed info for any applicable tax rate:
                'tax_type_id' - tax type id
                'Value' - charged tax value
-               'Deductible' - tax deductible (can be lower than Value for special goods)
+               'Deductible' - tax deductible (can be lower than Value for special goods or mixed sales structure)
                'Payable' - tax payable
-               'Adjust' - additional adjustemnt to deductible tax due to sales structure factor
+               'Adjust' - additional adjustment to deductible tax due to sales structure factor
                'rate' - tax rate
                'sales_gl_code' - sales tax GL account
                'purchasing_gl_code' - purchase tax GL account
                'tax_type_name' - name of tax type
+
+       Price value is splitted as follows:
+               Tax: sum of Value (for applicable taxes)
+               Net: amount - Tax
+               Cost: Net + sum(Payable-Deductible)
+        for every applicable tax rate:
+               Value: tax calculated or 0
+               Deductible: vat_factor*Value or 0
+               Adjust: Value-Deductible or 0
+               Payable: 0 or Value
 */
 function split_item_price($stock_id, $amount, $group_id, $tax_included=false, $trans_type=ST_SUPPINVOICE, $vat_factor = 1, 
-       $allow_reverse=true, $date=null)
+       $allow_reverse=true)
 {
        global $TS;
 
@@ -187,13 +197,17 @@ function split_item_price($stock_id, $amount, $group_id, $tax_included=false, $t
 
                                if ($taxopt & TAX_DEDUCTIBLE) // tax is deductible
                                {
-                                               $tax['Deductible'] = round2($vat_value*$factor, 2); // [4815] To avoid rounding issues if $dec > 2 decimal places
+                                               $tax['Deductible'] = round2($vat_value*$factor, 2); // avoid rounding issues if $dec > 2 decimal places
                                                $tax['Adjust'] = round2(-(1-$vat_factor)*$factor*$vat_value, $dec); // adjustment due to mixed taxed/exmpt sales activity
                                    } else {
                                                $tax['Deductible'] = 0;
                                                $tax['Adjust'] = 0;
                                        }
-                               $ret_array['Cost'] += $tax['Value'] + ($tax['Payable'] - $tax['Deductible']);// - $tax['Adjust'];
+
+                                       if ($tax['Payable'])
+                                       $ret_array['Cost'] += ($tax['Payable'] - $tax['Deductible']);
+                                   elseif ($tax['Deductible'])
+                                       $ret_array['Cost'] += $tax['Adjust'];
 
                                $ret_array[] = $tax;
                                        $ret_array['Tax'] += $tax['Value'];
@@ -227,7 +241,7 @@ function get_tax_for_items($trans_type, $items, $prices, $shipping_cost, $tax_gr
        foreach($items as $i => $stock_id)
        {
                $taxdata = split_item_price($stock_id, $prices[$i], $tax_group, $tax_included, $trans_type,
-                        $vat_factors ? $vat_factors[$i] : 1, $allow_reverse, $date=null); // FIXME: $date
+                        $vat_factors ? $vat_factors[$i] : 1, $allow_reverse);
 
                foreach ($taxdata as $key => $data)
                {
index 73f30b64fe389c0fc4144284124d899419ead6c5..9dd3519fd1a54b85262f21b9600cbcd3446add6d 100644 (file)
@@ -16,7 +16,6 @@
        TODO:
        . changes in Sales module
        . change all tax related methods in supp_trans to use split_item_price instead of other functions like get_taxes_for_item
-       . all tax types selections in tax group table (beside domestic group) are currently ignored (see FIXME in split_item_price())
 */
 define('TAX_NONE', 0); // none option
 define('TQ_NONE', 0); // none option