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 ***********************************************************************/
13 Class for supplier/customer payment/credit allocations edition
16 //-----------------------------------------------------------------------------------
24 var $person_name = '';
27 var $amount = 0; /*Total amount of the transaction in FX */
29 var $allocs; /*array of transactions allocated to */
31 function allocation($type, $trans_no)
33 $this->allocs = array();
35 $this->trans_no = $trans_no;
37 $this->read(); // read payment or credit
40 function add_item($type, $type_no, $date_, $due_date, $amount, $amount_allocated,
45 $this->allocs[count($this->allocs)] = new allocation_item($type, $type_no,
46 $date_, $due_date, $amount, $amount_allocated, $current_allocated);
55 function update_item($index, $type, $type_no, $date_, $due_date,
56 $amount, $amount_allocated, $current_allocated)
60 $this->allocs[$index] = new allocation_item($type, $type_no,
61 $date_, $due_date, $amount, $amount_allocated, $current_allocated);
70 function add_or_update_item($type, $type_no, $date_, $due_date,
71 $amount, $amount_allocated, $current_allocated)
73 for ($i = 0; $i < count($this->allocs); $i++)
75 $item = $this->allocs[$i];
76 if (($item->type == $type) && ($item->type_no == $type_no))
78 return $this->update_item($i, $type, $type_no, $date_, $due_date,
79 $amount, $amount_allocated, $current_allocated);
82 return $this->add_item($type, $type_no, $date_, $due_date,
83 $amount, $amount_allocated, $current_allocated);
87 // Read payment or credit current/available allocations to cart.
89 function read($type = null, $trans_no = 0)
91 if ($type == null) { // re-read
93 $trans_no = $this->trans_no;
95 if ($type == ST_BANKPAYMENT || $type == ST_BANKDEPOSIT) {
96 $bank_trans = db_fetch(get_bank_trans($type, $trans_no));
97 $this->person_type = $bank_trans['person_type_id'] == PT_SUPPLIER;
99 $this->person_type = $type == ST_SUPPCREDIT || $type == ST_SUPPAYMENT;
100 $this->allocs = array();
103 $trans = $this->person_type ? get_supp_trans($trans_no, $type)
104 : get_customer_trans($trans_no, $type);
106 $this->person_id = $trans[$this->person_type ? 'supplier_id':'debtor_no'];
107 $this->person_name = $trans[$this->person_type ? "supplier_name":"DebtorName"];
108 $this->amount = $trans["Total"];
109 $this->date_ = sql2date($trans["tran_date"]);
112 $this->person_id = get_post($this->person_type ? 'supplier_id':'customer_id');
113 $this->date_ = get_post($this->person_type ? 'DatePaid':'DateBanked', Today());
116 /* Now populate the array of possible (and previous actual) allocations
117 for this customer/supplier. First get the transactions that have
118 outstanding balances ie Total-alloc >0 */
120 if ($this->person_type)
121 $trans_items = get_allocatable_to_supp_transactions($this->person_id);
123 $trans_items = get_allocatable_to_cust_transactions($this->person_id);
125 while ($myrow = db_fetch($trans_items))
127 $this->add_item($myrow["type"], $myrow["trans_no"],
128 sql2date($myrow["tran_date"]),
129 sql2date($myrow["due_date"]),
130 $myrow["Total"], // trans total
131 $myrow["alloc"], // trans total allocated
132 0); // this allocation
135 if ($trans_no == 0) return; // this is new payment
137 /* Now get trans that might have previously been allocated to by this trans
138 NB existing entries where still some of the trans outstanding entered from
139 above logic will be overwritten with the prev alloc detail below */
141 if ($this->person_type)
142 $trans_items = get_allocatable_to_supp_transactions($this->person_id,
145 $trans_items = get_allocatable_to_cust_transactions($this->person_id,
148 while ($myrow = db_fetch($trans_items))
150 $this->add_or_update_item ($myrow["type"], $myrow["trans_no"],
151 sql2date($myrow["tran_date"]),
152 sql2date($myrow["due_date"]),
154 $myrow["alloc"] - $myrow["amt"], $myrow["amt"]);
158 // Update allocations in database.
164 if ($this->person_type)
165 clear_supp_alloctions($this->type, $this->trans_no, $this->date_);
167 clear_cust_alloctions($this->type, $this->trans_no, $this->date_);
169 // now add the new allocations
170 $total_allocated = 0;
171 foreach ($this->allocs as $alloc_item)
173 if ($alloc_item->current_allocated > 0)
175 if ($this->person_type) {
176 add_supp_allocation($alloc_item->current_allocated,
177 $this->type, $this->trans_no,
178 $alloc_item->type, $alloc_item->type_no, $this->date_);
180 update_supp_trans_allocation($alloc_item->type,
181 $alloc_item->type_no, $alloc_item->current_allocated);
183 add_cust_allocation($alloc_item->current_allocated,
184 $this->type, $this->trans_no,
185 $alloc_item->type, $alloc_item->type_no, $this->date_);
187 update_debtor_trans_allocation($alloc_item->type,
188 $alloc_item->type_no, $alloc_item->current_allocated);
190 // Exchange Variations Joe Hunt 2008-09-20 ////////////////////
192 exchange_variation($this->type, $this->trans_no,
193 $alloc_item->type, $alloc_item->type_no, $this->date_,
194 $alloc_item->current_allocated,
199 //////////////////////////////////////////////////////////////
200 $total_allocated += $alloc_item->current_allocated;
203 } /*end of the loop through the array of allocations made */
204 if ($this->person_type)
205 update_supp_trans_allocation($this->type, $this->trans_no,
208 update_debtor_trans_allocation($this->type, $this->trans_no,
211 commit_transaction();
217 //-----------------------------------------------------------------------------------
219 class allocation_item
228 var $amount_allocated;
231 var $current_allocated;
233 function allocation_item ($type, $type_no, $date_, $due_date, $amount,
234 $amount_allocated, $current_allocated)
238 $this->type_no = $type_no;
240 $this->date_ = $date_;
241 $this->due_date = $due_date;
243 $this->amount = $amount;
244 $this->amount_allocated = $amount_allocated;
245 $this->current_allocated = $current_allocated;
249 //--------------------------------------------------------------------------------
251 function show_allocatable($show_totals) {
253 global $table_style, $systypes_array;
255 $k = $counter = $total_allocated = 0;
257 if (count($_SESSION['alloc']->allocs))
259 start_table("$table_style width=60%");
260 $th = array(_("Transaction Type"), _("#"), _("Date"), _("Due Date"), _("Amount"),
261 _("Other Allocations"), _("This Allocation"), _("Left to Allocate"),'','');
264 foreach ($_SESSION['alloc']->allocs as $alloc_item)
266 alt_table_row_color($k);
267 label_cell($systypes_array[$alloc_item->type]);
268 label_cell(get_trans_view_str($alloc_item->type, $alloc_item->type_no));
269 label_cell($alloc_item->date_, "align=right");
270 label_cell($alloc_item->due_date, "align=right");
271 amount_cell($alloc_item->amount);
272 amount_cell($alloc_item->amount_allocated);
274 $_POST['amount' . $counter] = price_format($alloc_item->current_allocated);
275 amount_cells(null, "amount" . $counter, price_format('amount' . $counter));
277 $un_allocated = round($alloc_item->amount - $alloc_item->amount_allocated, 6);
278 amount_cell($un_allocated);
279 label_cell("<a href='#' name=Alloc$counter onclick='allocate_all(this.name.substr(5));return true;'>"
280 . _("All") . "</a>");
281 label_cell("<a href='#' name=DeAll$counter onclick='allocate_none(this.name.substr(5));return true;'>"
282 . _("None") . "</a>".hidden("un_allocated" . $counter,
283 price_format($un_allocated), false));
286 $total_allocated += input_num('amount' . $counter);
290 label_row(_("Total Allocated"), price_format($total_allocated),
291 "colspan=6 align=right", "align=right id='total_allocated'", 3);
292 $amount = $_SESSION['alloc']->amount;
294 if ($_SESSION['alloc']->type == ST_SUPPCREDIT
295 || $_SESSION['alloc']->type == ST_SUPPAYMENT
296 || $_SESSION['alloc']->type == ST_BANKPAYMENT)
299 if ($amount - $total_allocated < 0)
301 $font1 = "<font color=red>";
305 $font1 = $font2 = "";
306 $left_to_allocate = price_format($amount - $total_allocated);
307 label_row(_("Left to Allocate"), $font1 . $left_to_allocate . $font2,
308 "colspan=6 align=right", "nowrap align=right id='left_to_allocate'",
313 hidden('TotalNumberOfAllocs', $counter);
315 //--------------------------------------------------------------------------------
317 function check_allocations()
321 $total_allocated = 0;
323 for ($counter = 0; $counter < $_POST["TotalNumberOfAllocs"]; $counter++)
325 if (!check_num('amount' . $counter, 0))
327 display_error(_("The entry for one or more amounts is invalid or negative."));
328 set_focus('amount'.$counter);
332 /*Now check to see that the AllocAmt is no greater than the
333 amount left to be allocated against the transaction under review */
334 if (input_num('amount' . $counter) > get_post('un_allocated' . $counter))
336 //$_POST['amount' . $counter] = $_POST['un_allocated' . $counter];
339 $_SESSION['alloc']->allocs[$counter]->current_allocated = input_num('amount' . $counter);
341 $total_allocated += input_num('amount' . $counter);
344 $amount = $_SESSION['alloc']->amount;
345 if ($_SESSION['alloc']->type == 21 || $_SESSION['alloc']->type == 22)
348 if ($total_allocated - ($amount + input_num('discount')) > $SysPrefs->allocation_settled_allowance())
350 display_error(_("These allocations cannot be processed because the amount allocated is more than the total amount left to allocate."));