Merged last changes from stable.
[fa-stable.git] / includes / ui / allocation_cart.inc
index f67c5f15ba66c7aaca7025c9dfb69a53ea310edf..37c436a0ac3a96b2daa447f0f64985c4d7b014d9 100644 (file)
@@ -22,25 +22,39 @@ class allocation
        var $type;
        var $person_id = '';
        var $person_name = '';
-       var $person_type;       // true - supplier, otherwise customer
+       var $person_type;       // PT_SUPPLIER/PT_CUSTOMER
+       var $person_curr;
        var $date_;
        var $amount = 0; /*Total amount of the transaction in FX */
-       
-       var $allocs; /*array of transactions allocated to */    
+       var $currency;
+
+       var $allocs; /*array of transactions allocated to */
 
-       function allocation($type, $trans_no)
+       function allocation($type, $trans_no, $person_id = null, $person_type_id=null)
        {
                $this->allocs = array();
                
                $this->trans_no = $trans_no;
                $this->type = $type;
-               $this->read(); // read payment or credit
+               if ($person_id)
+                       $this->set_person($person_id, $person_type_id);
+
+               $this->read($type, $trans_no, $person_id, $person_type_id); // read payment or credit
+       }
+
+       function set_person($person_id, $person_type)
+       {
+               $this->person_id = $person_id;
+               $this->person_type = $person_type;
+               $this->person_curr = $person_type == PT_SUPPLIER ?
+                       get_supplier_currency($person_id) : get_customer_currency($person_id);
+               return $this->person_curr;
        }
 
        function add_item($type, $type_no, $date_, $due_date, $amount, $amount_allocated, 
                $current_allocated, $ref)
        {
-               if ($amount > 0)
+               if (floatcmp($amount, 0))
                {
                        $this->allocs[count($this->allocs)] = new allocation_item($type, $type_no, 
                                $date_, $due_date, $amount, $amount_allocated, $current_allocated, $ref);
@@ -55,7 +69,7 @@ class allocation
        function update_item($index, $type, $type_no, $date_, $due_date, 
                $amount, $amount_allocated, $current_allocated, $ref)
        {
-               if ($amount > 0)
+               if (floatcmp($amount, 0))
                {
                        $this->allocs[$index] = new allocation_item($type, $type_no, 
                                $date_, $due_date, $amount, $amount_allocated, $current_allocated, $ref);
@@ -65,7 +79,7 @@ class allocation
                {
                        return false;
                }
-       }       
+       }
        
        function add_or_update_item($type, $type_no, $date_, $due_date, 
                $amount, $amount_allocated, $current_allocated, $ref)
@@ -77,7 +91,7 @@ class allocation
                        {
                                return $this->update_item($i, $type, $type_no, $date_, $due_date, 
                                        $amount, $amount_allocated, $current_allocated, $ref);
-                       }  
+                       }
                }
         return $this->add_item($type, $type_no, $date_, $due_date, 
                $amount, $amount_allocated, $current_allocated, $ref);
@@ -88,65 +102,73 @@ class allocation
        //
        // FIXME - read all transactions below twice seems to be suboptimal
        //
