1<?php
2
3include ('includes/DefineSerialItems.php');
4include ('includes/SQL_CommonFunctions.inc');
5include ('includes/session.php');
6
7$Title = _('Reverse Goods Received');
8
9include ('includes/header.php');
10
11if ((isset($_SESSION['SupplierID']) and $_SESSION['SupplierID'] != '') or (!isset($_POST['SupplierID']) or $_POST['SupplierID']) == '') {
12
13	$_POST['SupplierID'] = $_SESSION['SupplierID'];
14
15}
16
17if (!isset($_POST['SupplierID']) or $_POST['SupplierID'] == "") {
18	echo '<br />' . _('This page is expected to be called after a supplier has been selected');
19	echo '<meta http-equiv="Refresh" content="0; url=' . $RootPath . '/SelectSupplier.php">';
20	exit;
21} elseif (!isset($_POST['SuppName']) or $_POST['SuppName'] == "") {
22	$SQL = "SELECT suppname FROM suppliers WHERE supplierid='" . $_SESSION['SupplierID'] . "'";
23	$SuppResult = DB_query($SQL, _('Could not retrieve the supplier name for') . ' ' . $_SESSION['SupplierID']);
24	$SuppRow = DB_fetch_row($SuppResult);
25	$_POST['SuppName'] = $SuppRow[0];
26}
27
28echo '<p class="page_title_text"><img src="' . $RootPath . '/css/' . $Theme . '/images/supplier.png" title="' . _('Sales') . '" alt="" />' . ' ' . _('Reverse Goods Received from') . ' ' . $_POST['SuppName'] . '</p> ';
29
30if (isset($_GET['GRNNo']) and isset($_POST['SupplierID'])) {
31	/* SQL to process the postings for the GRN reversal.. */
32
33	//Get the details of the GRN item and the cost at which it was received and other PODetail info
34	$SQL = "SELECT grns.podetailitem,
35					grns.grnbatch,
36					grns.itemcode,
37					grns.itemdescription,
38					grns.deliverydate,
39					grns.supplierref,
40					purchorderdetails.glcode,
41					purchorderdetails.assetid,
42					grns.qtyrecd,
43					grns.quantityinv,
44					purchorderdetails.stdcostunit,
45					purchorders.intostocklocation,
46					purchorders.orderno
47			FROM grns INNER JOIN purchorderdetails
48			ON grns.podetailitem=purchorderdetails.podetailitem
49			INNER JOIN purchorders
50			ON purchorderdetails.orderno = purchorders.orderno
51			INNER JOIN locationusers ON locationusers.loccode=purchorders.intostocklocation AND locationusers.userid='" . $_SESSION['UserID'] . "' AND locationusers.canupd=1
52			WHERE grnno='" . $_GET['GRNNo'] . "'";
53
54	$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('Could not get the details of the GRN selected for reversal because') . ' ';
55	$DbgMsg = _('The following SQL to retrieve the GRN details was used') . ':';
56
57	$Result = DB_query($SQL, $ErrMsg, $DbgMsg);
58
59	$GRN = DB_fetch_array($Result);
60	$QtyToReverse = $GRN['qtyrecd'] - $GRN['quantityinv'];
61
62	if ($QtyToReverse == 0) {
63		echo '<br />
64				<br />' . _('The GRN') . ' ' . $_GET['GRNNo'] . ' ' . _('has already been reversed or fully invoiced by the supplier - it cannot be reversed - stock quantities must be corrected by stock adjustments - the stock is paid for');
65		include ('includes/footer.php');
66		exit;
67	}
68
69	/*If the item is a stock item then need to check for Controlled or not ...
70	 if its controlled then need to check existence of the controlled items
71	 that came in with this GRN */
72
73	$SQL = "SELECT stockmaster.controlled
74			FROM stockmaster WHERE stockid ='" . $GRN['itemcode'] . "'";
75	$CheckControlledResult = DB_query($SQL, '<br />' . _('Could not determine if the item was controlled or not because') . ' ');
76	$ControlledRow = DB_fetch_row($CheckControlledResult);
77	if ($ControlledRow[0] == 1) { /*Then its a controlled item */
78		$Controlled = true;
79		/*So check to ensure the serial items received on this GRN are still there */
80		/*First get the StockMovement Reference for the GRN */
81		$SQL = "SELECT stockserialmoves.serialno,
82				stockserialmoves.moveqty
83		        FROM stockmoves INNER JOIN stockserialmoves
84				ON stockmoves.stkmoveno= stockserialmoves.stockmoveno
85				WHERE stockmoves.stockid='" . $GRN['itemcode'] . "'
86				AND stockmoves.type =25
87				AND stockmoves.transno='" . $GRN['grnbatch'] . "'";
88		$GetStockMoveResult = DB_query($SQL, _('Could not retrieve the stock movement reference number which is required in order to retrieve details of the serial items that came in with this GRN'));
89
90		while ($SerialStockMoves = DB_fetch_array($GetStockMoveResult)) {
91
92			$SQL = "SELECT stockserialitems.quantity
93			        FROM stockserialitems
94					WHERE stockserialitems.stockid='" . $GRN['itemcode'] . "'
95					AND stockserialitems.loccode ='" . $GRN['intostocklocation'] . "'
96					AND stockserialitems.serialno ='" . $SerialStockMoves['serialno'] . "'";
97			$GetQOHResult = DB_query($SQL, _('Unable to retrieve the quantity on hand of') . ' ' . $GRN['itemcode'] . ' ' . _('for Serial No') . ' ' . $SerialStockMoves['serialno']);
98			$GetQOH = DB_fetch_row($GetQOHResult);
99			if ($GetQOH[0] < $SerialStockMoves['moveqty']) {
100				/*Then some of the original goods received must have been sold
101				 or transfered so cannot reverse the GRN */
102				prnMsg(_('Unfortunately, of the original number') . ' (' . $SerialStockMoves['moveqty'] . ') ' . _('that were received on serial number') . ' ' . $SerialStockMoves['serialno'] . ' ' . _('only') . ' ' . $GetQOH[0] . ' ' . _('remain') . '. ' . _('The GRN can only be reversed if all the original serial number items are still in stock in the location they were received into'), 'error');
103				include ('includes/footer.php');
104				exit;
105			}
106		}
107		/*reset the pointer on this resultset ... will need it later */
108		DB_data_seek($GetStockMoveResult, 0);
109	} else {
110		$Controlled = false;
111	}
112
113	/*Start an SQL transaction */
114
115	$Result = DB_Txn_Begin();
116
117	$PeriodNo = GetPeriod(ConvertSQLDate($GRN['deliverydate']));
118
119	/*Now the SQL to do the update to the PurchOrderDetails */
120
121	$SQL = "UPDATE purchorderdetails
122			SET quantityrecd = quantityrecd - '" . $QtyToReverse . "',
123			completed=0
124			WHERE purchorderdetails.podetailitem = '" . $GRN['podetailitem'] . "'";
125
126	$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The purchase order detail record could not be updated with the quantity reversed because');
127	$DbgMsg = _('The following SQL to update the purchase order detail record was used');
128	$Result = DB_query($SQL, $ErrMsg, $DbgMsg, true);
129
130	/*Now the purchorder header status in case it was completed  - now incomplete - just printed */
131	$SQL = "UPDATE purchorders
132			SET status = 'Printed',
133				stat_comment = CONCAT('" . Date($_SESSION['DefaultDateFormat']) . ' ' . _('GRN Reversed for') . ' ' . DB_escape_string(stripslashes($GRN['itemdescription'])) . ' ' . _('by') . ' ' . $_SESSION['UsersRealName'] . "<br />', stat_comment )
134			WHERE orderno = '" . $GRN['orderno'] . "'";
135
136	$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The purchase order statusand status comment could not be changed because');
137	$DbgMsg = _('The following SQL to update the purchase order header record was used');
138	$Result = DB_query($SQL, $ErrMsg, $DbgMsg, true);
139
140	/*Need to update or delete the existing GRN item */
141	if ($QtyToReverse == $GRN['qtyrecd']) { //then ok to delete the whole thing
142		/* if this is not deleted then the purchorderdetail line cannot be deleted subsequentely */
143		//remove suppinvtogrns first;
144		$SQL = "DELETE FROM suppinvstogrn WHERE grnno='" . $_GET['GRNNo'] . "'";
145		$ErrMsg = _('Failed to delete the grn from supplier invoice record');
146		$Result = DB_query($SQL, $ErrMsg, '', true);
147
148		$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The GRN record could not be deleted because');
149		$DbgMsg = _('The following SQL to delete the GRN record was used');
150		$Result = DB_query("DELETE FROM grns WHERE grnno='" . $_GET['GRNNo'] . "'", $ErrMsg, $DbgMsg, true);
151	} else {
152		$SQL = "UPDATE grns	SET qtyrecd = qtyrecd - " . $QtyToReverse . "
153				WHERE grns.grnno='" . $_GET['GRNNo'] . "'";
154
155		$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The GRN record could not be updated') . '. ' . _('This reversal of goods received has not been processed because');
156		$DbgMsg = _('The following SQL to insert the GRN record was used');
157		$Result = DB_query($SQL, $ErrMsg, $DbgMsg, true);
158	}
159	/*If the GRN being reversed is an asset - reverse the fixedassettrans record */
160	if ($GRN['assetid'] != '0') {
161		$SQL = "INSERT INTO fixedassettrans (assetid,
162											transtype,
163											transno,
164											transdate,
165											periodno,
166											inputdate,
167											fixedassettranstype,
168											cost)
169						VALUES ('" . $GRN['assetid'] . "',
170								'25',
171								'" . $_GET['GRNNo'] . "',
172								'" . $GRN['deliverydate'] . "',
173								'" . $PeriodNo . "',
174								CURRENT_DATE,
175								'" . _('cost') . "',
176								'" . (-$GRN['stdcostunit'] * $QtyToReverse) . "')";
177		$ErrMsg = _('CRITICAL ERROR! NOTE DOWN THIS ERROR AND SEEK ASSISTANCE The fixed asset transaction could not be inserted because');
178		$DbgMsg = _('The following SQL to insert the fixed asset transaction record was used');
179		$Result = DB_query($SQL, $ErrMsg, $DbgMsg, true);
180
181		/*now reverse the cost put to fixedassets */
182		$SQL = "UPDATE fixedassets SET cost = cost - " . $GRN['stdcostunit'] * $QtyToReverse . "
183				WHERE assetid = '" . $GRN['assetid'] . "'";
184		$ErrMsg = _('CRITICAL ERROR! NOTE DOWN THIS ERROR AND SEEK ASSISTANCE. The fixed asset cost addition could not be reversed:');
185		$DbgMsg = _('The following SQL was used to attempt the reduce the cost of the asset was:');
186		$Result = DB_query($SQL, $ErrMsg, $DbgMsg, true);
187
188	} //end of if it is an asset
189	$SQL = "SELECT stockmaster.controlled
190			FROM stockmaster
191			WHERE stockmaster.stockid = '" . $GRN['itemcode'] . "'";
192	$Result = DB_query($SQL, _('Could not determine if the item exists because'), '<br />' . _('The SQL that failed was') . ' ', true);
193
194	if (DB_num_rows($Result) == 1) { /* if the GRN is in fact a stock item being reversed */
195
196		$StkItemExists = DB_fetch_row($Result);
197		$Controlled = $StkItemExists[0];
198
199		/* Update location stock records - NB  a PO cannot be entered for a dummy/assembly/kit parts */
200		/*Need to get the current location quantity will need it later for the stock movement */
201		$SQL = "SELECT quantity
202				FROM locstock
203				WHERE stockid='" . $GRN['itemcode'] . "'
204				AND loccode= '" . $GRN['intostocklocation'] . "'";
205
206		$Result = DB_query($SQL, _('Could not get the quantity on hand of the item before the reversal was processed'), _('The SQL that failed was'), true);
207		if (DB_num_rows($Result) == 1) {
208			$LocQtyRow = DB_fetch_row($Result);
209			$QtyOnHandPrior = $LocQtyRow[0];
210		} else {
211			/*There must actually be some error this should never happen */
212			$QtyOnHandPrior = 0;
213		}
214
215		$SQL = "UPDATE locstock
216				SET quantity = quantity - " . $QtyToReverse . "
217				WHERE stockid = '" . $GRN['itemcode'] . "'
218				AND loccode = '" . $GRN['intostocklocation'] . "'";
219
220		$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The location stock record could not be updated because');
221		$DbgMsg = _('The following SQL to update the location stock record was used');
222		$Result = DB_query($SQL, $ErrMsg, $DbgMsg, true);
223
224		/* If its a stock item .... Insert stock movements - with unit cost */
225		$NewQtyOnHand = $QtyOnHandPrior - $QtyToReverse;
226		$SQL = "INSERT INTO stockmoves (stockid,
227										type,
228										transno,
229										loccode,
230										trandate,
231										userid,
232										prd,
233										reference,
234										qty,
235										standardcost,
236										newqoh)
237									VALUES (
238										'" . $GRN['itemcode'] . "',
239										25,
240										'" . $_GET['GRNNo'] . "',
241										'" . $GRN['intostocklocation'] . "',
242										'" . $GRN['deliverydate'] . "',
243										'" . $_SESSION['UserID'] . "',
244										'" . $PeriodNo . "',
245										'" . _('Reversal') . ' - ' . $_POST['SupplierID'] . ' - ' . $GRN['orderno'] . "',
246										'" . -$QtyToReverse . "',
247										'" . $GRN['stdcostunit'] . "',
248										'" . $NewQtyOnHand . "'
249										)";
250
251		$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('Stock movement records could not be inserted because');
252		$DbgMsg = _('The following SQL to insert the stock movement records was used');
253		$Result = DB_query($SQL, $ErrMsg, $DbgMsg, true);
254
255		$StkMoveNo = DB_Last_Insert_ID('stockmoves', 'stkmoveno');
256
257		if ($Controlled == true) {
258			while ($SerialStockMoves = DB_fetch_array($GetStockMoveResult)) {
259				$SQL = "INSERT INTO stockserialmoves (
260						stockmoveno,
261						stockid,
262						serialno,
263						moveqty)
264					VALUES (
265						'" . $StkMoveNo . "',
266						'" . $GRN['itemcode'] . "',
267						'" . $SerialStockMoves['serialno'] . "',
268						'" . -$SerialStockMoves['moveqty'] . "')";
269
270				$Result = DB_query($SQL, _('Could not insert the reversing stock movements for the batch/serial numbers'), _('The SQL used but failed was') . ':', true);
271
272				$SQL = "UPDATE stockserialitems
273					SET quantity=quantity - " . $SerialStockMoves['moveqty'] . "
274					WHERE stockserialitems.stockid='" . $GRN['itemcode'] . "'
275					AND stockserialitems.loccode ='" . $GRN['intostocklocation'] . "'
276					AND stockserialitems.serialno = '" . $SerialStockMoves['serialno'] . "'";
277				$Result = DB_query($SQL, _('Could not update the batch/serial stock records'), _('The SQL used but failed was') . ':', true);
278			}
279		}
280	} /*end of its a stock item - updates to locations and insert movements*/
281
282	/* If GLLink_Stock then insert GLTrans to debit the GL Code  and credit GRN Suspense account at standard cost*/
283
284	if ($_SESSION['CompanyRecord']['gllink_stock'] == 1 and $GRN['glcode'] != 0 and $GRN['stdcostunit'] != 0) {
285
286		/*GLCode is set to 0 when the GLLink is not activated
287		this covers a situation where the GLLink is now active  but it wasn't when this PO was entered
288
289		First the credit using the GLCode in the PO detail record entry*/
290
291		$SQL = "INSERT INTO gltrans (type,
292									typeno,
293									trandate,
294									periodno,
295									account,
296									narrative,
297									amount)
298								VALUES (
299									25,
300									'" . $_GET['GRNNo'] . "',
301									'" . $GRN['deliverydate'] . "',
302									'" . $PeriodNo . "',
303									'" . $GRN['glcode'] . "',
304									'" . _('GRN Reversal for PO') . ": " . $GRN['orderno'] . " " . $_POST['SupplierID'] . " - " . $GRN['itemcode'] . "-" . DB_escape_string($GRN['itemdescription']) . " x " . $QtyToReverse . " @ " . locale_number_format($GRN['stdcostunit'], $_SESSION['CompanyRecord']['decimalplaces']) . "',
305									'" . -($GRN['stdcostunit'] * $QtyToReverse) . "')";
306
307		$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The purchase GL posting could not be inserted for the reversal of the received item because');
308		$DbgMsg = _('The following SQL to insert the purchase GLTrans record was used');
309		$Result = DB_query($SQL, $ErrMsg, $DbgMsg, true);
310
311		/*now the GRN suspense entry*/
312		$SQL = "INSERT INTO gltrans (type,
313									typeno,
314									trandate,
315									periodno,
316									account,
317									narrative,
318									amount)
319							VALUES (
320								25,
321								'" . $_GET['GRNNo'] . "',
322								'" . $GRN['deliverydate'] . "',
323								'" . $PeriodNo . "',
324								'" . $_SESSION['CompanyRecord']['grnact'] . "', '" . _('GRN Reversal PO') . ': ' . $GRN['orderno'] . " " . $_POST['SupplierID'] . " - " . $GRN['itemcode'] . "-" . DB_escape_string($GRN['itemdescription']) . " x " . $QtyToReverse . " @ " . locale_number_format($GRN['stdcostunit'], $_SESSION['CompanyRecord']['decimalplaces']) . "',
325								'" . $GRN['stdcostunit'] * $QtyToReverse . "'
326								)";
327
328		$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The GRN suspense side of the GL posting could not be inserted because');
329		$DbgMsg = _('The following SQL to insert the GRN Suspense GLTrans record was used');
330		$Result = DB_query($SQL, $ErrMsg, $DbgMsg, true);
331	} /* end of if GL and stock integrated*/
332
333	$Result = DB_Txn_Commit();
334
335	echo '<br />' . _('GRN number') . ' ' . $_GET['GRNNo'] . ' ' . _('for') . ' ' . $QtyToReverse . ' x ' . $GRN['itemcode'] . ' - ' . $GRN['itemdescription'] . ' ' . _('has been reversed') . '<br />';
336	unset($_GET['GRNNo']); // to ensure it cant be done again!!
337	echo '<a href="' . htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8') . '">' . _('Select another GRN to Reverse') . '</a>';
338	/*end of Process Goods Received Reversal entry */
339
340} else {
341	echo '<form action="' . htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8') . '" method="post">';
342	echo '<div>';
343	echo '<input type="hidden" name="FormID" value="' . $_SESSION['FormID'] . '" />';
344
345	if (!isset($_POST['RecdAfterDate']) or !Is_Date($_POST['RecdAfterDate'])) {
346		$_POST['RecdAfterDate'] = Date($_SESSION['DefaultDateFormat'], Mktime(0, 0, 0, Date("m") - 3, Date("d"), Date("Y")));
347	}
348	echo '<input type="hidden" name="SupplierID" value="' . $_POST['SupplierID'] . '" />';
349	echo '<input type="hidden" name="SuppName" value="' . $_POST['SuppName'] . '" />';
350	echo '<table class="selection"><tr>';
351	echo '<td>' . _('Show all goods received after') . ': </td>
352			<td><input type="text" class="date" name="RecdAfterDate" value="' . $_POST['RecdAfterDate'] . '" maxlength="10" size="11" /></td>
353		</tr>
354		</table>
355		<br />
356		<div class="centre">
357			<input type="submit" name="ShowGRNS" value="' . _('Show Outstanding Goods Received') . '" />
358		</div>
359		</div>
360	</form>';
361
362	if (isset($_POST['ShowGRNS'])) {
363
364		$SQL = "SELECT grnno,
365						grnbatch,
366						grns.itemcode,
367						grns.itemdescription,
368						grns.deliverydate,
369						grns.supplierref,
370						qtyrecd,
371						quantityinv,
372						qtyrecd-quantityinv AS qtytoreverse
373				FROM grns
374				INNER JOIN purchorderdetails ON purchorderdetails.podetailitem=grns.podetailitem
375				INNER JOIN purchorders on purchorders.orderno = purchorderdetails.orderno
376				INNER JOIN locationusers ON locationusers.loccode=purchorders.intostocklocation AND locationusers.userid='" . $_SESSION['UserID'] . "' AND locationusers.canupd=1
377				WHERE grns.supplierid = '" . $_POST['SupplierID'] . "'
378				AND (grns.qtyrecd-grns.quantityinv) >0
379				AND grns.deliverydate>='" . FormatDateForSQL($_POST['RecdAfterDate']) . "'";
380
381		$ErrMsg = _('An error occurred in the attempt to get the outstanding GRNs for') . ' ' . $_POST['SuppName'] . '. ' . _('The message was') . ':';
382		$DbgMsg = _('The SQL that failed was') . ':';
383		$Result = DB_query($SQL, $ErrMsg, $DbgMsg);
384
385		if (DB_num_rows($Result) == 0) {
386			prnMsg(_('There are no outstanding goods received yet to be invoiced for') . ' ' . $_POST['SuppName'] . '.<br />' . _('To reverse a GRN that has been invoiced first it must be credited'), 'warn');
387		} else { //there are GRNs to show
388			echo '<br /><table cellpadding="2" class="selection">';
389			$TableHeader = '<tr>
390								<th>' . _('GRN') . ' #</th>
391								<th>' . _('GRN Batch') . '</th>
392								<th>' . _('Supplier\' Ref') . '</th>
393								<th>' . _('Item Code') . '</th>
394								<th>' . _('Description') . '</th>
395								<th>' . _('Date') . '<br />' . _('Received') . '</th>
396								<th>' . _('Quantity') . '<br />' . _('Received') . '</th>
397								<th>' . _('Quantity') . '<br />' . _('Invoiced') . '</th>
398								<th>' . _('Quantity To') . '<br />' . _('Reverse') . '</th>
399							</tr>';
400
401			echo $TableHeader;
402
403			/* show the GRNs outstanding to be invoiced that could be reversed */
404			$RowCounter = 0;
405			while ($MyRow = DB_fetch_array($Result)) {
406
407				$DisplayQtyRecd = locale_number_format($MyRow['qtyrecd'], 'Variable');
408				$DisplayQtyInv = locale_number_format($MyRow['quantityinv'], 'Variable');
409				$DisplayQtyRev = locale_number_format($MyRow['qtytoreverse'], 'Variable');
410				$DisplayDateDel = ConvertSQLDate($MyRow['deliverydate']);
411				$LinkToRevGRN = '<a href="' . htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8') . '?GRNNo=' . $MyRow['grnno'] . '">' . _('Reverse') . '</a>';
412
413				printf('<tr class="striped_row">
414						<td>%s</td>
415						<td>%s</td>
416						<td>%s</td>
417						<td>%s</td>
418						<td>%s</td>
419						<td>%s</td>
420						<td class="number">%s</td>
421						<td class="number">%s</td>
422						<td class="number">%s</td>
423						<td>%s</td>
424						</tr>', $MyRow['grnno'], $MyRow['grnbatch'], $MyRow['supplierref'], $MyRow['itemcode'], $MyRow['itemdescription'], $DisplayDateDel, $DisplayQtyRecd, $DisplayQtyInv, $DisplayQtyRev, $LinkToRevGRN);
425
426				$RowCounter++;
427				if ($RowCounter > 20) {
428					$RowCounter = 0;
429					echo $TableHeader;
430				}
431			}
432
433			echo '</table>';
434
435		}
436	}
437}
438include ('includes/footer.php');
439?>
440