Customer Payments, Payments to Supplier: improved readbility and multiply cleanups...
[fa-stable.git] / includes / ui / allocation_cart.inc
index d408c80a6d0c52e4d7419974af23a749bf1ad089..1be54f5ca61442256d3eedde74d47efbf7172178 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,64 +102,72 @@ 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)
                {
-                       $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))
                {
@@ -163,50 +185,47 @@ class allocation
        {
                begin_transaction();
 
-               if ($this->person_type)
+               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, $this->date_);
 
                // 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 ////////////////////
                                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);
+               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();
 
@@ -257,50 +276,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)
-           {
-                       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->due_date, "align=right");
-               amount_cell($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));
-
-               $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;'>"
-                                . _("All") . "</a>");
-                       label_cell("<a href='#' name=DeAll$counter onclick='allocate_none(this.name.substr(5));return true;'>"
-                                . _("None") . "</a>".hidden("un_allocated" . $counter, 
-                                price_format($un_allocated), false));
-                       end_row();
-
-               $total_allocated += input_num('amount' . $counter);
-                   $counter++;
-               }
+               foreach ($cart->allocs as $id => $alloc_item)
+               {
+                   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->due_date, "align=right");
+                       amount_cell(abs($alloc_item->amount));
+                               amount_cell($alloc_item->amount_allocated);
+
+                       $_POST['amount' . $id] = price_format($alloc_item->current_allocated);
+
+                       $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$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' . $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>";
@@ -309,12 +339,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));
 }
 //--------------------------------------------------------------------------------
 
@@ -324,8 +354,9 @@ function check_allocations()
 
        $total_allocated = 0;
 
-       for ($counter = 0; $counter < $_POST["TotalNumberOfAllocs"]; $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."));
@@ -333,9 +364,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);
@@ -346,12 +379,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())
        {
@@ -361,5 +395,3 @@ function check_allocations()
 
        return true;
 }
-
-?>