By changing a simple sentence in allocation_cart.inc, the customer/supplier payments...
[fa-stable.git] / includes / ui / allocation_cart.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         Class for supplier/customer payment/credit allocations edition
14         and related helpers.
15 */
16 //-----------------------------------------------------------------------------------
17
18 class allocation 
19 {
20
21         var $trans_no; 
22         var $type;
23         var $person_id = '';
24         var $person_name = '';
25         var $date_;
26         var $amount = 0; /*Total amount of the transaction in FX */
27         
28         var $allocs; /*array of transactions allocated to */    
29
30         function allocation($type, $trans_no)
31         {
32                 $this->allocs = array();
33                 
34                 $this->trans_no = $trans_no;
35                 $this->type = $type;
36                 $this->read(); // read payment or credit
37         }
38
39         function add_item($type, $type_no, $date_, $due_date, $amount, $amount_allocated, 
40                 $current_allocated)
41         {
42                 if ($amount > 0)
43                 {
44                         $this->allocs[count($this->allocs)] = new allocation_item($type, $type_no, 
45                                 $date_, $due_date, $amount, $amount_allocated, $current_allocated);
46                         return true;
47                 } 
48                 else 
49                 {
50                         return false;
51                 }
52         }
53         
54         function update_item($index, $type, $type_no, $date_, $due_date, 
55                 $amount, $amount_allocated, $current_allocated)
56         {
57                 if ($amount > 0)
58                 {
59                         $this->allocs[$index] = new allocation_item($type, $type_no, 
60                                 $date_, $due_date, $amount, $amount_allocated, $current_allocated);
61                         return true;
62                 } 
63                 else 
64                 {
65                         return false;
66                 }
67         }       
68         
69         function add_or_update_item($type, $type_no, $date_, $due_date, 
70                 $amount, $amount_allocated, $current_allocated)
71         {
72                 for ($i = 0; $i < count($this->allocs); $i++) 
73                 {
74                         $item = $this->allocs[$i];
75                         if (($item->type == $type) && ($item->type_no == $type_no)) 
76                         {
77                                 return $this->update_item($i, $type, $type_no, $date_, $due_date, 
78                                         $amount, $amount_allocated, $current_allocated);
79                         }  
80                 }
81         return $this->add_item($type, $type_no, $date_, $due_date, 
82                 $amount, $amount_allocated, $current_allocated);
83         }                                               
84
85         //
86         //      Read payment or credit current/available allocations to cart.
87         //
88         function read($type = null, $trans_no = 0) 
89         {
90                 if ($type == null) {    // re-read
91                         $type = $this->type;
92                         $trans_no = $this->trans_no;
93                 }
94                 
95                 $sup = $type == 21 || $type == 22;
96                 $this->allocs = array();
97
98                 if ($trans_no) {
99                         $trans = $sup ? get_supp_trans($trans_no, $type) 
100                                 : get_customer_trans($trans_no, $type);
101
102                         $this->person_id = $trans[$sup ? 'supplier_id':'debtor_no'];
103                         $this->person_name = $trans[$sup ? "supplier_name":"DebtorName"];
104                         $this->amount = $trans["Total"];
105                         $this->date_ = sql2date($trans["tran_date"]);
106                 } 
107                 else {
108                         $this->person_id = get_post($sup ? 'supplier_id':'customer_id');
109                         $this->date_ = get_post($sup ? 'DatePaid':'DateBanked', Today());
110                 }
111
112         /* Now populate the array of possible (and previous actual) allocations 
113                 for this customer/supplier. First get the transactions that have 
114                 outstanding balances ie Total-alloc >0 */
115
116                 if ($sup)
117                         $trans_items = get_allocatable_to_supp_transactions($this->person_id);
118                 else
119                         $trans_items = get_allocatable_to_cust_transactions($this->person_id);
120
121                 while ($myrow = db_fetch($trans_items))
122                 {
123                         $this->add_item($myrow["type"], $myrow["trans_no"],
124                                 sql2date($myrow["tran_date"]),
125                                 sql2date($myrow["due_date"]),
126                                 $myrow["Total"], // trans total
127                                 $myrow["alloc"], // trans total allocated
128                                 0); // this allocation
129                 }
130
131                 if ($trans_no == 0) return; // this is new payment
132
133         /* Now get trans that might have previously been allocated to by this trans
134         NB existing entries where still some of the trans outstanding entered from
135         above logic will be overwritten with the prev alloc detail below */
136
137                 if ($sup)
138                         $trans_items = get_allocatable_to_supp_transactions($this->person_id, 
139                                 $trans_no, $type);
140                 else
141                         $trans_items = get_allocatable_to_cust_transactions($this->person_id, 
142                                 $trans_no, $type);
143         
144                 while ($myrow = db_fetch($trans_items))
145                 {
146                         $this->add_or_update_item ($myrow["type"], $myrow["trans_no"],
147                                 sql2date($myrow["tran_date"]),
148                                 sql2date($myrow["due_date"]),
149                                 $myrow["Total"],
150                                 $myrow["alloc"] - $myrow["amt"], $myrow["amt"]);
151                 }
152         }
153         //
154         //      Update allocations in database.
155         //
156         function write()
157         {
158                 $sup = $this->type == 21 || $this->type == 22;
159
160                 begin_transaction();
161
162                 if ($sup)
163                         clear_supp_alloctions($this->type, $this->trans_no, $this->date_);
164                 else
165                         clear_cust_alloctions($this->type, $this->trans_no, $this->date_);
166
167                 // now add the new allocations
168                 $total_allocated = 0;
169                 foreach ($this->allocs as $alloc_item)
170                 {
171                         if ($alloc_item->current_allocated > 0)
172                         {
173                                 if ($sup) {
174                                         add_supp_allocation($alloc_item->current_allocated,
175                                                 $this->type, $this->trans_no,
176                                         $alloc_item->type, $alloc_item->type_no, $this->date_);
177
178                                         update_supp_trans_allocation($alloc_item->type, 
179                                                 $alloc_item->type_no, $alloc_item->current_allocated);
180                                 } else {
181                                         add_cust_allocation($alloc_item->current_allocated,
182                                                 $this->type, $this->trans_no,
183                                         $alloc_item->type, $alloc_item->type_no, $this->date_);
184                         
185                                         update_debtor_trans_allocation($alloc_item->type, 
186                                                 $alloc_item->type_no, $alloc_item->current_allocated);
187                                 }
188                                 // Exchange Variations Joe Hunt 2008-09-20 ////////////////////
189
190                                 exchange_variation($this->type, $this->trans_no,
191                                         $alloc_item->type, $alloc_item->type_no, $this->date_,
192                                         $alloc_item->current_allocated,
193                                         $sup ? payment_person_types::supplier() 
194                                                 : payment_person_types::customer());
195                                 
196
197                                 //////////////////////////////////////////////////////////////
198                                 $total_allocated += $alloc_item->current_allocated;
199                         }
200
201                 }  /*end of the loop through the array of allocations made */
202                 if ($sup)
203                         update_supp_trans_allocation($this->type, $this->trans_no, 
204                                 $total_allocated);
205                 else
206                         update_debtor_trans_allocation($this->type,     $this->trans_no, 
207                                 $total_allocated);
208         
209                 commit_transaction();
210
211         }
212
213
214
215 //-----------------------------------------------------------------------------------
216
217 class allocation_item 
218 {
219
220         var $type;
221         var $type_no;
222         
223         var $date_;
224         var $due_date;
225         
226         var $amount_allocated;
227         var $amount;
228         
229         var $current_allocated;
230         
231         function allocation_item ($type, $type_no, $date_, $due_date, $amount, 
232                 $amount_allocated, $current_allocated)
233         {
234
235                 $this->type = $type;
236                 $this->type_no = $type_no;
237                 
238                 $this->date_ = $date_;
239                 $this->due_date = $due_date;
240                 
241                 $this->amount = $amount;
242                 $this->amount_allocated = $amount_allocated;
243                 $this->current_allocated = $current_allocated;
244         }
245 }
246
247 //--------------------------------------------------------------------------------
248
249 function show_allocatable($show_totals) {
250
251         global $table_style;
252         
253     $k = $counter = $total_allocated = 0;
254
255         if (count($_SESSION['alloc']->allocs)) 
256         {
257                 start_table("$table_style width=60%");
258                 $th = array(_("Transaction Type"), _("#"), _("Date"), _("Due Date"), _("Amount"),
259                         _("Other Allocations"), _("This Allocation"), _("Left to Allocate"),'','');
260                 table_header($th);
261
262                 foreach ($_SESSION['alloc']->allocs as $alloc_item)
263             {
264                         alt_table_row_color($k);
265                 label_cell(systypes::name($alloc_item->type));
266                         label_cell(get_trans_view_str($alloc_item->type, $alloc_item->type_no));
267                 label_cell($alloc_item->date_, "align=right");
268                 label_cell($alloc_item->due_date, "align=right");
269                 amount_cell($alloc_item->amount);
270                         amount_cell($alloc_item->amount_allocated);
271
272                 $_POST['amount' . $counter] = price_format($alloc_item->current_allocated);
273                 amount_cells(null, "amount" . $counter, price_format('amount' . $counter));
274
275                 $un_allocated = round($alloc_item->amount - $alloc_item->amount_allocated, 6);
276                 amount_cell($un_allocated);
277                         label_cell("<a href='#' name=Alloc$counter onclick='allocate_all(this.name.substr(5));return true;'>"
278                                  . _("All") . "</a>");
279                         label_cell("<a href='#' name=DeAll$counter onclick='allocate_none(this.name.substr(5));return true;'>"
280                                  . _("None") . "</a>".hidden("un_allocated" . $counter, 
281                                  price_format($un_allocated), false));
282                         end_row();
283
284                 $total_allocated += input_num('amount' . $counter);
285                     $counter++;
286                 }
287                 if ($show_totals) {
288                 label_row(_("Total Allocated"), price_format($total_allocated),
289                         "colspan=6 align=right", "align=right id='total_allocated'", 3);
290                         $amount = $_SESSION['alloc']->amount;
291
292                         if ($_SESSION['alloc']->type == 21 || $_SESSION['alloc']->type == 22) 
293                                 $amount = -$amount;
294                         
295                         if ($amount - $total_allocated < 0)
296                 {
297                         $font1 = "<font color=red>";
298                         $font2 = "</font>";
299             }
300                 else
301                         $font1 = $font2 = "";
302                         $left_to_allocate = price_format($amount - $total_allocated);
303                 label_row(_("Left to Allocate"), $font1 . $left_to_allocate . $font2, 
304                                 "colspan=6 align=right", "nowrap align=right id='left_to_allocate'",
305                                  3);
306                 }
307                 end_table(1);
308         }
309         hidden('TotalNumberOfAllocs', $counter);
310 }
311 //--------------------------------------------------------------------------------
312
313 function check_allocations()
314 {
315         $total_allocated = 0;
316
317         for ($counter = 0; $counter < $_POST["TotalNumberOfAllocs"]; $counter++)
318         {
319                 if (!check_num('amount' . $counter, 0))
320                 {
321                         display_error(_("The entry for one or more amounts is invalid or negative."));
322                         set_focus('amount'.$counter);
323                         return false;
324                  }
325
326                   /*Now check to see that the AllocAmt is no greater than the
327                  amount left to be allocated against the transaction under review */
328                  if (input_num('amount' . $counter) > get_post('un_allocated' . $counter))
329                  {
330                      //$_POST['amount' . $counter] = $_POST['un_allocated' . $counter];
331                  }
332
333                  $_SESSION['alloc']->allocs[$counter]->current_allocated = input_num('amount' . $counter);
334
335                  $total_allocated += input_num('amount' . $counter);
336         }
337
338         $amount = $_SESSION['alloc']->amount;
339         if ($_SESSION['alloc']->type == 21 || $_SESSION['alloc']->type == 22) 
340                 $amount = -$amount;
341
342         if ($total_allocated - ($amount + input_num('discount'))  > sys_prefs::allocation_settled_allowance())
343         {
344                 display_error(_("These allocations cannot be processed because the amount allocated is more than the total amount left to allocate."));
345                 return false;
346         }
347
348         return true;
349 }
350
351 ?>