Fixed payments reallocation for prepayment orders; blocked edition for open prepaymen...
[fa-stable.git] / includes / db / allocations_db.inc
1 <?php
2 /**********************************************************************
3         Copyright (C) FrontAccounting, LLC.
4         Released under the terms of the GNU General Public License, GPL, 
5         as published by the Free Software Foundation, either version 3 
6         of the License, or (at your option) any later version.
7         This program is distributed in the hope that it will be useful,
8         but WITHOUT ANY WARRANTY; without even the implied warranty of
9         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
10         See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
11 ***********************************************************************/
12 //
13 // Functions below are unified interface to allocations (should supersede currently separate cust/supp allocations in a future)
14 //
15 //----------------------------------------------------------------------------------------
16 //
17 //      Returns table of payments currently allocated to selected transaction.
18 //
19 function get_payments_for($trans_no, $trans_type, $person_id)
20 {
21         $allocations = array();
22
23         $sql = "(SELECT alloc.*, trans.tran_date FROM ".TB_PREF."cust_allocations alloc
24                                 LEFT JOIN ".TB_PREF."debtor_trans trans ON trans.type=alloc.trans_type_from AND trans.trans_no=alloc.trans_no_from
25                         WHERE (trans_type_to=".db_escape($trans_type)." AND trans_no_to=".db_escape($trans_no)." AND person_id=".db_escape($person_id)."))
26                 UNION
27                         (SELECT alloc.*, trans.tran_date FROM ".TB_PREF."supp_allocations alloc
28                                 LEFT JOIN ".TB_PREF."supp_trans trans ON trans.type=alloc.trans_type_from AND trans.trans_no=alloc.trans_no_from
29                         WHERE (trans_type_to=".db_escape($trans_type)." AND trans_no_to=".db_escape($trans_no)." AND person_id=".db_escape($person_id)."))";
30         $result = db_query($sql, "error reading current allocations");
31
32         while($dat = db_fetch($result))
33         {
34                 $allocations[] = $dat;
35         }
36
37         return $allocations;
38 }
39
40 //
41 //      Unified inteface to (re)allocate payments to supp/cust/transaction
42 //
43 function allocate_payment($type_from, $no_from, $type_to, $no_to, $person_id, $amount, $date)
44 {
45         $date = date2sql($date); // FIXME types
46         if (in_array($type_to, array(ST_SALESORDER, ST_CUSTCREDIT, ST_CUSTDELIVERY, ST_SALESINVOICE)))
47                 $allocations = 'cust_allocations';
48         else
49                 $allocations = 'supp_allocations';
50
51         $sql = "DELETE FROM ".TB_PREF.$allocations."
52                 WHERE trans_type_from=".db_escape($type_from)." AND trans_no_from=".db_escape($no_from)
53                 ." AND trans_type_to=".db_escape($type_to)." AND trans_no_to=".db_escape($no_to)." AND person_id=".db_escape($person_id);
54         db_query($sql, "The existing allocations could not be updated");
55         if (floatcmp($amount, 0) != 0)
56         {
57                 $sql = "INSERT INTO ".TB_PREF.$allocations." (amt, date_alloc, trans_type_from, trans_no_from, trans_type_to, trans_no_to, person_id)
58                 VALUES (". db_escape($amount).",'$date',".db_escape($type_from).",".db_escape($no_from)
59                         .",".db_escape($type_to).",".db_escape($no_to).",".db_escape($person_id).")";
60                 db_query($sql, "The existing allocations could not be updated");
61         }
62         if ($allocations == 'cust_allocations') {
63                 update_debtor_trans_allocation($type_from, $no_from, $person_id);
64                 update_debtor_trans_allocation($type_to, $no_to, $person_id);
65         } else {
66                 update_supp_trans_allocation($type_from, $no_from, $person_id);
67                 update_supp_trans_allocation($type_to, $no_to, $person_id);
68         }
69 }
70
71 //----------------------------------------------------------------------------------------
72 //
73 //      Reallocates allocations to selected transaction.
74 //  $allocs is table of payments which should be reallocated
75 //  $free_remainder should be true if old allacations should be freed when not allocated to new transaction.
76 //
77 function reallocate_payments($trans_no, $trans_type, $alloc_date, $max_alloc, $allocs, $person_id, $free_remainder=true)
78 {
79
80         foreach($allocs as $alloc)
81         {
82                 $amount = min($alloc['amt'], $max_alloc);
83                 $remainder = $alloc['amt'] - $amount;
84
85                 $max_alloc = floatcmp($max_alloc, $amount) > 0 ? $max_alloc-$amount : 0;
86
87                 $same_to =  $trans_type == $alloc['trans_type_to'] && $trans_no == $alloc['trans_no_to'];
88
89                 allocate_payment($alloc['trans_type_from'], $alloc['trans_no_from'], $trans_type, $trans_no, $person_id, $amount, $alloc_date);
90
91                 if (!$same_to && ($remainder > 0 || $free_remainder))
92                 {
93                         allocate_payment($alloc['trans_type_from'], $alloc['trans_no_from'], 
94                                 $alloc['trans_type_to'], $alloc['trans_no_to'], $person_id, $free_remainder ? 0 : $remainder, $alloc_date);
95                 }
96                 if (!$free_remainder && $max_alloc==0)
97                         break;
98         }
99 }