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,
195 $this->person_type ? PT_SUPPLIER : PT_CUSTOMER);
198 //////////////////////////////////////////////////////////////
199 $total_allocated += $alloc_item->current_allocated;
202 } /*end of the loop through the array of allocations made */
203 if ($this->person_type)
204 update_supp_trans_allocation($this->type, $this->trans_no,
207 update_debtor_trans_allocation($this->type, $this->trans_no,
210 commit_transaction();
216 //-----------------------------------------------------------------------------------
218 class allocation_item
227 var $amount_allocated;
230 var $current_allocated;
232 function allocation_item ($type, $type_no, $date_, $due_date, $amount,
233 $amount_allocated, $current_allocated)
237 $this->type_no = $type_no;
239 $this->date_ = $date_;
240 $this->due_date = $due_date;
242 $this->amount = $amount;
243 $this->amount_allocated = $amount_allocated;
244 $this->current_allocated = $current_allocated;
248 //--------------------------------------------------------------------------------
250 function show_allocatable($show_totals) {
252 global $systypes_array;
254 $k = $counter = $total_allocated = 0;
256 if (count($_SESSION['alloc']->allocs))
258 start_table(TABLESTYLE, "width=60%");
259 $th = array(_("Transaction Type"), _("#"), _("Date"), _("Due Date"), _("Amount"),
260 _("Other Allocations"), _("This Allocation"), _("Left to Allocate"),'','');
263 foreach ($_SESSION['alloc']->allocs as $alloc_item)
265 alt_table_row_color($k);
266 label_cell($systypes_array[$alloc_item->type]);
267 label_cell(get_trans_view_str($alloc_item->type, $alloc_item->type_no));
268 label_cell($alloc_item->date_, "align=right");
269 label_cell($alloc_item->due_date, "align=right");
270 amount_cell($alloc_item->amount);
271 amount_cell($alloc_item->amount_allocated);
273 $_POST['amount' . $counter] = price_format($alloc_item->current_allocated);
274 amount_cells(null, "amount" . $counter, price_format('amount' . $counter));
276 $un_allocated = round($alloc_item->amount - $alloc_item->amount_allocated, 6);
277 amount_cell($un_allocated, false,'', 'maxval'.$counter);
278 label_cell("<a href='#' name=Alloc$counter onclick='allocate_all(this.name.substr(5));return true;'>"
279 . _("All") . "</a>");
280 label_cell("<a href='#' name=DeAll$counter onclick='allocate_none(this.name.substr(5));return true;'>"
281 . _("None") . "</a>".hidden("un_allocated" . $counter,
282 price_format($un_allocated), false));
285 $total_allocated += input_num('amount' . $counter);
289 label_row(_("Total Allocated"), price_format($total_allocated),
290 "colspan=6 align=right", "align=right id='total_allocated'", 3);
291 $amount = $_SESSION['alloc']->amount;
293 if ($_SESSION['alloc']->type == ST_SUPPCREDIT
294 || $_SESSION['alloc']->type == ST_SUPPAYMENT
295 || $_SESSION['alloc']->type == ST_BANKPAYMENT)
298 if ($amount - $total_allocated < 0)
300 $font1 = "<font color=red>";
304 $font1 = $font2 = "";
305 $left_to_allocate = price_format($amount - $total_allocated);
306 label_row(_("Left to Allocate"), $font1 . $left_to_allocate . $font2,
307 "colspan=6 align=right", "nowrap align=right id='left_to_allocate'",
312 hidden('TotalNumberOfAllocs', $counter);
314 //--------------------------------------------------------------------------------
316 function check_allocations()
320 $total_allocated = 0;
322 for ($counter = 0; $counter < $_POST["TotalNumberOfAllocs"]; $counter++)
324 if (!check_num('amount' . $counter, 0))
326 display_error(_("The entry for one or more amounts is invalid or negative."));
327 set_focus('amount'.$counter);
331 /*Now check to see that the AllocAmt is no greater than the
332 amount left to be allocated against the transaction under review */
333 if (input_num('amount' . $counter) > get_post('un_allocated' . $counter))
335 display_error(_("At least one transaction is overallocated."));
336 set_focus('amount'.$counter);
340 $_SESSION['alloc']->allocs[$counter]->current_allocated = input_num('amount' . $counter);
342 $total_allocated += input_num('amount' . $counter);
345 $amount = $_SESSION['alloc']->amount;
348 if (in_array($_SESSION['alloc']->type, array(ST_BANKPAYMENT, ST_SUPPCREDIT, ST_SUPPAYMENT)))
351 if ($total_allocated - ($amount + input_num('discount')) > $SysPrefs->allocation_settled_allowance())
353 display_error(_("These allocations cannot be processed because the amount allocated is more than the total amount left to allocate."));