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 = '';
25 var $person_type; // true - supplier, otherwise customer
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,
41 $current_allocated, $ref)
45 $this->allocs[count($this->allocs)] = new allocation_item($type, $type_no,
46 $date_, $due_date, $amount, $amount_allocated, $current_allocated, $ref);
55 function update_item($index, $type, $type_no, $date_, $due_date,
56 $amount, $amount_allocated, $current_allocated, $ref)
60 $this->allocs[$index] = new allocation_item($type, $type_no,
61 $date_, $due_date, $amount, $amount_allocated, $current_allocated, $ref);
70 function add_or_update_item($type, $type_no, $date_, $due_date,
71 $amount, $amount_allocated, $current_allocated, $ref)
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, $ref);
82 return $this->add_item($type, $type_no, $date_, $due_date,
83 $amount, $amount_allocated, $current_allocated, $ref);
87 // Read payment or credit current/available allocations to cart.
89 // FIXME - read all transactions below twice seems to be suboptimal
91 function read($type = null, $trans_no = 0)
93 if ($type == null) { // re-read
95 $trans_no = $this->trans_no;
97 if ($type == ST_BANKPAYMENT || $type == ST_BANKDEPOSIT) {
98 $bank_trans = db_fetch(get_bank_trans($type, $trans_no));
99 $this->person_type = $bank_trans['person_type_id'] == PT_SUPPLIER;
101 $this->person_type = $type == ST_SUPPCREDIT || $type == ST_SUPPAYMENT;
102 $this->allocs = array();
105 $trans = $this->person_type ? get_supp_trans($trans_no, $type)
106 : get_customer_trans($trans_no, $type);
108 $this->person_id = $trans[$this->person_type ? 'supplier_id':'debtor_no'];
109 $this->person_name = $trans[$this->person_type ? "supplier_name":"DebtorName"];
110 $this->amount = $trans["Total"];
111 $this->date_ = sql2date($trans["tran_date"]);
114 $this->person_id = get_post($this->person_type ? 'supplier_id':'customer_id');
115 $this->date_ = get_post($this->person_type ? 'DatePaid':'DateBanked', Today());
118 /* Now populate the array of possible (and previous actual) allocations
119 for this customer/supplier. First get the transactions that have
120 outstanding balances ie Total-alloc >0 */
122 if ($this->person_type)
123 $trans_items = get_allocatable_to_supp_transactions($this->person_id);
125 $trans_items = get_allocatable_to_cust_transactions($this->person_id);
127 while ($myrow = db_fetch($trans_items))
130 $this->add_item($myrow["type"], $myrow["trans_no"],
131 sql2date($myrow["tran_date"]),
132 sql2date($myrow["due_date"]),
133 $myrow["Total"], // trans total
134 $myrow["alloc"], // trans total allocated
136 $myrow["reference"]); // this allocation
138 if ($trans_no == 0) return; // this is new payment
140 /* Now get trans that might have previously been allocated to by this trans
141 NB existing entries where still some of the trans outstanding entered from
142 above logic will be overwritten with the prev alloc detail below */
144 if ($this->person_type)
145 $trans_items = get_allocatable_to_supp_transactions($this->person_id,
148 $trans_items = get_allocatable_to_cust_transactions($this->person_id,
150 while ($myrow = db_fetch($trans_items))
153 $this->add_or_update_item ($myrow["type"], $myrow["trans_no"],
154 sql2date($myrow["tran_date"]),
155 sql2date($myrow["due_date"]),
157 $myrow["alloc"] - $myrow["amt"], $myrow["amt"], $myrow["reference"]);
161 // Update allocations in database.
167 if ($this->person_type)
168 clear_supp_alloctions($this->type, $this->trans_no);
170 clear_cust_alloctions($this->type, $this->trans_no);
172 // now add the new allocations
173 $total_allocated = 0;
174 foreach ($this->allocs as $alloc_item)
176 if ($alloc_item->current_allocated > 0)
178 if ($this->person_type) {
179 add_supp_allocation($alloc_item->current_allocated,
180 $this->type, $this->trans_no,
181 $alloc_item->type, $alloc_item->type_no, $this->date_);
183 update_supp_trans_allocation($alloc_item->type,
184 $alloc_item->type_no, $alloc_item->current_allocated);
186 add_cust_allocation($alloc_item->current_allocated,
187 $this->type, $this->trans_no,
188 $alloc_item->type, $alloc_item->type_no, $this->date_);
190 update_debtor_trans_allocation($alloc_item->type,
191 $alloc_item->type_no, $alloc_item->current_allocated);
193 // Exchange Variations Joe Hunt 2008-09-20 ////////////////////
194 if (!in_array($alloc_item->type, array(ST_SALESQUOTE, ST_SALESORDER, ST_PURCHORDER)))
195 exchange_variation($this->type, $this->trans_no,
196 $alloc_item->type, $alloc_item->type_no, $this->date_,
197 $alloc_item->current_allocated,
198 $this->person_type ? PT_SUPPLIER : PT_CUSTOMER);
200 //////////////////////////////////////////////////////////////
201 $total_allocated += $alloc_item->current_allocated;
204 } //end of the loop through the array of allocations made
205 if ($this->person_type)
206 update_supp_trans_allocation($this->type, $this->trans_no,
209 update_debtor_trans_allocation($this->type, $this->trans_no,
212 commit_transaction();
218 //-----------------------------------------------------------------------------------
220 class allocation_item
229 var $amount_allocated;
233 var $current_allocated;
235 function allocation_item ($type, $type_no, $date_, $due_date, $amount,
236 $amount_allocated, $current_allocated, $ref)
240 $this->type_no = $type_no;
244 $this->date_ = $date_;
245 $this->due_date = $due_date;
247 $this->amount = $amount;
248 $this->amount_allocated = $amount_allocated;
249 $this->current_allocated = $current_allocated;
253 //--------------------------------------------------------------------------------
255 function show_allocatable($show_totals) {
257 global $systypes_array;
259 $k = $counter = $total_allocated = 0;
261 if (count($_SESSION['alloc']->allocs))
263 start_table(TABLESTYLE, "width=60%");
264 $th = array(_("Transaction Type"), _("#"), _("Ref"), _("Date"), _("Due Date"), _("Amount"),
265 _("Other Allocations"), _("This Allocation"), _("Left to Allocate"),'','');
268 foreach ($_SESSION['alloc']->allocs as $alloc_item)
270 if ($alloc_item->amount > $alloc_item->amount_allocated) {
271 alt_table_row_color($k);
272 label_cell($systypes_array[$alloc_item->type]);
273 label_cell(get_trans_view_str($alloc_item->type, $alloc_item->type_no));
274 label_cell($alloc_item->ref);
275 label_cell($alloc_item->date_, "align=right");
276 label_cell($alloc_item->due_date, "align=right");
277 amount_cell($alloc_item->amount);
278 amount_cell($alloc_item->amount_allocated);
280 $_POST['amount' . $counter] = price_format($alloc_item->current_allocated);
281 amount_cells(null, "amount" . $counter, price_format('amount' . $counter));
283 $un_allocated = round($alloc_item->amount - $alloc_item->amount_allocated, 6);
284 amount_cell($un_allocated, false,'', 'maxval'.$counter);
285 label_cell("<a href='#' name=Alloc$counter onclick='allocate_all(this.name.substr(5));return true;'>"
286 . _("All") . "</a>");
287 label_cell("<a href='#' name=DeAll$counter onclick='allocate_none(this.name.substr(5));return true;'>"
288 . _("None") . "</a>".hidden("un_allocated" . $counter,
289 price_format($un_allocated), false));
292 $total_allocated += input_num('amount' . $counter);
297 label_row(_("Total Allocated"), price_format($total_allocated),
298 "colspan=6 align=right", "align=right id='total_allocated'", 3);
299 $amount = $_SESSION['alloc']->amount;
301 if ($_SESSION['alloc']->type == ST_SUPPCREDIT
302 || $_SESSION['alloc']->type == ST_SUPPAYMENT
303 || $_SESSION['alloc']->type == ST_BANKPAYMENT)
306 if ($amount - $total_allocated < 0)
308 $font1 = "<font color=red>";
312 $font1 = $font2 = "";
313 $left_to_allocate = price_format($amount - $total_allocated);
314 label_row(_("Left to Allocate"), $font1 . $left_to_allocate . $font2,
315 "colspan=6 align=right", "nowrap align=right id='left_to_allocate'",
320 hidden('TotalNumberOfAllocs', $counter);
322 //--------------------------------------------------------------------------------
324 function check_allocations()
328 $total_allocated = 0;
330 for ($counter = 0; $counter < $_POST["TotalNumberOfAllocs"]; $counter++)
331 if (isset($_POST['amount' . $counter])) {
332 if (!check_num('amount' . $counter, 0))
334 display_error(_("The entry for one or more amounts is invalid or negative."));
335 set_focus('amount'.$counter);
339 /*Now check to see that the AllocAmt is no greater than the
340 amount left to be allocated against the transaction under review */
341 if (input_num('amount' . $counter) > input_num('un_allocated' . $counter))
343 display_error(_("At least one transaction is overallocated."));
344 set_focus('amount'.$counter);
348 $_SESSION['alloc']->allocs[$counter]->current_allocated = input_num('amount' . $counter);
350 $total_allocated += input_num('amount' . $counter);
353 $amount = $_SESSION['alloc']->amount;
356 if (in_array($_SESSION['alloc']->type, array(ST_BANKPAYMENT, ST_SUPPCREDIT, ST_SUPPAYMENT)))
359 if ($total_allocated - ($amount + input_num('discount')) > $SysPrefs->allocation_settled_allowance())
361 display_error(_("These allocations cannot be processed because the amount allocated is more than the total amount left to allocate."));