-       function read($type = null, $trans_no = 0
+       function read($type = null, $trans_no = 0, $person_id=null, $person_type_id=null)
        {
-               if ($type == null) {    // re-read
+               if ($type !== null) {   // otherwise re-read
                        $type = $this->type;
                        $trans_no = $this->trans_no;
-               }
-               if ($type == ST_BANKPAYMENT || $type == ST_BANKDEPOSIT) {
-                       $bank_trans = db_fetch(get_bank_trans($type, $trans_no));
-                       $this->person_type = $bank_trans['person_type_id'] == PT_SUPPLIER;
-               } else
-                       $this->person_type = $type == ST_SUPPCREDIT || $type == ST_SUPPAYMENT;
-               $this->allocs = array();
 
-               if ($trans_no) {
-                       $trans = $this->person_type ? get_supp_trans($trans_no, $type) 
-                               : get_customer_trans($trans_no, $type);
+                       if (isset($person_type_id))
+                       {
+                               $this->person_type = $person_type_id;
+                               $this->person_id = $person_id;
+                       } else { // guess person_type_id
+                               if (in_array($type, array(ST_BANKPAYMENT, ST_BANKDEPOSIT)))
+                               {
+                                       $bank_trans = db_fetch(get_bank_trans($type, $trans_no));
+                                       $this->person_type = $bank_trans['person_type_id'];
+                               } else
+                                       $this->person_type = in_array($type, array(ST_SUPPCREDIT, ST_SUPPAYMENT)) ? PT_SUPPLIER : PT_CUSTOMER;
+                       }
 
-                       $this->person_id = $trans[$this->person_type ? 'supplier_id':'debtor_no'];
-                       $this->person_name = $trans[$this->person_type ? "supplier_name":"DebtorName"];
-                       $this->amount = $trans["Total"];
-                       $this->date_ = sql2date($trans["tran_date"]);
-               } 
-               else {
-                       $this->person_id = get_post($this->person_type ? 'supplier_id':'customer_id');
-                       $this->date_ = get_post($this->person_type ? 'DatePaid':'DateBanked', Today());
+                       if ($trans_no) {
+                               $trans = $this->person_type == PT_SUPPLIER ? get_supp_trans($trans_no, $type, $person_id)
+                                       : get_customer_trans($trans_no, $type, $person_id);
+
+                               $this->person_id = $trans[$this->person_type == PT_SUPPLIER ? 'supplier_id':'debtor_no'];
+                               $this->person_name = $trans[$this->person_type == PT_SUPPLIER ? "supplier_name":"DebtorName"];
+                               $this->date_ = sql2date($trans["tran_date"]);
+                               $this->person_curr = $trans['curr_code'];
+                               $this->currency = isset($trans['bank_curr_code']) ? $trans['bank_curr_code'] : $trans['curr_code'];
+                               $this->bank_amount = @$trans["bank_amount"];
+                               $this->amount = $trans["Total"];
+                       }
                }
-               
        /* Now populate the array of possible (and previous actual) allocations 
                for this customer/supplier. First get the transactions that have 
                outstanding balances ie Total-alloc >0 */
 
-               if ($this->person_type)
-                       $trans_items = get_allocatable_to_supp_transactions($this->person_id);
-               else
-                       $trans_items = get_allocatable_to_cust_transactions($this->person_id);
-
-               while ($myrow = db_fetch($trans_items))
+               $this->allocs = array();
+               if ($this->person_id)
                {
-//_vd($myrow);
-                       $this->add_item($myrow["type"], $myrow["trans_no"],
-                               sql2date($myrow["tran_date"]),
-                               sql2date($myrow["due_date"]),
-                               $myrow["Total"], // trans total
-                               $myrow["alloc"], // trans total allocated
-                               0,
-                               $myrow["reference"]); // this allocation
+                       if ($this->person_type==PT_SUPPLIER)
+                               $trans_items = get_allocatable_to_supp_transactions($this->person_id);
+                       else
+                               $trans_items = get_allocatable_to_cust_transactions($this->person_id);
+                       while ($myrow = db_fetch($trans_items))
+                       {
+                               $this->add_item($myrow["type"], $myrow["trans_no"],
+                                       sql2date($myrow["tran_date"]),
+                                       sql2date($myrow["due_date"]),
+                                       $myrow["Total"], // trans total
+                                       $myrow["alloc"], // trans total allocated
+                                       0,
+                                       $myrow["reference"]); // this allocation
+                       }
                }
-               if ($trans_no == 0) return; // this is new payment
+               if ($this->trans_no == 0) return; // this is new payment
 
        /* Now get trans that might have previously been allocated to by this trans
        NB existing entries where still some of the trans outstanding entered from
        above logic will be overwritten with the prev alloc detail below */
 
-               if ($this->person_type)
+               if ($this->person_type==PT_SUPPLIER)
                        $trans_items = get_allocatable_to_supp_transactions($this->person_id, 
-                               $trans_no, $type);
+                               $this->trans_no, $this->type);
                else
                        $trans_items = get_allocatable_to_cust_transactions($this->person_id, 
-                               $trans_no, $type);
+                               $this->trans_no, $this->type);
+
                while ($myrow = db_fetch($trans_items))
                {
 //_vd($myrow);
@@ -164,50 +186,48 @@ class allocation
        {
                begin_transaction();
 
-               if ($this->person_type)
-                       clear_supp_alloctions($this->type, $this->trans_no);
+               if ($this->person_type == PT_SUPPLIER)
+                       clear_supp_alloctions($this->type, $this->trans_no, $this->date_);
                else
                        clear_cust_alloctions($this->type, $this->trans_no);
 
                // now add the new allocations
                $total_allocated = 0;
+               $dec = user_price_dec();
                foreach ($this->allocs as $alloc_item)
                {
                        if ($alloc_item->current_allocated > 0)
                        {
-                               if ($this->person_type) {
-                                       add_supp_allocation($alloc_item->current_allocated,
+                               $amount = round($alloc_item->current_allocated, $dec);
+
+                               if ($this->person_type == PT_SUPPLIER) {
+                                       add_supp_allocation($amount,
                                                $this->type, $this->trans_no,
                                        $alloc_item->type, $alloc_item->type_no, $this->date_);
 
-                                       update_supp_trans_allocation($alloc_item->type, 
-                                               $alloc_item->type_no, $alloc_item->current_allocated);
+                                       update_supp_trans_allocation($alloc_item->type, $alloc_item->type_no);
                                } else {
-                                       add_cust_allocation($alloc_item->current_allocated,
+                                       add_cust_allocation($amount,
                                                $this->type, $this->trans_no,
                                        $alloc_item->type, $alloc_item->type_no, $this->date_);
 
-                                       update_debtor_trans_allocation($alloc_item->type, 
-                                               $alloc_item->type_no, $alloc_item->current_allocated);
+                                       update_debtor_trans_allocation($alloc_item->type, $alloc_item->type_no);
                                }
                                // Exchange Variations Joe Hunt 2008-09-20 ////////////////////
                                if (!in_array($alloc_item->type, array(ST_SALESQUOTE, ST_SALESORDER, ST_PURCHORDER)))
                                 exchange_variation($this->type, $this->trans_no,
                                        $alloc_item->type, $alloc_item->type_no, $this->date_,
-                                       $alloc_item->current_allocated,
-                                       $this->person_type ? PT_SUPPLIER : PT_CUSTOMER);
+                                       $amount, $this->person_type);
 
                                //////////////////////////////////////////////////////////////
                                $total_allocated += $alloc_item->current_allocated;
                        }
 
-               }  //end of the loop through the array of allocations made
-               if ($this->person_type)
-                       update_supp_trans_allocation($this->type, $this->trans_no, 
-                               $total_allocated);
+               }  /*end of the loop through the array of allocations made */
+               if ($this->person_type == PT_SUPPLIER)
+                       update_supp_trans_allocation($this->type, $this->trans_no);
                else
-                       update_debtor_trans_allocation($this->type,     $this->trans_no, 
-                               $total_allocated);
+                       update_debtor_trans_allocation($this->type,     $this->trans_no);
 
                commit_transaction();
 
@@ -258,52 +278,61 @@ function show_allocatable($show_totals) {
        
     $k = $counter = $total_allocated = 0;
 
-       if (count($_SESSION['alloc']->allocs)) 
+       $cart = $_SESSION['alloc'];
+       $supp_ref = in_array($cart->type, array(ST_SUPPCREDIT, ST_SUPPAYMENT, ST_BANKPAYMENT));
+
+       if (count($cart->allocs)) 
        {
+               if ($cart->currency != $cart->person_curr)
+                       display_heading(sprintf(_("Allocated amounts in %s:"), $cart->person_curr));
                start_table(TABLESTYLE, "width=60%");
-               $th = array(_("Transaction Type"), _("#"), _("Ref"), _("Date"), _("Due Date"), _("Amount"),
-                       _("Other Allocations"), _("This Allocation"), _("Left to Allocate"),'','');
+               $th = array(_("Transaction Type"), _("#"), $supp_ref ? _("Supplier Ref"): _("Ref"), _("Date"), _("Due Date"), _("Amount"),
+                       _("Other Allocations"), _("Left to Allocate"), _("This Allocation"),'','');
+
                table_header($th);
 
-               foreach ($_SESSION['alloc']->allocs as $alloc_item)
+               foreach ($cart->allocs as $id => $alloc_item)
                {
-                   if ($alloc_item->amount > $alloc_item->amount_allocated) {
+                   if (floatcmp(abs($alloc_item->amount), $alloc_item->amount_allocated))
+                   {
                                alt_table_row_color($k);
                        label_cell($systypes_array[$alloc_item->type]);
                                label_cell(get_trans_view_str($alloc_item->type, $alloc_item->type_no));
-                               label_cell($alloc_item->ref);
-                       label_cell($alloc_item->date_, "align=right");
+                               label_cell($alloc_item->ref);
+                       label_cell($alloc_item->date_, "align=right");
                        label_cell($alloc_item->due_date, "align=right");
-                       amount_cell($alloc_item->amount);
+                       amount_cell(abs($alloc_item->amount));
                                amount_cell($alloc_item->amount_allocated);
 
-                       $_POST['amount' . $counter] = price_format($alloc_item->current_allocated);
-                       amount_cells(null, "amount" . $counter, price_format('amount' . $counter));
+                       $_POST['amount' . $id] = price_format($alloc_item->current_allocated);
 
-                       $un_allocated = round($alloc_item->amount - $alloc_item->amount_allocated, 6);
-                       amount_cell($un_allocated, false,'', 'maxval'.$counter);
-                               label_cell("<a href='#' name=Alloc$counter onclick='allocate_all(this.name.substr(5));return true;'>"
+                       $un_allocated = round((abs($alloc_item->amount) - $alloc_item->amount_allocated), 6);
+                       amount_cell($un_allocated, false,'', 'maxval'.$id);
+                       amount_cells(null, "amount" . $id);//, input_num('amount' . $id));
+                               label_cell("<a href='#' name=Alloc$id onclick='allocate_all(this.name.substr(5));return true;'>"
                                         . _("All") . "</a>");
-                               label_cell("<a href='#' name=DeAll$counter onclick='allocate_none(this.name.substr(5));return true;'>"
-                                        . _("None") . "</a>".hidden("un_allocated" . $counter
+                               label_cell("<a href='#' name=DeAll$id onclick='allocate_none(this.name.substr(5));return true;'>"
+                                        . _("None") . "</a>".hidden("un_allocated" . $id
                                         price_format($un_allocated), false));
                                end_row();
 
-                       $total_allocated += input_num('amount' . $counter);
-                       }
-                   $counter++;
-               }
+                       $total_allocated += input_num('amount' . $id);
+                       }
+               }
                if ($show_totals) {
                label_row(_("Total Allocated"), price_format($total_allocated),
-                       "colspan=6 align=right", "align=right id='total_allocated'", 3);
+                       "colspan=8 align=right", "align=right id='total_allocated'", 3);
+/*
                        $amount = $_SESSION['alloc']->amount;
 
                        if ($_SESSION['alloc']->type == ST_SUPPCREDIT
                                || $_SESSION['alloc']->type == ST_SUPPAYMENT
                                ||  $_SESSION['alloc']->type == ST_BANKPAYMENT)
                                $amount = -$amount;
-                       
-                       if ($amount - $total_allocated < 0)
+*/
+                       $amount = abs($cart->amount);
+
+                       if (floatcmp($amount, $total_allocated) < 0)
                {
                        $font1 = "<font color=red>";
                        $font2 = "</font>";
@@ -312,12 +341,12 @@ function show_allocatable($show_totals) {
                        $font1 = $font2 = "";
                        $left_to_allocate = price_format($amount - $total_allocated);
                label_row(_("Left to Allocate"), $font1 . $left_to_allocate . $font2, 
-                               "colspan=6 align=right", "nowrap align=right id='left_to_allocate'",
+                               "colspan=8 align=right", "nowrap align=right id='left_to_allocate'",
                                 3);
                }
                end_table(1);
        }
-       hidden('TotalNumberOfAllocs', $counter);
+       hidden('TotalNumberOfAllocs', count($cart->allocs));
 }
 //--------------------------------------------------------------------------------
 
@@ -327,8 +356,10 @@ function check_allocations()
 
        $total_allocated = 0;
 
-       for ($counter = 0; $counter < $_POST["TotalNumberOfAllocs"]; $counter++)
-       if (isset($_POST['amount' . $counter])) {
+       for ($counter = 0; $counter < get_post("TotalNumberOfAllocs"); $counter++)
+       {
+               if (!isset($_POST['amount'.$counter])) continue;
+
                if (!check_num('amount' . $counter, 0))
                {
                        display_error(_("The entry for one or more amounts is invalid or negative."));
@@ -336,9 +367,11 @@ function check_allocations()
                        return false;
                 }
 
-                 /*Now check to see that the AllocAmt is no greater than the
-                amount left to be allocated against the transaction under review */
-                if (input_num('amount' . $counter) > input_num('un_allocated' . $counter))
+                 /* Now check to see that the AllocAmt is no greater than the
+                amount left to be allocated against the transaction under review;
+                skip check if no allocation is set to avoid deadlock on mistakenly overallocated transactions*/
+                $allocated = input_num('amount' . $counter);
+                if ($allocated && ($allocated > input_num('un_allocated' . $counter)))
                 {
                        display_error(_("At least one transaction is overallocated."));
                        set_focus('amount'.$counter);
@@ -349,12 +382,13 @@ function check_allocations()
 
                 $total_allocated += input_num('amount' . $counter);
        }
-
+/*
        $amount = $_SESSION['alloc']->amount;
-       
 
        if (in_array($_SESSION['alloc']->type, array(ST_BANKPAYMENT, ST_SUPPCREDIT, ST_SUPPAYMENT)))
                $amount = -$amount;
+*/
+       $amount = abs($_SESSION['alloc']->amount);
 
        if ($total_allocated - ($amount + input_num('discount'))  > $SysPrefs->allocation_settled_allowance())
        {
@@ -364,5 +398,3 @@ function check_allocations()
 
        return true;
 }
-
-?>