1<?php
2// CounterSales.php
3// Allows sales to be entered against a cash sale customer account defined in the users location record.
4
5include('includes/DefineCartClass.php');
6
7/* Session started in session.php for password checking and authorisation level check
8config.php is in turn included in session.php $PageSecurity now comes from session.php (and gets read in by GetConfig.php*/
9
10include('includes/session.php');
11$Title = _('Counter Sales');
12$ViewTopic= 'SalesOrders';
13$BookMark = 'SalesOrderCounterSales';
14
15include('includes/header.php');
16include('includes/GetPrice.inc');
17include('includes/SQL_CommonFunctions.inc');
18include('includes/GetSalesTransGLCodes.inc');
19
20$AlreadyWarnedAboutCredit = false;
21
22if (empty($_GET['identifier'])) {
23	$identifier=date('U');
24} else {
25	$identifier=$_GET['identifier'];
26}
27if (isset($_SESSION['Items'.$identifier]) AND isset($_POST['CustRef'])) {
28	//update the Items object variable with the data posted from the form
29	$_SESSION['Items'.$identifier]->CustRef = $_POST['CustRef'];
30	$_SESSION['Items'.$identifier]->Comments = $_POST['Comments'];
31	$_SESSION['Items'.$identifier]->DeliverTo = $_POST['DeliverTo'];
32	$_SESSION['Items'.$identifier]->PhoneNo = $_POST['PhoneNo'];
33	$_SESSION['Items'.$identifier]->Email = $_POST['Email'];
34	if ($_SESSION['SalesmanLogin'] != '') {
35		$_SESSION['Items' . $identifier]->SalesPerson = $_SESSION['SalesmanLogin'];
36	}else{
37		$_SESSION['Items' . $identifier]->SalesPerson = $_POST['SalesPerson'];
38	}
39}
40
41if (isset($_POST['QuickEntry'])) {
42	unset($_POST['PartSearch']);
43}
44
45if (isset($_POST['SelectingOrderItems'])) {
46	foreach ($_POST as $FormVariable => $Quantity) {
47		if (mb_strpos($FormVariable,'OrderQty')!==false) {
48			$NewItemArray[$_POST['StockID' . mb_substr($FormVariable,8)]] = filter_number_format($Quantity);
49		}
50	}
51}
52
53if (isset($_GET['NewItem'])) {
54	$NewItem = trim($_GET['NewItem']);
55}
56
57if (isset($_GET['NewOrder'])) {
58	/*New order entry - clear any existing order details from the Items object and initiate a newy*/
59	 if (isset($_SESSION['Items'.$identifier])) {
60		unset ($_SESSION['Items'.$identifier]->LineItems);
61		$_SESSION['Items'.$identifier]->ItemsOrdered=0;
62		unset ($_SESSION['Items'.$identifier]);
63	}
64}
65
66
67if (!isset($_SESSION['Items'.$identifier])) {
68	/* It must be a new order being created $_SESSION['Items'.$identifier] would be set up from the order
69	modification code above if a modification to an existing order. Also $ExistingOrder would be
70	set to 1. The delivery check screen is where the details of the order are either updated or
71	inserted depending on the value of ExistingOrder */
72
73	$_SESSION['ExistingOrder'. $identifier] = 0;
74	$_SESSION['Items'.$identifier] = new cart;
75	$_SESSION['PrintedPackingSlip'] = 0; /*Of course 'cos the order ain't even started !!*/
76	/*Get the default customer-branch combo from the user's default location record */
77	$SQL = "SELECT cashsalecustomer,
78				cashsalebranch,
79				locationname,
80				taxprovinceid
81			FROM locations
82			WHERE loccode='" . $_SESSION['UserStockLocation'] ."'";
83	$result = DB_query($SQL);
84	if (DB_num_rows($result)==0) {
85		prnMsg(_('Your user account does not have a valid default inventory location set up. Please see the system administrator to modify your user account.'),'error');
86		include('includes/footer.php');
87		exit;
88	} else {
89		$MyRow = DB_fetch_array($result); //get the only row returned
90
91		if ($MyRow['cashsalecustomer']=='' OR $MyRow['cashsalebranch']=='') {
92			prnMsg(_('To use this script it is first necessary to define a cash sales customer for the location that is your default location. The default cash sale customer is defined under set up ->Inventory Locations Maintenance. The customer should be entered using the customer code and a valid branch code of the customer entered.'),'error');
93			include('includes/footer.php');
94			exit;
95		}
96		if (isset($_GET['DebtorNo'])) {
97			$_SESSION['Items'.$identifier]->DebtorNo = $_GET['DebtorNo'];
98			$_SESSION['Items'.$identifier]->Branch = $_GET['BranchNo'];
99		} else {
100			$_SESSION['Items'.$identifier]->Branch = $MyRow['cashsalebranch'];
101			$_SESSION['Items'.$identifier]->DebtorNo = $MyRow['cashsalecustomer'];
102		}
103
104		$_SESSION['Items'.$identifier]->LocationName = $MyRow['locationname'];
105		$_SESSION['Items'.$identifier]->Location = $_SESSION['UserStockLocation'];
106		$_SESSION['Items'.$identifier]->DispatchTaxProvince = $MyRow['taxprovinceid'];
107
108		// Now check to ensure this account exists and set defaults */
109		$SQL = "SELECT debtorsmaster.name,
110					holdreasons.dissallowinvoices,
111					debtorsmaster.salestype,
112					salestypes.sales_type,
113					debtorsmaster.currcode,
114					debtorsmaster.customerpoline,
115					paymentterms.terms,
116					currencies.decimalplaces
117				FROM debtorsmaster INNER JOIN holdreasons
118				ON debtorsmaster.holdreason=holdreasons.reasoncode
119				INNER JOIN salestypes
120				ON debtorsmaster.salestype=salestypes.typeabbrev
121				INNER JOIN paymentterms
122				ON debtorsmaster.paymentterms=paymentterms.termsindicator
123				INNER JOIN currencies
124				ON debtorsmaster.currcode=currencies.currabrev
125				WHERE debtorsmaster.debtorno = '" . $_SESSION['Items'.$identifier]->DebtorNo . "'";
126
127		$ErrMsg = _('The details of the customer selected') . ': ' .  $_SESSION['Items'.$identifier]->DebtorNo . ' ' . _('cannot be retrieved because');
128		$DbgMsg = _('The SQL used to retrieve the customer details and failed was') . ':';
129		$result =DB_query($SQL,$ErrMsg,$DbgMsg);
130
131		$MyRow = DB_fetch_array($result);
132		if ($MyRow['dissallowinvoices'] != 1) {
133			if ($MyRow['dissallowinvoices']==2) {
134				prnMsg($MyRow['name'] . ' ' . _('Although this account is defined as the cash sale account for the location.  The account is currently flagged as an account that needs to be watched. Please contact the credit control personnel to discuss'),'warn');
135			}
136
137			$_SESSION['RequireCustomerSelection']=0;
138			$_SESSION['Items'.$identifier]->CustomerName = $MyRow['name'];
139			// the sales type is the price list to be used for this sale
140			$_SESSION['Items'.$identifier]->DefaultSalesType = $MyRow['salestype'];
141			$_SESSION['Items'.$identifier]->SalesTypeName = $MyRow['sales_type'];
142			$_SESSION['Items'.$identifier]->DefaultCurrency = $MyRow['currcode'];
143			$_SESSION['Items'.$identifier]->DefaultPOLine = $MyRow['customerpoline'];
144			$_SESSION['Items'.$identifier]->PaymentTerms = $MyRow['terms'];
145			$_SESSION['Items'.$identifier]->CurrDecimalPlaces = $MyRow['decimalplaces'];
146			/* now get the branch defaults from the customer branches table CustBranch. */
147
148			$SQL = "SELECT custbranch.brname,
149				       custbranch.braddress1,
150				       custbranch.defaultshipvia,
151				       custbranch.deliverblind,
152				       custbranch.specialinstructions,
153				       custbranch.estdeliverydays,
154				       custbranch.salesman,
155				       custbranch.taxgroupid,
156				       custbranch.defaultshipvia
157				FROM custbranch
158				WHERE custbranch.branchcode='" . $_SESSION['Items'.$identifier]->Branch . "'
159				AND custbranch.debtorno = '" . $_SESSION['Items'.$identifier]->DebtorNo . "'";
160            $ErrMsg = _('The customer branch record of the customer selected') . ': ' . $_SESSION['Items'.$identifier]->Branch . ' ' . _('cannot be retrieved because');
161			$DbgMsg = _('SQL used to retrieve the branch details was') . ':';
162			$result =DB_query($SQL,$ErrMsg,$DbgMsg);
163
164			if (DB_num_rows($result)==0) {
165
166				prnMsg(_('The branch details for branch code') . ': ' . $_SESSION['Items'.$identifier]->Branch . ' ' . _('against customer code') . ': ' . $_SESSION['Items'.$identifier]->DebtorNo . ' ' . _('could not be retrieved') . '. ' . _('Check the set up of the customer and branch'),'error');
167
168				if ($debug==1) {
169					echo '<br />' . _('The SQL that failed to get the branch details was') . ':<br />' . $SQL;
170				}
171				include('includes/footer.php');
172				exit;
173			}
174			// add echo
175			echo '<br />';
176			$MyRow = DB_fetch_array($result);
177
178			$_SESSION['Items'.$identifier]->DeliverTo = '';
179			$_SESSION['Items'.$identifier]->DelAdd1 = $MyRow['braddress1'];
180			$_SESSION['Items'.$identifier]->ShipVia = $MyRow['defaultshipvia'];
181			$_SESSION['Items'.$identifier]->DeliverBlind = $MyRow['deliverblind'];
182			$_SESSION['Items'.$identifier]->SpecialInstructions = $MyRow['specialinstructions'];
183			$_SESSION['Items'.$identifier]->DeliveryDays = $MyRow['estdeliverydays'];
184			$_SESSION['Items'.$identifier]->TaxGroup = $MyRow['taxgroupid'];
185			$_SESSION['Items'.$identifier]->SalesPerson = $MyRow['salesman'];
186
187			if ($_SESSION['Items'.$identifier]->SpecialInstructions) {
188				prnMsg($_SESSION['Items'.$identifier]->SpecialInstructions,'warn');
189			}
190
191			if ($_SESSION['CheckCreditLimits'] > 0 AND $AlreadyWarnedAboutCredit==false) {  /*Check credit limits is 1 for warn and 2 for prohibit sales */
192				$_SESSION['Items'.$identifier]->CreditAvailable = GetCreditAvailable($_SESSION['Items'.$identifier]->DebtorNo);
193
194				if ($_SESSION['CheckCreditLimits']==1 AND $_SESSION['Items'.$identifier]->CreditAvailable <=0) {
195					prnMsg(_('The') . ' ' . $MyRow['brname'] . ' ' . _('account is currently at or over their credit limit'),'warn');
196					$AlreadyWarnedAboutCredit = true;
197				} elseif ($_SESSION['CheckCreditLimits']==2 AND $_SESSION['Items'.$identifier]->CreditAvailable <=0) {
198					prnMsg(_('No more orders can be placed by') . ' ' . $MyRow[0] . ' ' . _(' their account is currently at or over their credit limit'),'warn');
199					$AlreadyWarnedAboutCredit = true;
200					include('includes/footer.php');
201					exit;
202				}
203			}
204
205		} else {
206			prnMsg($MyRow['brname'] . ' ' . _('Although the account is defined as the cash sale account for the location  the account is currently on hold. Please contact the credit control personnel to discuss'),'warn');
207		}
208
209	}
210} // end if its a new sale to be set up ...
211
212if (isset($_POST['CancelOrder'])) {
213
214
215	unset($_SESSION['Items'.$identifier]->LineItems);
216	$_SESSION['Items'.$identifier]->ItemsOrdered = 0;
217	unset($_SESSION['Items'.$identifier]);
218	$_SESSION['Items'.$identifier] = new cart;
219
220	echo '<br /><br />';
221	prnMsg(_('This sale has been cancelled as requested'),'success');
222	echo '<br /><br /><a href="' .htmlspecialchars($_SERVER['PHP_SELF'],ENT_QUOTES,'UTF-8') . '">' . _('Start a new Counter Sale') . '</a>';
223	include('includes/footer.php');
224	exit;
225
226} else { /*Not cancelling the order */
227
228	echo '<p class="page_title_text"><img src="'.$RootPath.'/css/'.$Theme.'/images/inventory.png" title="' . _('Counter Sales') . '" alt="" />' . ' ';
229	echo $_SESSION['Items'.$identifier]->CustomerName . ' ' . _('Counter Sale') . ' ' ._('from') . ' ' . $_SESSION['Items'.$identifier]->LocationName . ' ' . _('inventory') . ' (' . _('all amounts in') . ' ' . $_SESSION['Items'.$identifier]->DefaultCurrency . ')';
230	echo '</p>';
231}
232
233if (isset($_POST['Search']) or isset($_POST['Next']) or isset($_POST['Previous'])) {
234
235	if ($_POST['Keywords']!='' AND $_POST['StockCode']=='') {
236		$msg = _('Item description has been used in search');
237	} else if ($_POST['StockCode']!='' AND $_POST['Keywords']=='') {
238		$msg = _('Item Code has been used in search');
239	} else if ($_POST['Keywords']=='' AND $_POST['StockCode']=='') {
240		$msg = _('Stock Category has been used in search');
241	}
242	if (isset($_POST['Keywords']) AND mb_strlen($_POST['Keywords'])>0) {
243		//insert wildcard characters in spaces
244		$_POST['Keywords'] = mb_strtoupper($_POST['Keywords']);
245		$SearchString = '%' . str_replace(' ', '%', $_POST['Keywords']) . '%';
246
247		if ($_POST['StockCat']=='All') {
248			$SQL = "SELECT stockmaster.stockid,
249						stockmaster.description,
250						stockmaster.units,
251						stockmaster.decimalplaces
252					FROM stockmaster INNER JOIN stockcategory
253					ON stockmaster.categoryid=stockcategory.categoryid
254					WHERE (stockcategory.stocktype='F' OR stockcategory.stocktype='D' OR stockcategory.stocktype='L')
255					AND stockmaster.mbflag <>'G'
256					AND stockmaster.controlled <> 1
257					AND stockmaster.description " . LIKE . " '" . $SearchString . "'
258					AND stockmaster.discontinued=0
259					ORDER BY stockmaster.stockid";
260		} else {
261			$SQL = "SELECT stockmaster.stockid,
262						stockmaster.description,
263						stockmaster.units,
264						stockmaster.decimalplaces
265					FROM stockmaster INNER JOIN stockcategory
266					ON  stockmaster.categoryid=stockcategory.categoryid
267					WHERE (stockcategory.stocktype='F' OR stockcategory.stocktype='D' OR stockcategory.stocktype='L')
268					AND stockmaster.mbflag <>'G'
269					AND stockmaster.controlled <> 1
270					AND stockmaster.discontinued=0
271					AND stockmaster.description " . LIKE . " '" . $SearchString . "'
272					AND stockmaster.categoryid='" . $_POST['StockCat'] . "'
273					ORDER BY stockmaster.stockid";
274		}
275
276	} else if (mb_strlen($_POST['StockCode'])>0) {
277
278		$_POST['StockCode'] = mb_strtoupper($_POST['StockCode']);
279		$SearchString = '%' . $_POST['StockCode'] . '%';
280
281		if ($_POST['StockCat']=='All') {
282			$SQL = "SELECT stockmaster.stockid,
283						stockmaster.description,
284						stockmaster.units,
285						stockmaster.decimalplaces
286					FROM stockmaster INNER JOIN stockcategory
287					  ON stockmaster.categoryid=stockcategory.categoryid
288					WHERE (stockcategory.stocktype='F' OR stockcategory.stocktype='D' OR stockcategory.stocktype='L')
289					AND stockmaster.stockid " . LIKE . " '" . $SearchString . "'
290					AND stockmaster.mbflag <>'G'
291					AND stockmaster.controlled <> 1
292					AND stockmaster.discontinued=0
293					ORDER BY stockmaster.stockid";
294		} else {
295			$SQL = "SELECT stockmaster.stockid,
296						stockmaster.description,
297						stockmaster.units,
298						stockmaster.decimalplaces
299					FROM stockmaster INNER JOIN stockcategory
300					ON stockmaster.categoryid=stockcategory.categoryid
301					AND (stockcategory.stocktype='F' OR stockcategory.stocktype='D' OR stockcategory.stocktype='L')
302					AND stockmaster.stockid " . LIKE . " '" . $SearchString . "'
303					AND stockmaster.mbflag <>'G'
304					AND stockmaster.controlled <> 1
305					AND stockmaster.discontinued=0
306					AND stockmaster.categoryid='" . $_POST['StockCat'] . "'
307					ORDER BY stockmaster.stockid";
308		}
309
310	} else {
311		if ($_POST['StockCat']=='All') {
312			$SQL = "SELECT stockmaster.stockid,
313						stockmaster.description,
314						stockmaster.units,
315						stockmaster.decimalplaces
316					FROM stockmaster INNER JOIN stockcategory
317					ON  stockmaster.categoryid=stockcategory.categoryid
318					WHERE (stockcategory.stocktype='F' OR stockcategory.stocktype='D' OR stockcategory.stocktype='L')
319					AND stockmaster.mbflag <>'G'
320					AND stockmaster.controlled <> 1
321					AND stockmaster.discontinued=0
322					ORDER BY stockmaster.stockid";
323        	} else {
324			$SQL = "SELECT stockmaster.stockid,
325						stockmaster.description,
326						stockmaster.units,
327						stockmaster.decimalplaces
328					FROM stockmaster INNER JOIN stockcategory
329					ON stockmaster.categoryid=stockcategory.categoryid
330					WHERE (stockcategory.stocktype='F' OR stockcategory.stocktype='D' OR stockcategory.stocktype='L')
331					AND stockmaster.mbflag <>'G'
332					AND stockmaster.controlled <> 1
333					AND stockmaster.discontinued=0
334					AND stockmaster.categoryid='" . $_POST['StockCat'] . "'
335					ORDER BY stockmaster.stockid";
336		  }
337	}
338
339	if (isset($_POST['Next'])) {
340		$Offset = $_POST['NextList'];
341	}
342	if (isset($_POST['Previous'])) {
343		$Offset = $_POST['PreviousList'];
344	}
345	if (!isset($Offset) OR $Offset < 0) {
346		$Offset = 0;
347	}
348	$SQL = $SQL . ' LIMIT ' . $_SESSION['DefaultDisplayRecordsMax'].' OFFSET ' . strval($_SESSION['DefaultDisplayRecordsMax']*$Offset);
349
350	$ErrMsg = _('There is a problem selecting the part records to display because');
351	$DbgMsg = _('The SQL used to get the part selection was');
352	$SearchResult = DB_query($SQL,$ErrMsg, $DbgMsg);
353
354	if (DB_num_rows($SearchResult)==0 ) {
355		prnMsg (_('There are no products available meeting the criteria specified'),'info');
356	}
357	if (DB_num_rows($SearchResult)==1) {
358		$MyRow=DB_fetch_array($SearchResult);
359		$NewItem = $MyRow['stockid'];
360		DB_data_seek($SearchResult,0);
361	}
362	if (DB_num_rows($SearchResult)< $_SESSION['DisplayRecordsMax']) {
363		$Offset=0;
364	}
365
366} //end of if search
367
368
369/* Always do the stuff below */
370
371echo '<form action="' . htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8') . '?identifier=' . urlencode($identifier) . '" id="SelectParts" method="post">';
372echo '<div>';
373echo '<input type="hidden" name="FormID" value="' . $_SESSION['FormID'] . '" />';
374
375//Get The exchange rate used for GPPercent calculations on adding or amending items
376if ($_SESSION['Items'.$identifier]->DefaultCurrency != $_SESSION['CompanyRecord']['currencydefault']) {
377	$ExRateResult = DB_query("SELECT rate FROM currencies WHERE currabrev='" . $_SESSION['Items'.$identifier]->DefaultCurrency . "'");
378	if (DB_num_rows($ExRateResult)>0) {
379		$ExRateRow = DB_fetch_row($ExRateResult);
380		$ExRate = $ExRateRow[0];
381	} else {
382		$ExRate =1;
383	}
384} else {
385	$ExRate = 1;
386}
387
388/*Process Quick Entry */
389/* If enter is pressed on the quick entry screen, the default button may be Recalculate */
390 if (isset($_POST['SelectingOrderItems'])
391		OR isset($_POST['QuickEntry'])
392		OR isset($_POST['Recalculate'])) {
393
394	/* get the item details from the database and hold them in the cart object */
395
396	/*Discount can only be set later on  -- after quick entry -- so default discount to 0 in the first place */
397	$Discount = 0;
398	$AlreadyWarnedAboutCredit = false;
399	$i=1;
400	while ($i<=max($_SESSION['QuickEntries'], $_POST['TotalQuickEntryRows'])
401			AND isset($_POST['part_' . $i])
402			AND $_POST['part_' . $i]!='') {
403
404		$QuickEntryCode = 'part_' . $i;
405		$QuickEntryQty = 'qty_' . $i;
406		$QuickEntryPOLine = 'poline_' . $i;
407		$QuickEntryItemDue = 'ItemDue_' . $i;
408
409		$i++;
410
411		if (isset($_POST[$QuickEntryCode])) {
412			$NewItem = mb_strtoupper($_POST[$QuickEntryCode]);
413		}
414		if (isset($_POST[$QuickEntryQty])) {
415			$NewItemQty = filter_number_format($_POST[$QuickEntryQty]);
416		}
417		if (isset($_POST[$QuickEntryItemDue])) {
418			$NewItemDue = $_POST[$QuickEntryItemDue];
419		} else {
420			$NewItemDue = DateAdd (Date($_SESSION['DefaultDateFormat']),'d', $_SESSION['Items'.$identifier]->DeliveryDays);
421		}
422		if (isset($_POST[$QuickEntryPOLine])) {
423			$NewPOLine = $_POST[$QuickEntryPOLine];
424		} else {
425			$NewPOLine = 0;
426		}
427
428		if (!isset($NewItem)) {
429			unset($NewItem);
430			break;	/* break out of the loop if nothing in the quick entry fields*/
431		}
432
433		if(!Is_Date($NewItemDue)) {
434			prnMsg(_('An invalid date entry was made for ') . ' ' . $NewItem . ' ' . _('The date entry') . ' ' . $NewItemDue . ' ' . _('must be in the format') . ' ' . $_SESSION['DefaultDateFormat'],'warn');
435			//Attempt to default the due date to something sensible?
436			$NewItemDue = DateAdd (Date($_SESSION['DefaultDateFormat']),'d', $_SESSION['Items'.$identifier]->DeliveryDays);
437		}
438		/*Now figure out if the item is a kit set - the field MBFlag='K'*/
439		$SQL = "SELECT stockmaster.mbflag,
440						stockmaster.controlled
441				FROM stockmaster
442				WHERE stockmaster.stockid='". $NewItem ."'";
443
444		$ErrMsg = _('Could not determine if the part being ordered was a kitset or not because');
445		$DbgMsg = _('The sql that was used to determine if the part being ordered was a kitset or not was ');
446		$KitResult = DB_query($SQL,$ErrMsg,$DbgMsg);
447
448
449		if (DB_num_rows($KitResult)==0) {
450			prnMsg( _('The item code') . ' ' . $NewItem . ' ' . _('could not be retrieved from the database and has not been added to the order'),'warn');
451		} elseif ($MyRow=DB_fetch_array($KitResult)) {
452			if ($MyRow['mbflag']=='K') {	/*It is a kit set item */
453				$SQL = "SELECT bom.component,
454							bom.quantity
455						FROM bom
456						WHERE bom.parent='" . $NewItem . "'
457                        AND bom.effectiveafter <= '" . date('Y-m-d') . "'
458                        AND bom.effectiveto > '" . date('Y-m-d') . "'";
459
460				$ErrMsg =  _('Could not retrieve kitset components from the database because') . ' ';
461				$KitResult = DB_query($SQL,$ErrMsg,$DbgMsg);
462
463				$ParentQty = $NewItemQty;
464				while ($KitParts = DB_fetch_array($KitResult)) {
465					$NewItem = $KitParts['component'];
466					$NewItemQty = $KitParts['quantity'] * $ParentQty;
467					$NewPOLine = 0;
468					include('includes/SelectOrderItems_IntoCart.inc');
469					$_SESSION['Items'.$identifier]->GetTaxes(($_SESSION['Items'.$identifier]->LineCounter - 1));
470				}
471
472			} else if ($MyRow['mbflag']=='G') {
473				prnMsg(_('Phantom assemblies cannot be sold, these items exist only as bills of materials used in other manufactured items. The following item has not been added to the order:') . ' ' . $NewItem, 'warn');
474			} else if ($MyRow['controlled']==1) {
475				prnMsg(_('The system does not currently cater for counter sales of lot controlled or serialised items'),'warn');
476			} else if ($NewItemQty<=0) {
477				prnMsg(_('Only items entered with a positive quantity can be added to the sale'),'warn');
478			} else { /*Its not a kit set item*/
479				include('includes/SelectOrderItems_IntoCart.inc');
480				$_SESSION['Items'.$identifier]->GetTaxes(($_SESSION['Items'.$identifier]->LineCounter - 1));
481			}
482		}
483	 }
484	 unset($NewItem);
485 } /* end of if quick entry */
486
487 /*Now do non-quick entry delete/edits/adds */
488
489if ((isset($_SESSION['Items'.$identifier])) OR isset($NewItem)) {
490
491	if (isset($_GET['Delete'])) {
492		$_SESSION['Items'.$identifier]->remove_from_cart($_GET['Delete']);  /*Don't do any DB updates*/
493	}
494	$AlreadyWarnedAboutCredit = false;
495	foreach ($_SESSION['Items'.$identifier]->LineItems as $OrderLine) {
496
497		if (isset($_POST['Quantity_' . $OrderLine->LineNumber])) {
498
499			$Quantity = round(filter_number_format($_POST['Quantity_' . $OrderLine->LineNumber]),$OrderLine->DecimalPlaces);
500
501				if (ABS($OrderLine->Price - filter_number_format($_POST['Price_' . $OrderLine->LineNumber]))>0.01) {
502					/*There is a new price being input for the line item */
503
504					$Price = filter_number_format($_POST['Price_' . $OrderLine->LineNumber]);
505					$_POST['GPPercent_' . $OrderLine->LineNumber] = (($Price*(1-(filter_number_format($_POST['Discount_' . $OrderLine->LineNumber])/100))) - $OrderLine->StandardCost*$ExRate)/($Price *(1-filter_number_format($_POST['Discount_' . $OrderLine->LineNumber]))/100);
506
507				} elseif (ABS($OrderLine->GPPercent - filter_number_format($_POST['GPPercent_' . $OrderLine->LineNumber]))>=0.01) {
508					/* A GP % has been input so need to do a recalculation of the price at this new GP Percentage */
509
510					prnMsg(_('Recalculated the price from the GP % entered - the GP % was') . ' ' . $OrderLine->GPPercent . '  the new GP % is ' . filter_number_format($_POST['GPPercent_' . $OrderLine->LineNumber]),'info');
511
512					$Price = ($OrderLine->StandardCost*$ExRate)/(1 -((filter_number_format($_POST['GPPercent_' . $OrderLine->LineNumber]) + filter_number_format($_POST['Discount_' . $OrderLine->LineNumber]))/100));
513				} else {
514					$Price = filter_number_format($_POST['Price_' . $OrderLine->LineNumber]);
515				}
516				$DiscountPercentage = filter_number_format($_POST['Discount_' . $OrderLine->LineNumber]);
517				if ($_SESSION['AllowOrderLineItemNarrative'] == 1) {
518					$Narrative = $_POST['Narrative_' . $OrderLine->LineNumber];
519				} else {
520					$Narrative = '';
521				}
522
523				if (!isset($OrderLine->DiscountPercent)) {
524					$OrderLine->DiscountPercent = 0;
525				}
526
527			if ($Quantity<0 OR $Price < 0 OR $DiscountPercentage >100 OR $DiscountPercentage <0) {
528				prnMsg(_('The item could not be updated because you are attempting to set the quantity ordered to less than 0 or the price less than 0 or the discount more than 100% or less than 0%'),'warn');
529			} else if ($OrderLine->Quantity !=$Quantity
530						OR $OrderLine->Price != $Price
531						OR abs($OrderLine->DiscountPercent -$DiscountPercentage/100) >0.001
532						OR $OrderLine->Narrative != $Narrative
533						OR $OrderLine->ItemDue != $_POST['ItemDue_' . $OrderLine->LineNumber]
534						OR $OrderLine->POLine != $_POST['POLine_' . $OrderLine->LineNumber]) {
535
536				$_SESSION['Items'.$identifier]->update_cart_item($OrderLine->LineNumber,
537																$Quantity,
538																$Price,
539																$DiscountPercentage/100,
540																$Narrative,
541																'Yes', /*Update DB */
542																$_POST['ItemDue_' . $OrderLine->LineNumber],
543																$_POST['POLine_' . $OrderLine->LineNumber],
544																filter_number_format($_POST['GPPercent_' . $OrderLine->LineNumber]),
545																$identifier);
546			}
547		} //page not called from itself - POST variables not set
548	}
549}
550
551if (isset($_POST['Recalculate'])) {
552	foreach ($_SESSION['Items'.$identifier]->LineItems as $OrderLine) {
553		$NewItem=$OrderLine->StockID;
554		$SQL = "SELECT stockmaster.mbflag,
555						stockmaster.controlled
556				FROM stockmaster
557				WHERE stockmaster.stockid='". $OrderLine->StockID."'";
558
559		$ErrMsg = _('Could not determine if the part being ordered was a kitset or not because');
560		$DbgMsg = _('The sql that was used to determine if the part being ordered was a kitset or not was ');
561		$KitResult = DB_query($SQL,$ErrMsg,$DbgMsg);
562		if ($MyRow=DB_fetch_array($KitResult)) {
563			if ($MyRow['mbflag']=='K') {	/*It is a kit set item */
564				$SQL = "SELECT bom.component,
565								bom.quantity
566							FROM bom
567							WHERE bom.parent='" . $OrderLine->StockID. "'
568                            AND bom.effectiveafter <= '" . date('Y-m-d') . "'
569                            AND bom.effectiveto > '" . date('Y-m-d') . "'";
570
571				$ErrMsg = _('Could not retrieve kitset components from the database because');
572				$KitResult = DB_query($SQL,$ErrMsg);
573
574				$ParentQty = $NewItemQty;
575				while ($KitParts = DB_fetch_array($KitResult)) {
576					$NewItem = $KitParts['component'];
577					$NewItemQty = $KitParts['quantity'] * $ParentQty;
578					$NewPOLine = 0;
579					$NewItemDue = date($_SESSION['DefaultDateFormat']);
580					$_SESSION['Items'.$identifier]->GetTaxes($OrderLine->LineNumber);
581				}
582
583			} else { /*Its not a kit set item*/
584				$NewItemDue = date($_SESSION['DefaultDateFormat']);
585				$NewPOLine = 0;
586				$_SESSION['Items'.$identifier]->GetTaxes($OrderLine->LineNumber);
587			}
588		}
589		unset($NewItem);
590	} /* end of if its a new item */
591}
592
593if (isset($NewItem)) {
594/* get the item details from the database and hold them in the cart object make the quantity 1 by default then add it to the cart
595Now figure out if the item is a kit set - the field MBFlag='K'
596* controlled items and ghost/phantom items cannot be selected because the SQL to show items to select doesn't show 'em
597* */
598	$AlreadyWarnedAboutCredit = false;
599
600	$SQL = "SELECT stockmaster.mbflag,
601				stockmaster.taxcatid
602			FROM stockmaster
603			WHERE stockmaster.stockid='". $NewItem ."'";
604
605	$ErrMsg =  _('Could not determine if the part being ordered was a kitset or not because');
606
607	$KitResult = DB_query($SQL,$ErrMsg);
608
609	$NewItemQty = 1; /*By Default */
610	$Discount = 0; /*By default - can change later or discount category override */
611
612	if ($MyRow=DB_fetch_array($KitResult)) {
613	   	if ($MyRow['mbflag']=='K') {	/*It is a kit set item */
614			$SQL = "SELECT bom.component,
615						bom.quantity
616					FROM bom
617					WHERE bom.parent='" . $NewItem . "'
618                    AND bom.effectiveafter <= '" . date('Y-m-d') . "'
619                    AND bom.effectiveto > '" . date('Y-m-d') . "'";
620
621			$ErrMsg = _('Could not retrieve kitset components from the database because');
622			$KitResult = DB_query($SQL,$ErrMsg);
623
624			$ParentQty = $NewItemQty;
625			while ($KitParts = DB_fetch_array($KitResult)) {
626				$NewItem = $KitParts['component'];
627				$NewItemQty = $KitParts['quantity'] * $ParentQty;
628				$NewPOLine = 0;
629				$NewItemDue = date($_SESSION['DefaultDateFormat']);
630				include('includes/SelectOrderItems_IntoCart.inc');
631				$_SESSION['Items'.$identifier]->GetTaxes(($_SESSION['Items'.$identifier]->LineCounter - 1));
632			}
633
634		} else { /*Its not a kit set item*/
635			$NewItemDue = date($_SESSION['DefaultDateFormat']);
636			$NewPOLine = 0;
637
638			include('includes/SelectOrderItems_IntoCart.inc');
639			$_SESSION['Items'.$identifier]->GetTaxes(($_SESSION['Items'.$identifier]->LineCounter - 1));
640		}
641
642	} /* end of if its a new item */
643
644} /*end of if its a new item */
645
646if (isset($NewItemArray) AND isset($_POST['SelectingOrderItems'])) {
647/* get the item details from the database and hold them in the cart object make the quantity 1 by default then add it to the cart */
648/*Now figure out if the item is a kit set - the field MBFlag='K'*/
649	$AlreadyWarnedAboutCredit = false;
650
651	foreach($NewItemArray as $NewItem => $NewItemQty) {
652		if($NewItemQty > 0)	{
653			$SQL = "SELECT stockmaster.mbflag
654					FROM stockmaster
655					WHERE stockmaster.stockid='". $NewItem ."'";
656
657			$ErrMsg =  _('Could not determine if the part being ordered was a kitset or not because');
658
659			$KitResult = DB_query($SQL,$ErrMsg);
660
661			//$NewItemQty = 1; /*By Default */
662			$Discount = 0; /*By default - can change later or discount category override */
663
664			if ($MyRow=DB_fetch_array($KitResult)) {
665				if ($MyRow['mbflag']=='K') {	/*It is a kit set item */
666					$SQL = "SELECT bom.component,
667	        					bom.quantity
668		          			FROM bom
669							WHERE bom.parent='" . $NewItem . "'
670                            AND bom.effectiveafter <= '" . date('Y-m-d') . "'
671                            AND bom.effectiveto > '" . date('Y-m-d') . "'";
672
673					$ErrMsg = _('Could not retrieve kitset components from the database because');
674					$KitResult = DB_query($SQL,$ErrMsg);
675
676					$ParentQty = $NewItemQty;
677					while ($KitParts = DB_fetch_array($KitResult)) {
678						$NewItem = $KitParts['component'];
679						$NewItemQty = $KitParts['quantity'] * $ParentQty;
680						$NewItemDue = date($_SESSION['DefaultDateFormat']);
681						$NewPOLine = 0;
682						include('includes/SelectOrderItems_IntoCart.inc');
683						$_SESSION['Items'.$identifier]->GetTaxes(($_SESSION['Items'.$identifier]->LineCounter - 1));
684					}
685
686				} else { /*Its not a kit set item*/
687					$NewItemDue = date($_SESSION['DefaultDateFormat']);
688					$NewPOLine = 0;
689					include('includes/SelectOrderItems_IntoCart.inc');
690					$_SESSION['Items'.$identifier]->GetTaxes(($_SESSION['Items'.$identifier]->LineCounter - 1));
691				}
692			} /* end of if its a new item */
693		} /*end of if its a new item */
694	}
695}
696
697
698/* Now Run through each line of the order again to work out the appropriate discount from the discount matrix */
699$DiscCatsDone = array();
700foreach ($_SESSION['Items'.$identifier]->LineItems as $OrderLine) {
701
702	if ($OrderLine->DiscCat !='' AND ! in_array($OrderLine->DiscCat,$DiscCatsDone)) {
703		$DiscCatsDone[]=$OrderLine->DiscCat;
704		$QuantityOfDiscCat = 0;
705
706		foreach ($_SESSION['Items'.$identifier]->LineItems as $OrderLine_2) {
707			/* add up total quantity of all lines of this DiscCat */
708			if ($OrderLine_2->DiscCat==$OrderLine->DiscCat) {
709				$QuantityOfDiscCat += $OrderLine_2->Quantity;
710			}
711		}
712		$result = DB_query("SELECT MAX(discountrate) AS discount
713							FROM discountmatrix
714							WHERE salestype='" .  $_SESSION['Items'.$identifier]->DefaultSalesType . "'
715							AND discountcategory ='" . $OrderLine->DiscCat . "'
716							AND quantitybreak <= '" . $QuantityOfDiscCat ."'");
717		$MyRow = DB_fetch_row($result);
718		if ($MyRow[0]==NULL) {
719			$DiscountMatrixRate = 0;
720		} else {
721			$DiscountMatrixRate = $MyRow[0];
722		}
723		if ($MyRow[0]!=0) { /* need to update the lines affected */
724			foreach ($_SESSION['Items'.$identifier]->LineItems as $OrderLine_2) {
725				if ($OrderLine_2->DiscCat==$OrderLine->DiscCat) {
726					$_SESSION['Items'.$identifier]->LineItems[$OrderLine_2->LineNumber]->DiscountPercent = $DiscountMatrixRate;
727					$_SESSION['Items'.$identifier]->LineItems[$OrderLine_2->LineNumber]->GPPercent = (($_SESSION['Items'.$identifier]->LineItems[$OrderLine_2->LineNumber]->Price*(1-$DiscountMatrixRate)) - $_SESSION['Items'.$identifier]->LineItems[$OrderLine_2->LineNumber]->StandardCost*$ExRate)/($_SESSION['Items'.$identifier]->LineItems[$OrderLine_2->LineNumber]->Price *(1-$DiscountMatrixRate)/100);
728				}
729			}
730		}
731	}
732} /* end of discount matrix lookup code */
733
734
735if (count($_SESSION['Items'.$identifier]->LineItems)>0 ) { /*only show order lines if there are any */
736/*
737// *************************************************************************
738//   T H I S   W H E R E   T H E   S A L E  I S   D I S P L A Y E D
739// *************************************************************************
740*/
741
742	echo '<br />
743		<table width="90%" cellpadding="2">
744		<tr style="tableheader">';
745	echo '<th>' . _('Item Code') . '</th>
746   	      <th>' . _('Item Description') . '</th>
747	      <th>' . _('Quantity') . '</th>
748	      <th>' . _('QOH') . '</th>
749	      <th>' . _('Unit') . '</th>
750	      <th>' . _('Price') . '</th>';
751	if (in_array($_SESSION['PageSecurityArray']['OrderEntryDiscountPricing'], $_SESSION['AllowedPageSecurityTokens'])) {
752		echo '<th>' . _('Discount') . '</th>
753			  <th>' . _('GP %') . '</th>';
754	}
755	echo '<th>' . _('Net') . '</th>
756	      <th>' . _('Tax') . '</th>
757	      <th>' . _('Total') . '<br />' . _('Incl Tax') . '</th>
758	      </tr>';
759
760	$_SESSION['Items'.$identifier]->total = 0;
761	$_SESSION['Items'.$identifier]->totalVolume = 0;
762	$_SESSION['Items'.$identifier]->totalWeight = 0;
763	$TaxTotals = array();
764	$TaxGLCodes = array();
765	$TaxTotal =0;
766
767	foreach ($_SESSION['Items'.$identifier]->LineItems as $OrderLine) {
768
769		$SubTotal = round($OrderLine->Quantity * $OrderLine->Price * (1 - $OrderLine->DiscountPercent),$_SESSION['Items'.$identifier]->CurrDecimalPlaces);
770		$DisplayDiscount = locale_number_format(($OrderLine->DiscountPercent * 100),2);
771		$QtyOrdered = $OrderLine->Quantity;
772		$QtyRemain = $QtyOrdered - $OrderLine->QtyInv;
773
774		if ($OrderLine->QOHatLoc < $OrderLine->Quantity AND ($OrderLine->MBflag=='B' OR $OrderLine->MBflag=='M')) {
775			/*There is a stock deficiency in the stock location selected */
776			$RowStarter = '<tr style="background-color:#EEAABB">';
777		} else {
778			$RowStarter = '<tr class="striped_row">';
779		}
780
781		echo $RowStarter;
782		echo '<td><input type="hidden" name="POLine_' .	 $OrderLine->LineNumber . '" value="" />';
783		echo '<input type="hidden" name="ItemDue_' .	 $OrderLine->LineNumber . '" value="'.$OrderLine->ItemDue.'" />';
784
785		echo '<a target="_blank" href="' . $RootPath . '/StockStatus.php?identifier='.$identifier . '&amp;StockID=' . $OrderLine->StockID . '&amp;DebtorNo=' . $_SESSION['Items'.$identifier]->DebtorNo . '">' . $OrderLine->StockID . '</a></td>
786			<td title="' . $OrderLine->LongDescription . '">' . $OrderLine->ItemDescription . '</td>';
787
788		echo '<td><input class="number" tabindex="2" type="text" name="Quantity_' . $OrderLine->LineNumber . '" required="required" size="6" maxlength="6" value="' . locale_number_format($OrderLine->Quantity,$OrderLine->DecimalPlaces) . '" />';
789
790		echo '</td>
791			<td class="number">' . locale_number_format($OrderLine->QOHatLoc,$OrderLine->DecimalPlaces) . '</td>
792			<td>' . $OrderLine->Units . '</td>';
793		if (in_array($_SESSION['PageSecurityArray']['OrderEntryDiscountPricing'], $_SESSION['AllowedPageSecurityTokens'])) {
794			echo '<td><input class="number" type="text" name="Price_' . $OrderLine->LineNumber . '" required="required" size="16" maxlength="16" value="' . locale_number_format($OrderLine->Price,$_SESSION['Items'.$identifier]->CurrDecimalPlaces) . '" /></td>
795				<td><input class="number" type="text" name="Discount_' . $OrderLine->LineNumber . '" required="required" size="5" maxlength="4" value="' . locale_number_format(($OrderLine->DiscountPercent * 100),2) . '" /></td>
796				<td><input class="number" type="text" name="GPPercent_' . $OrderLine->LineNumber . '" required="required" size="3" maxlength="40" value="' . locale_number_format($OrderLine->GPPercent,2) . '" /></td>';
797		} else {
798			echo '<td class="number">' . locale_number_format($OrderLine->Price,$_SESSION['Items'.$identifier]->CurrDecimalPlaces) . '<input type="hidden" name="Price_' . $OrderLine->LineNumber . '"  value="' . locale_number_format($OrderLine->Price,$_SESSION['Items'.$identifier]->CurrDecimalPlaces) . '" />
799				<input type="hidden" name="Discount_' . $OrderLine->LineNumber . '" value="' . locale_number_format(($OrderLine->DiscountPercent * 100),2) . '" />
800				<input type="hidden" name="GPPercent_' . $OrderLine->LineNumber . '" value="' . locale_number_format($OrderLine->GPPercent,2) . '" /></td>';
801		}
802		echo '<td class="number">' . locale_number_format($SubTotal,$_SESSION['Items'.$identifier]->CurrDecimalPlaces) . '</td>';
803		$LineDueDate = $OrderLine->ItemDue;
804		if (!Is_Date($OrderLine->ItemDue)) {
805			$LineDueDate = DateAdd (Date($_SESSION['DefaultDateFormat']),'d', $_SESSION['Items'.$identifier]->DeliveryDays);
806			$_SESSION['Items'.$identifier]->LineItems[$OrderLine->LineNumber]->ItemDue= $LineDueDate;
807		}
808		$i=0; // initialise the number of taxes iterated through
809		$TaxLineTotal =0; //initialise tax total for the line
810
811		foreach ($OrderLine->Taxes AS $Tax) {
812			if (empty($TaxTotals[$Tax->TaxAuthID])) {
813				$TaxTotals[$Tax->TaxAuthID]=0;
814			}
815			if ($Tax->TaxOnTax ==1) {
816				$TaxTotals[$Tax->TaxAuthID] += ($Tax->TaxRate * ($SubTotal + $TaxLineTotal));
817				$TaxLineTotal += ($Tax->TaxRate * ($SubTotal + $TaxLineTotal));
818			} else {
819				$TaxTotals[$Tax->TaxAuthID] += ($Tax->TaxRate * $SubTotal);
820				$TaxLineTotal += ($Tax->TaxRate * $SubTotal);
821			}
822			$TaxGLCodes[$Tax->TaxAuthID] = $Tax->TaxGLCode;
823		}
824
825		$TaxTotal += $TaxLineTotal;
826		$_SESSION['Items'.$identifier]->TaxTotals=$TaxTotals;
827		$_SESSION['Items'.$identifier]->TaxGLCodes=$TaxGLCodes;
828		echo '<td class="number">' . locale_number_format($TaxLineTotal ,$_SESSION['Items'.$identifier]->CurrDecimalPlaces) . '</td>';
829		echo '<td class="number">' . locale_number_format($SubTotal + $TaxLineTotal ,$_SESSION['Items'.$identifier]->CurrDecimalPlaces) . '</td>';
830		echo '<td><a href="' . htmlspecialchars($_SERVER['PHP_SELF'],ENT_QUOTES,'UTF-8') . '?identifier='.$identifier . '&amp;Delete=' . $OrderLine->LineNumber . '" onclick="return confirm(\'' . _('Are You Sure?') . '\');">' . _('Delete') . '</a></td></tr>';
831
832		if ($_SESSION['AllowOrderLineItemNarrative'] == 1) {
833			echo $RowStarter;
834			echo '<td valign="top" colspan="11">' . _('Narrative') . ':<textarea name="Narrative_' . $OrderLine->LineNumber . '" cols="100" rows="1">' . stripslashes(AddCarriageReturns($OrderLine->Narrative)) . '</textarea><br /></td></tr>';
835		} else {
836			echo '<input type="hidden" name="Narrative" value="" />';
837		}
838
839		$_SESSION['Items'.$identifier]->total = $_SESSION['Items'.$identifier]->total + $SubTotal;
840		$_SESSION['Items'.$identifier]->totalVolume = $_SESSION['Items'.$identifier]->totalVolume + $OrderLine->Quantity * $OrderLine->Volume;
841		$_SESSION['Items'.$identifier]->totalWeight = $_SESSION['Items'.$identifier]->totalWeight + $OrderLine->Quantity * $OrderLine->Weight;
842
843	} /* end of loop around items */
844
845	echo '<tr class="striped_row">';
846	if (in_array($_SESSION['PageSecurityArray']['OrderEntryDiscountPricing'], $_SESSION['AllowedPageSecurityTokens'])) {
847		echo '<td colspan="8" class="number"><b>' . _('Total') . '</b></td>';
848	} else {
849		echo '<td colspan="6" class="number"><b>' . _('Total') . '</b></td>';
850	}
851	echo '<td class="number">' . locale_number_format(($_SESSION['Items'.$identifier]->total),$_SESSION['Items'.$identifier]->CurrDecimalPlaces) . '</td>
852			<td class="number">' . locale_number_format($TaxTotal,$_SESSION['Items'.$identifier]->CurrDecimalPlaces) . '</td>
853			<td class="number">' . locale_number_format(($_SESSION['Items'.$identifier]->total+$TaxTotal),$_SESSION['Items'.$identifier]->CurrDecimalPlaces) . '</td>
854		</tr>
855		</table>';
856	echo '<input type="hidden" name="TaxTotal" value="'.$TaxTotal.'" />';
857	echo '<table><tr><td>';
858	//nested table
859	echo '<table><tr>
860		<td>' .  _('Picked Up By') .':</td>
861		<td><input type="text" size="25" maxlength="25" name="DeliverTo" value="' . stripslashes($_SESSION['Items'.$identifier]->DeliverTo) . '" /></td>
862	</tr>';
863	echo '<tr>
864		<td>' .  _('Contact Phone Number') .':</td>
865		<td><input type="te1" size="25" maxlength="25" name="PhoneNo" value="' . stripslashes($_SESSION['Items'.$identifier]->PhoneNo) . '" /></td>
866	</tr>';
867
868	echo '<tr>
869			<td>' . _('Contact Email') . ':</td>
870			<td><input type="email" placeholder="contact@domain.com" size="25" maxlength="30" name="Email" value="' . stripslashes($_SESSION['Items'.$identifier]->Email) . '" /></td></tr>';
871
872	echo '<tr>
873			<td>' .  _('Customer Reference') .':</td>
874			<td><input type="text" size="25" maxlength="25" name="CustRef" value="' . stripcslashes($_SESSION['Items'.$identifier]->CustRef) . '" /></td>
875		</tr>';
876
877	echo '<tr>
878			<td>' . _('Sales person'). ':</td>';
879
880	if ($_SESSION['SalesmanLogin'] != '') {
881		echo '<td>';
882		echo $_SESSION['UsersRealName'];
883		echo '</td>';
884	}else{
885		echo '<td><select name="SalesPerson">';
886		$SalesPeopleResult = DB_query("SELECT salesmancode, salesmanname FROM salesman WHERE current=1");
887		if (!isset($_POST['SalesPerson']) AND $_SESSION['SalesmanLogin']!=NULL ) {
888			$_SESSION['Items'.$identifier]->SalesPerson = $_SESSION['SalesmanLogin'];
889		}
890
891		while ($SalesPersonRow = DB_fetch_array($SalesPeopleResult)) {
892			if ($SalesPersonRow['salesmancode']==$_SESSION['Items'.$identifier]->SalesPerson) {
893				echo '<option selected="selected" value="' . $SalesPersonRow['salesmancode'] . '">' . $SalesPersonRow['salesmanname'] . '</option>';
894			} else {
895				echo '<option value="' . $SalesPersonRow['salesmancode'] . '">' . $SalesPersonRow['salesmanname'] . '</option>';
896			}
897		}
898
899		echo '</select></td>';
900	}
901	echo '</tr>';
902	echo '<tr>
903			<td>' .  _('Comments') .':</td>
904			<td><textarea name="Comments" cols="23" rows="5">' . stripcslashes($_SESSION['Items'.$identifier]->Comments)  . '</textarea></td>
905		</tr>';
906	echo '</table>'; //end the sub table in the first column of master table
907	echo '</td><th valign="bottom">'; //for the master table
908	echo '<table class="selection">'; // a new nested table in the second column of master table
909	//now the payment stuff in this column
910	$PaymentMethodsResult = DB_query("SELECT paymentid, paymentname FROM paymentmethods");
911
912	echo '<tr>
913			<td>' . _('Payment Type') . ':</td>
914			<td><select name="PaymentMethod">';
915	while ($PaymentMethodRow = DB_fetch_array($PaymentMethodsResult)) {
916		if (isset($_POST['PaymentMethod']) AND $_POST['PaymentMethod'] == $PaymentMethodRow['paymentid']) {
917			echo '<option selected="selected" value="' . $PaymentMethodRow['paymentid'] . '">' . $PaymentMethodRow['paymentname'] . '</option>';
918		} else {
919			echo '<option value="' . $PaymentMethodRow['paymentid'] . '">' . $PaymentMethodRow['paymentname'] . '</option>';
920		}
921	}
922	echo '</select></td>
923		</tr>';
924
925	$BankAccountsResult = DB_query("SELECT bankaccountname, accountcode, currcode FROM bankaccounts ORDER BY bankaccountname");
926
927	echo '<tr>
928			<td>' . _('Banked to') . ':</td>
929			<td><select name="BankAccount">';
930	while ($MyRow = DB_fetch_array($BankAccountsResult)) {
931		// Lists bank accounts order by bankaccountname
932		echo '<option',
933			((isset($_POST['BankAccount']) and $_POST['BankAccount'] == $MyRow['accountcode']) ? ' selected="selected"' : '' ),
934			' value="', $MyRow['accountcode'], '">', $MyRow['bankaccountname'], ' - ', $MyRow['currcode'], '</option>';
935	}
936	echo '</select></td>
937		</tr>';
938
939	if (!isset($_POST['CashReceived'])) {
940		$_POST['CashReceived'] =0;
941	}
942	echo '<tr>
943			<td>' . _('Cash Received') . ':</td>
944			<td><input type="text" class="number" id="CashReceived" name="CashReceived" required="required"  maxlength="12" size="12" value="' . $_POST['CashReceived'] . '" onkeyup="CalculateChangeDue();" /></td>
945		</tr>';
946
947	if (!isset($_POST['AmountPaid'])) {
948		$_POST['AmountPaid'] =0;
949	}
950	echo '<tr>
951			<td>' . _('Amount Paid') . ':</td>
952			<td><input type="text" class="number" id="AmountPaid" name="AmountPaid" required="required"  title="' . _('Enter the amount paid by the customer, this must equal the amount of the sale') . '" maxlength="12" size="12" value="' . $_POST['AmountPaid'] . '" readonly /></td>
953		</tr>';
954
955	if (!isset($_POST['ChangeDue'])) {
956		$_POST['ChangeDue'] =0;
957	}
958	echo '<tr>
959			<td>' . _('Change') . ':</td>
960			<td><input type="text" class="number" id="ChangeDue" name="ChangeDue" maxlength="12" size="12" value="' . $_POST['ChangeDue'] . '" readonly /></td>
961		</tr>';
962
963	echo '</table>'; //end the sub table in the second column of master table
964	echo '</th>
965		</tr>
966		</table>';	//end of column/row/master table
967	if (!isset($_POST['ProcessSale'])) {
968		echo '<br />
969				<div class="centre">
970					<input type="submit" name="Recalculate" value="' . _('Re-Calculate') . '" />
971					<input type="submit" name="ProcessSale" value="' . _('Process The Sale') . '" />
972				</div>';
973	}
974	echo '<hr />';
975
976} # end of if lines
977
978/* **********************************
979 * Invoice Processing Here
980 * **********************************
981 * */
982if (isset($_POST['ProcessSale']) AND $_POST['ProcessSale'] != '') {
983
984	$InputError = false; //always assume the best
985	//but check for the worst
986	if ($_SESSION['Items'.$identifier]->LineCounter == 0) {
987		prnMsg(_('There are no lines on this sale. Please enter lines to invoice first'),'error');
988		$InputError = true;
989	}
990	if (abs(filter_number_format($_POST['AmountPaid']) -(round($_SESSION['Items'.$identifier]->total+filter_number_format($_POST['TaxTotal']),$_SESSION['Items'.$identifier]->CurrDecimalPlaces)))>=0.01) {
991		prnMsg(_('The amount entered as payment does not equal the amount of the invoice. Please ensure the customer has paid the correct amount and re-enter'),'error');
992		$InputError = true;
993	}
994
995	if ($_SESSION['ProhibitNegativeStock']==1) { // checks for negative stock after processing invoice
996	//sadly this check does not combine quantities occuring twice on and order and each line is considered individually :-(
997		$NegativesFound = false;
998		foreach ($_SESSION['Items'.$identifier]->LineItems as $OrderLine) {
999			$SQL = "SELECT stockmaster.description,
1000					   		locstock.quantity,
1001					   		stockmaster.mbflag
1002		 			FROM locstock
1003		 			INNER JOIN stockmaster
1004					ON stockmaster.stockid=locstock.stockid
1005					WHERE stockmaster.stockid='" . $OrderLine->StockID . "'
1006					AND locstock.loccode='" . $_SESSION['Items'.$identifier]->Location . "'";
1007
1008			$ErrMsg = _('Could not retrieve the quantity left at the location once this order is invoiced (for the purposes of checking that stock will not go negative because)');
1009			$Result = DB_query($SQL,$ErrMsg);
1010			$CheckNegRow = DB_fetch_array($Result);
1011			if ($CheckNegRow['mbflag']=='B' OR $CheckNegRow['mbflag']=='M') {
1012				if ($CheckNegRow['quantity'] < $OrderLine->Quantity) {
1013					prnMsg( _('Invoicing the selected order would result in negative stock. The system parameters are set to prohibit negative stocks from occurring. This invoice cannot be created until the stock on hand is corrected.'),'error',$OrderLine->StockID . ' ' . $CheckNegRow['description'] . ' - ' . _('Negative Stock Prohibited'));
1014					$NegativesFound = true;
1015				}
1016			} else if ($CheckNegRow['mbflag']=='A') {
1017
1018				/*Now look for assembly components that would go negative */
1019				$SQL = "SELECT bom.component,
1020							   stockmaster.description,
1021							   locstock.quantity-(" . $OrderLine->Quantity  . "*bom.quantity) AS qtyleft
1022						FROM bom
1023						INNER JOIN locstock
1024						ON bom.component=locstock.stockid
1025						INNER JOIN stockmaster
1026						ON stockmaster.stockid=bom.component
1027						WHERE bom.parent='" . $OrderLine->StockID . "'
1028						AND locstock.loccode='" . $_SESSION['Items'.$identifier]->Location . "'
1029                        AND bom.effectiveafter <= '" . date('Y-m-d') . "'
1030                        AND bom.effectiveto > '" . date('Y-m-d') . "'";
1031
1032				$ErrMsg = _('Could not retrieve the component quantity left at the location once the assembly item on this order is invoiced (for the purposes of checking that stock will not go negative because)');
1033				$Result = DB_query($SQL,$ErrMsg);
1034				while ($NegRow = DB_fetch_array($Result)) {
1035					if ($NegRow['qtyleft']<0) {
1036						prnMsg(_('Invoicing the selected order would result in negative stock for a component of an assembly item on the order. The system parameters are set to prohibit negative stocks from occurring. This invoice cannot be created until the stock on hand is corrected.'),'error',$NegRow['component'] . ' ' . $NegRow['description'] . ' - ' . _('Negative Stock Prohibited'));
1037						$NegativesFound = true;
1038					} // end if negative would result
1039				} //loop around the components of an assembly item
1040			}//end if its an assembly item - check component stock
1041
1042		} //end of loop around items on the order for negative check
1043
1044		if ($NegativesFound) {
1045			prnMsg(_('The parameter to prohibit negative stock is set and invoicing this sale would result in negative stock. No futher processing can be performed. Alter the sale first changing quantities or deleting lines which do not have sufficient stock.'),'error');
1046			$InputError = true;
1047		}
1048
1049	}//end of testing for negative stocks
1050
1051	if ($InputError == true ) { //allow the error to be fixed and then resubmit buttone needs to show
1052		echo '<br />
1053				<div class="centre">
1054					<input type="submit" name="Recalculate" value="' . _('Re-Calculate') . '" />
1055					<input type="submit" name="ProcessSale" value="' . _('Process The Sale') . '" />
1056				</div>
1057				<hr />';
1058	} else { //all good so let's get on with the processing
1059
1060	/* Now Get the area where the sale is to from the branches table */
1061
1062		$SQL = "SELECT area,
1063						defaultshipvia
1064				FROM custbranch
1065				WHERE custbranch.debtorno ='". $_SESSION['Items'.$identifier]->DebtorNo . "'
1066				AND custbranch.branchcode = '" . $_SESSION['Items'.$identifier]->Branch . "'";
1067
1068		$ErrMsg = _('We were unable to load the area from the custbranch table where the sale is to ');
1069		$Result = DB_query($SQL, $ErrMsg);
1070		$MyRow = DB_fetch_row($Result);
1071		$Area = $MyRow[0];
1072		$DefaultShipVia = $MyRow[1];
1073		DB_free_result($Result);
1074
1075	/*company record read in on login with info on GL Links and debtors GL account*/
1076
1077		if ($_SESSION['CompanyRecord']==0) {
1078			/*The company data and preferences could not be retrieved for some reason */
1079			prnMsg( _('The company information and preferences could not be retrieved. See your system administrator'), 'error');
1080			include('includes/footer.php');
1081			exit;
1082		}
1083
1084	// *************************************************************************
1085	//   S T A R T   O F   I N V O I C E   S Q L   P R O C E S S I N G
1086	// *************************************************************************
1087		$result = DB_Txn_Begin();
1088	/*First add the order to the database - it only exists in the session currently! */
1089		$OrderNo = GetNextTransNo(30);
1090		$InvoiceNo = GetNextTransNo(10);
1091		$PeriodNo = GetPeriod(Date($_SESSION['DefaultDateFormat']));
1092
1093		$HeaderSQL = "INSERT INTO salesorders (	orderno,
1094												debtorno,
1095												branchcode,
1096												customerref,
1097												comments,
1098												orddate,
1099												ordertype,
1100												shipvia,
1101												deliverto,
1102												deladd1,
1103												contactphone,
1104												contactemail,
1105												fromstkloc,
1106												deliverydate,
1107												confirmeddate,
1108												deliverblind,
1109												salesperson)
1110											VALUES (
1111												'" . $OrderNo . "',
1112												'" . $_SESSION['Items'.$identifier]->DebtorNo . "',
1113												'" . $_SESSION['Items'.$identifier]->Branch . "',
1114												'". $_SESSION['Items'.$identifier]->CustRef ."',
1115												'". $_SESSION['Items'.$identifier]->Comments ."',
1116												'" . Date('Y-m-d H:i') . "',
1117												'" . $_SESSION['Items'.$identifier]->DefaultSalesType . "',
1118												'" . $_SESSION['Items'.$identifier]->ShipVia . "',
1119												'". $_SESSION['Items'.$identifier]->DeliverTo . "',
1120												'" . _('Counter Sale') . "',
1121												'" . $_SESSION['Items'.$identifier]->PhoneNo . "',
1122												'" . $_SESSION['Items'.$identifier]->Email . "',
1123												'" . $_SESSION['Items'.$identifier]->Location ."',
1124												'" . Date('Y-m-d') . "',
1125												'" . Date('Y-m-d') . "',
1126												0,
1127												'" . $_SESSION['Items'.$identifier]->SalesPerson . "')";
1128		$DbgMsg = _('Trouble inserting the sales order header. The SQL that failed was');
1129		$ErrMsg = _('The order cannot be added because');
1130		$InsertQryResult = DB_query($HeaderSQL,$ErrMsg,$DbgMsg,true);
1131
1132		$StartOf_LineItemsSQL = "INSERT INTO salesorderdetails (orderlineno,
1133																orderno,
1134																stkcode,
1135																unitprice,
1136																quantity,
1137																discountpercent,
1138																narrative,
1139																itemdue,
1140																actualdispatchdate,
1141																qtyinvoiced,
1142																completed)
1143															VALUES (";
1144
1145		$DbgMsg = _('Trouble inserting a line of a sales order. The SQL that failed was');
1146		foreach ($_SESSION['Items'.$identifier]->LineItems as $StockItem) {
1147
1148			$LineItemsSQL = $StartOf_LineItemsSQL .
1149					"'".$StockItem->LineNumber . "',
1150					'" . $OrderNo . "',
1151					'" . $StockItem->StockID . "',
1152					'". $StockItem->Price . "',
1153					'" . $StockItem->Quantity . "',
1154					'" . floatval($StockItem->DiscountPercent) . "',
1155					'" . $StockItem->Narrative . "',
1156					'" . Date('Y-m-d') . "',
1157					'" . Date('Y-m-d') . "',
1158					'" . $StockItem->Quantity . "',
1159					1)";
1160
1161			$ErrMsg = _('Unable to add the sales order line');
1162			$Ins_LineItemResult = DB_query($LineItemsSQL,$ErrMsg,$DbgMsg,true);
1163
1164			/*Now check to see if the item is manufactured
1165			 * 			and AutoCreateWOs is on
1166			 * 			and it is a real order (not just a quotation)*/
1167
1168			if ($StockItem->MBflag=='M'
1169				AND $_SESSION['AutoCreateWOs']==1) { //oh yeah its all on!
1170
1171				//now get the data required to test to see if we need to make a new WO
1172				$QOHResult = DB_query("SELECT SUM(quantity) FROM locstock WHERE stockid='" . $StockItem->StockID . "'");
1173				$QOHRow = DB_fetch_row($QOHResult);
1174				$QOH = $QOHRow[0];
1175
1176				$SQL = "SELECT SUM(salesorderdetails.quantity - salesorderdetails.qtyinvoiced) AS qtydemand
1177						FROM salesorderdetails INNER JOIN salesorders
1178						ON salesorderdetails.orderno=salesorders.orderno
1179						WHERE salesorderdetails.stkcode = '" . $StockItem->StockID . "'
1180						AND salesorderdetails.completed = 0
1181						AND salesorders.quotation = 0";
1182				$DemandResult = DB_query($SQL);
1183				$DemandRow = DB_fetch_row($DemandResult);
1184				$QuantityDemand = $DemandRow[0];
1185
1186				$SQL = "SELECT SUM((salesorderdetails.quantity-salesorderdetails.qtyinvoiced)*bom.quantity) AS dem
1187						FROM salesorderdetails INNER JOIN salesorders
1188						ON salesorderdetails.orderno=salesorders.orderno
1189						INNER JOIN bom
1190						ON salesorderdetails.stkcode=bom.parent
1191						INNER JOIN stockmaster
1192						ON stockmaster.stockid=bom.parent
1193						WHERE salesorderdetails.quantity-salesorderdetails.qtyinvoiced > 0
1194						AND bom.component='" . $StockItem->StockID . "'
1195						AND salesorderdetails.completed=0
1196						AND salesorders.quotation=0";
1197				$AssemblyDemandResult = DB_query($SQL);
1198				$AssemblyDemandRow = DB_fetch_row($AssemblyDemandResult);
1199				$QuantityAssemblyDemand = $AssemblyDemandRow[0];
1200
1201				// Get the QOO due to Purchase orders for all locations. Function defined in SQL_CommonFunctions.inc
1202				$QuantityPurchOrders= GetQuantityOnOrderDueToPurchaseOrders($StockItem->StockID, '');
1203				// Get the QOO dues to Work Orders for all locations. Function defined in SQL_CommonFunctions.inc
1204				$QuantityWorkOrders = GetQuantityOnOrderDueToWorkOrders($StockItem->StockID, '');
1205
1206				//Now we have the data - do we need to make any more?
1207				$ShortfallQuantity = $QOH-$QuantityDemand-$QuantityAssemblyDemand+$QuantityPurchOrders+$QuantityWorkOrders;
1208
1209				if ($ShortfallQuantity < 0) { //then we need to make a work order
1210					//How many should the work order be for??
1211					if ($ShortfallQuantity + $StockItem->EOQ < 0) {
1212						$WOQuantity = -$ShortfallQuantity;
1213					} else {
1214						$WOQuantity = $StockItem->EOQ;
1215					}
1216
1217					$WONo = GetNextTransNo(40);
1218					$ErrMsg = _('Unable to insert a new work order for the sales order item');
1219					$InsWOResult = DB_query("INSERT INTO workorders (wo,
1220													 loccode,
1221													 requiredby,
1222													 startdate)
1223									 VALUES ('" . $WONo . "',
1224											'" . $_SESSION['DefaultFactoryLocation'] . "',
1225											'" . Date('Y-m-d') . "',
1226											'" . Date('Y-m-d'). "')",
1227											$ErrMsg,
1228											$DbgMsg,
1229											true);
1230					//Need to get the latest BOM to roll up cost
1231					$CostResult = DB_query("SELECT SUM((materialcost+labourcost+overheadcost)*bom.quantity) AS cost
1232																	FROM stockmaster INNER JOIN bom
1233																	ON stockmaster.stockid=bom.component
1234																	WHERE bom.parent='" . $StockItem->StockID . "'
1235																	AND bom.loccode='" . $_SESSION['DefaultFactoryLocation'] . "'");
1236					$CostRow = DB_fetch_row($CostResult);
1237					if (is_null($CostRow[0]) OR $CostRow[0]==0) {
1238						$Cost =0;
1239						prnMsg(_('In automatically creating a work order for') . ' ' . $StockItem->StockID . ' ' . _('an item on this sales order, the cost of this item as accumulated from the sum of the component costs is nil. This could be because there is no bill of material set up ... you may wish to double check this'),'warn');
1240					} else {
1241						$Cost = $CostRow[0];
1242					}
1243
1244					// insert parent item info
1245					$SQL = "INSERT INTO woitems (wo,
1246												 stockid,
1247												 qtyreqd,
1248												 stdcost)
1249									 VALUES ('" . $WONo . "',
1250											 '" . $StockItem->StockID . "',
1251											 '" . $WOQuantity . "',
1252											 '" . $Cost . "')";
1253					$ErrMsg = _('The work order item could not be added');
1254					$result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1255
1256					//Recursively insert real component requirements - see includes/SQL_CommonFunctions.in for function WoRealRequirements
1257					WoRealRequirements($WONo, $_SESSION['DefaultFactoryLocation'], $StockItem->StockID);
1258
1259					$FactoryManagerEmail = _('A new work order has been created for') .
1260										":\n" . $StockItem->StockID . ' - ' . $StockItem->ItemDescription . ' x ' . $WOQuantity . ' ' . $StockItem->Units .
1261										"\n" . _('These are for') . ' ' . $_SESSION['Items'.$identifier]->CustomerName . ' ' . _('there order ref') . ': '  . $_SESSION['Items'.$identifier]->CustRef . ' ' ._('our order number') . ': ' . $OrderNo;
1262
1263					if ($StockItem->Serialised AND $StockItem->NextSerialNo>0) {
1264						//then we must create the serial numbers for the new WO also
1265						$FactoryManagerEmail .= "\n" . _('The following serial numbers have been reserved for this work order') . ':';
1266
1267						for ($i=0;$i<$WOQuantity;$i++) {
1268
1269							$result = DB_query("SELECT serialno FROM stockserialitems
1270													WHERE serialno='" . ($StockItem->NextSerialNo + $i) . "'
1271													AND stockid='" . $StockItem->StockID ."'");
1272							if (DB_num_rows($result)!=0) {
1273								$WOQuantity++;
1274								prnMsg(($StockItem->NextSerialNo + $i) . ': ' . _('This automatically generated serial number already exists - it cannot be added to the work order'),'error');
1275							} else {
1276								$SQL = "INSERT INTO woserialnos (wo,
1277																	stockid,
1278																	serialno)
1279														VALUES ('" . $WONo . "',
1280																'" . $StockItem->StockID . "',
1281																'" . ($StockItem->NextSerialNo + $i)	 . "')";
1282								$ErrMsg = _('The serial number for the work order item could not be added');
1283								$result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1284								$FactoryManagerEmail .= "\n" . ($StockItem->NextSerialNo + $i);
1285							}
1286						} //end loop around creation of woserialnos
1287						$NewNextSerialNo = ($StockItem->NextSerialNo + $WOQuantity +1);
1288						$ErrMsg = _('Could not update the new next serial number for the item');
1289						$UpdateSQL="UPDATE stockmaster SET nextserialno='" . $NewNextSerialNo . "' WHERE stockid='" . $StockItem->StockID . "'";
1290						$UpdateNextSerialNoResult = DB_query($UpdateSQL,$ErrMsg,$DbgMsg,true);
1291					} // end if the item is serialised and nextserialno is set
1292
1293					$EmailSubject = _('New Work Order Number') . ' ' . $WONo . ' ' . _('for') . ' ' . $StockItem->StockID . ' x ' . $WOQuantity;
1294					//Send email to the Factory Manager
1295					if($_SESSION['SmtpSetting']==0) {
1296							mail($_SESSION['FactoryManagerEmail'],$EmailSubject,$FactoryManagerEmail);
1297
1298					}else{
1299							include('includes/htmlMimeMail.php');
1300							$mail = new htmlMimeMail();
1301							$mail->setSubject($EmailSubject);
1302							$result = SendmailBySmtp($mail,array($_SESSION['FactoryManagerEmail']));
1303					}
1304
1305				} //end if with this sales order there is a shortfall of stock - need to create the WO
1306			}//end if auto create WOs in on
1307		} /* end inserted line items into sales order details */
1308
1309		prnMsg(_('Order Number') . ' ' . $OrderNo . ' ' . _('has been entered'),'success');
1310
1311	/* End of insertion of new sales order */
1312
1313	/*Now Get the next invoice number - GetNextTransNo() function in SQL_CommonFunctions
1314	 * GetPeriod() in includes/DateFunctions.inc */
1315
1316
1317
1318		$DefaultDispatchDate = Date('Y-m-d');
1319
1320	/*Update order header for invoice charged on */
1321		$SQL = "UPDATE salesorders SET comments = CONCAT(comments,'" . ' ' . _('Invoice') . ': ' . "','" . $InvoiceNo . "') WHERE orderno= '" . $OrderNo."'";
1322
1323		$ErrMsg = _('CRITICAL ERROR') . ' ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The sales order header could not be updated with the invoice number');
1324		$DbgMsg = _('The following SQL to update the sales order was used');
1325		$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1326
1327	/*Now insert the DebtorTrans */
1328
1329		$SQL = "INSERT INTO debtortrans (transno,
1330										type,
1331										debtorno,
1332										branchcode,
1333										trandate,
1334										inputdate,
1335										prd,
1336										reference,
1337										tpe,
1338										order_,
1339										ovamount,
1340										ovgst,
1341										rate,
1342										invtext,
1343										shipvia,
1344										alloc,
1345										settled,
1346										salesperson )
1347			VALUES (
1348				'". $InvoiceNo . "',
1349				10,
1350				'" . $_SESSION['Items'.$identifier]->DebtorNo . "',
1351				'" . $_SESSION['Items'.$identifier]->Branch . "',
1352				'" . $DefaultDispatchDate . "',
1353				'" . date('Y-m-d H-i-s') . "',
1354				'" . $PeriodNo . "',
1355				'" . $_SESSION['Items'.$identifier]->CustRef  . "',
1356				'" . $_SESSION['Items'.$identifier]->DefaultSalesType . "',
1357				'" . $OrderNo . "',
1358				'" . $_SESSION['Items'.$identifier]->total . "',
1359				'" . filter_number_format($_POST['TaxTotal']) . "',
1360				'" . $ExRate . "',
1361				'" . $_SESSION['Items'.$identifier]->Comments . "',
1362				'" . $_SESSION['Items'.$identifier]->ShipVia . "',
1363				'" . ($_SESSION['Items'.$identifier]->total + filter_number_format($_POST['TaxTotal'])) . "',
1364				'1',
1365				'" . $_SESSION['Items'.$identifier]->SalesPerson . "')";
1366
1367		$ErrMsg =_('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The debtor transaction record could not be inserted because');
1368		$DbgMsg = _('The following SQL to insert the debtor transaction record was used');
1369	 	$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1370
1371		$DebtorTransID = DB_Last_Insert_ID('debtortrans','id');
1372
1373	/* Insert the tax totals for each tax authority where tax was charged on the invoice */
1374		foreach ($_SESSION['Items'.$identifier]->TaxTotals AS $TaxAuthID => $TaxAmount) {
1375
1376			$SQL = "INSERT INTO debtortranstaxes (debtortransid,
1377													taxauthid,
1378													taxamount)
1379										VALUES ('" . $DebtorTransID . "',
1380											'" . $TaxAuthID . "',
1381											'" . $TaxAmount/$ExRate . "')";
1382
1383			$ErrMsg =_('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The debtor transaction taxes records could not be inserted because');
1384			$DbgMsg = _('The following SQL to insert the debtor transaction taxes record was used');
1385	 		$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1386		}
1387
1388		//Loop around each item on the sale and process each in turn
1389		foreach ($_SESSION['Items'.$identifier]->LineItems as $OrderLine) {
1390			 /* Update location stock records if not a dummy stock item
1391			 need the MBFlag later too so save it to $MBFlag */
1392			$Result = DB_query("SELECT mbflag FROM stockmaster WHERE stockid = '" . $OrderLine->StockID . "'");
1393			$MyRow = DB_fetch_row($Result);
1394			$MBFlag = $MyRow[0];
1395			if ($MBFlag=='B' OR $MBFlag=='M') {
1396				$Assembly = False;
1397
1398				/* Need to get the current location quantity
1399				will need it later for the stock movement */
1400				$SQL="SELECT locstock.quantity
1401								FROM locstock
1402								WHERE locstock.stockid='" . $OrderLine->StockID . "'
1403								AND loccode= '" . $_SESSION['Items'.$identifier]->Location . "'";
1404				$ErrMsg = _('WARNING') . ': ' . _('Could not retrieve current location stock');
1405				$Result = DB_query($SQL, $ErrMsg);
1406
1407				if (DB_num_rows($Result)==1) {
1408					$LocQtyRow = DB_fetch_row($Result);
1409					$QtyOnHandPrior = $LocQtyRow[0];
1410				} else {
1411					/* There must be some error this should never happen */
1412					$QtyOnHandPrior = 0;
1413				}
1414
1415				$SQL = "UPDATE locstock
1416							SET quantity = locstock.quantity - " . $OrderLine->Quantity . "
1417							WHERE locstock.stockid = '" . $OrderLine->StockID . "'
1418							AND loccode = '" . $_SESSION['Items'.$identifier]->Location . "'";
1419
1420				$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('Location stock record could not be updated because');
1421				$DbgMsg = _('The following SQL to update the location stock record was used');
1422				$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1423
1424			} else if ($MBFlag=='A') { /* its an assembly */
1425				/*Need to get the BOM for this part and make
1426				stock moves for the components then update the Location stock balances */
1427				$Assembly=True;
1428				$StandardCost =0; /*To start with - accumulate the cost of the comoponents for use in journals later on */
1429				$SQL = "SELECT bom.component,
1430						bom.quantity,
1431						stockmaster.materialcost+stockmaster.labourcost+stockmaster.overheadcost AS standard
1432						FROM bom,
1433							stockmaster
1434						WHERE bom.component=stockmaster.stockid
1435						AND bom.parent='" . $OrderLine->StockID . "'
1436                        AND bom.effectiveafter <= '" . date('Y-m-d') . "'
1437                        AND bom.effectiveto > '" . date('Y-m-d') . "'";
1438
1439				$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('Could not retrieve assembly components from the database for'). ' '. $OrderLine->StockID . _('because').' ';
1440				$DbgMsg = _('The SQL that failed was');
1441				$AssResult = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1442
1443				while ($AssParts = DB_fetch_array($AssResult)) {
1444
1445					$StandardCost += ($AssParts['standard'] * $AssParts['quantity']) ;
1446					/* Need to get the current location quantity
1447					will need it later for the stock movement */
1448					$SQL="SELECT locstock.quantity
1449									FROM locstock
1450									WHERE locstock.stockid='" . $AssParts['component'] . "'
1451									AND loccode= '" . $_SESSION['Items'.$identifier]->Location . "'";
1452
1453					$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('Can not retrieve assembly components location stock quantities because ');
1454					$DbgMsg = _('The SQL that failed was');
1455					$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1456					if (DB_num_rows($Result)==1) {
1457						$LocQtyRow = DB_fetch_row($Result);
1458						$QtyOnHandPrior = $LocQtyRow[0];
1459					} else {
1460						/*There must be some error this should never happen */
1461						$QtyOnHandPrior = 0;
1462					}
1463					if (empty($AssParts['standard'])) {
1464						$AssParts['standard']=0;
1465					}
1466					$SQL = "INSERT INTO stockmoves (stockid,
1467													type,
1468													transno,
1469													loccode,
1470													trandate,
1471													userid,
1472													debtorno,
1473													branchcode,
1474													prd,
1475													reference,
1476													qty,
1477													standardcost,
1478													show_on_inv_crds,
1479													newqoh)
1480										VALUES ('" . $AssParts['component'] . "',
1481												 10,
1482												'" . $InvoiceNo . "',
1483												'" . $_SESSION['Items'.$identifier]->Location . "',
1484												'" . $DefaultDispatchDate . "',
1485												'" . $_SESSION['UserID'] . "',
1486												'" . $_SESSION['Items'.$identifier]->DebtorNo . "',
1487												'" . $_SESSION['Items'.$identifier]->Branch . "',
1488												'" . $PeriodNo . "',
1489												'" . _('Assembly') . ': ' . $OrderLine->StockID . ' ' . _('Order') . ': ' . $OrderNo . "',
1490												'" . -$AssParts['quantity'] * $OrderLine->Quantity . "',
1491												'" . $AssParts['standard'] . "',
1492												0,
1493												newqoh-" . ($AssParts['quantity'] * $OrderLine->Quantity) . " )";
1494
1495					$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('Stock movement records for the assembly components of'). ' '. $OrderLine->StockID . ' ' . _('could not be inserted because');
1496					$DbgMsg = _('The following SQL to insert the assembly components stock movement records was used');
1497					$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1498
1499
1500					$SQL = "UPDATE locstock
1501							SET quantity = locstock.quantity - " . $AssParts['quantity'] * $OrderLine->Quantity . "
1502							WHERE locstock.stockid = '" . $AssParts['component'] . "'
1503							AND loccode = '" . $_SESSION['Items'.$identifier]->Location . "'";
1504
1505					$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('Location stock record could not be updated for an assembly component because');
1506					$DbgMsg = _('The following SQL to update the locations stock record for the component was used');
1507					$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1508				} /* end of assembly explosion and updates */
1509
1510				/*Update the cart with the recalculated standard cost from the explosion of the assembly's components*/
1511				$_SESSION['Items'.$identifier]->LineItems[$OrderLine->LineNumber]->StandardCost = $StandardCost;
1512				$OrderLine->StandardCost = $StandardCost;
1513			} /* end of its an assembly */
1514
1515			// Insert stock movements - with unit cost
1516			$LocalCurrencyPrice = ($OrderLine->Price / $ExRate);
1517
1518			if (empty($OrderLine->StandardCost)) {
1519				$OrderLine->StandardCost=0;
1520			}
1521			if ($MBFlag=='B' OR $MBFlag=='M') {
1522				$SQL = "INSERT INTO stockmoves (stockid,
1523												type,
1524												transno,
1525												loccode,
1526												trandate,
1527												userid,
1528												debtorno,
1529												branchcode,
1530												price,
1531												prd,
1532												reference,
1533												qty,
1534												discountpercent,
1535												standardcost,
1536												newqoh,
1537												narrative )
1538						VALUES ('" . $OrderLine->StockID . "',
1539								10,
1540								'" . $InvoiceNo . "',
1541								'" . $_SESSION['Items'.$identifier]->Location . "',
1542								'" . $DefaultDispatchDate . "',
1543								'" . $_SESSION['UserID'] . "',
1544								'" . $_SESSION['Items'.$identifier]->DebtorNo . "',
1545								'" . $_SESSION['Items'.$identifier]->Branch . "',
1546								'" . $LocalCurrencyPrice . "',
1547								'" . $PeriodNo . "',
1548								'" . $OrderNo . "',
1549								'" . -$OrderLine->Quantity . "',
1550								'" . $OrderLine->DiscountPercent . "',
1551								'" . $OrderLine->StandardCost . "',
1552								'" . ($QtyOnHandPrior - $OrderLine->Quantity) . "',
1553								'" . $OrderLine->Narrative . "' )";
1554			} else {
1555			// its an assembly or dummy and assemblies/dummies always have nil stock (by definition they are made up at the time of dispatch  so new qty on hand will be nil
1556				if (empty($OrderLine->StandardCost)) {
1557					$OrderLine->StandardCost = 0;
1558				}
1559				$SQL = "INSERT INTO stockmoves (stockid,
1560												type,
1561												transno,
1562												loccode,
1563												trandate,
1564												userid,
1565												debtorno,
1566												branchcode,
1567												price,
1568												prd,
1569												reference,
1570												qty,
1571												discountpercent,
1572												standardcost,
1573												narrative )
1574						VALUES ('" . $OrderLine->StockID . "',
1575										10,
1576										'" . $InvoiceNo . "',
1577										'" . $_SESSION['Items'.$identifier]->Location . "',
1578										'" . $DefaultDispatchDate . "',
1579										'" . $_SESSION['UserID'] . "',
1580										'" . $_SESSION['Items'.$identifier]->DebtorNo . "',
1581										'" . $_SESSION['Items'.$identifier]->Branch . "',
1582										'" . $LocalCurrencyPrice . "',
1583										'" . $PeriodNo . "',
1584										'" . $OrderNo . "',
1585										'" . -$OrderLine->Quantity . "',
1586										'" . $OrderLine->DiscountPercent . "',
1587										'" . $OrderLine->StandardCost . "',
1588										'" . $OrderLine->Narrative . "')";
1589			}
1590
1591			$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('Stock movement records could not be inserted because');
1592			$DbgMsg = _('The following SQL to insert the stock movement records was used');
1593			$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1594
1595		/*Get the ID of the StockMove... */
1596			$StkMoveNo = DB_Last_Insert_ID('stockmoves','stkmoveno');
1597
1598		/*Insert the taxes that applied to this line */
1599			foreach ($OrderLine->Taxes as $Tax) {
1600
1601				$SQL = "INSERT INTO stockmovestaxes (stkmoveno,
1602									taxauthid,
1603									taxrate,
1604									taxcalculationorder,
1605									taxontax)
1606						VALUES ('" . $StkMoveNo . "',
1607							'" . $Tax->TaxAuthID . "',
1608							'" . $Tax->TaxRate . "',
1609							'" . $Tax->TaxCalculationOrder . "',
1610							'" . $Tax->TaxOnTax . "')";
1611
1612				$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('Taxes and rates applicable to this invoice line item could not be inserted because');
1613				$DbgMsg = _('The following SQL to insert the stock movement tax detail records was used');
1614				$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1615			} //end for each tax for the line
1616
1617			/* Controlled stuff not currently handled by counter orders
1618
1619			Insert the StockSerialMovements and update the StockSerialItems  for controlled items
1620
1621			if ($OrderLine->Controlled ==1) {
1622				foreach($OrderLine->SerialItems as $Item) {
1623								//We need to add the StockSerialItem record and the StockSerialMoves as well
1624
1625					$SQL = "UPDATE stockserialitems
1626							SET quantity= quantity - " . $Item->BundleQty . "
1627							WHERE stockid='" . $OrderLine->StockID . "'
1628							AND loccode='" . $_SESSION['Items'.$identifier]->Location . "'
1629							AND serialno='" . $Item->BundleRef . "'";
1630
1631					$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The serial stock item record could not be updated because');
1632					$DbgMsg = _('The following SQL to update the serial stock item record was used');
1633					$Result = DB_query($SQL, $ErrMsg, $DbgMsg, true);
1634
1635					// now insert the serial stock movement
1636
1637					$SQL = "INSERT INTO stockserialmoves (stockmoveno,
1638										stockid,
1639										serialno,
1640										moveqty)
1641						VALUES (" . $StkMoveNo . ",
1642							'" . $OrderLine->StockID . "',
1643							'" . $Item->BundleRef . "',
1644							" . -$Item->BundleQty . ")";
1645
1646					$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The serial stock movement record could not be inserted because');
1647					$DbgMsg = _('The following SQL to insert the serial stock movement records was used');
1648					$Result = DB_query($SQL, $ErrMsg, $DbgMsg, true);
1649				}// foreach controlled item in the serialitems array
1650			} //end if the orderline is a controlled item
1651
1652			End of controlled stuff not currently handled by counter orders
1653			*/
1654			$SalesValue = 0;
1655			if ($ExRate>0) {
1656				$SalesValue = $OrderLine->Price * $OrderLine->Quantity / $ExRate;
1657			}
1658
1659		/*Insert Sales Analysis records */
1660
1661			$SQL="SELECT COUNT(*),
1662					salesanalysis.stockid,
1663					salesanalysis.stkcategory,
1664					salesanalysis.cust,
1665					salesanalysis.custbranch,
1666					salesanalysis.area,
1667					salesanalysis.periodno,
1668					salesanalysis.typeabbrev,
1669					salesanalysis.salesperson
1670				FROM salesanalysis,
1671					custbranch,
1672					stockmaster
1673				WHERE salesanalysis.stkcategory=stockmaster.categoryid
1674				AND salesanalysis.stockid=stockmaster.stockid
1675				AND salesanalysis.cust=custbranch.debtorno
1676				AND salesanalysis.custbranch=custbranch.branchcode
1677				AND salesanalysis.area=custbranch.area
1678				AND salesanalysis.salesperson='" . $_SESSION['Items'.$identifier]->SalesPerson . "'
1679				AND salesanalysis.typeabbrev ='" . $_SESSION['Items'.$identifier]->DefaultSalesType . "'
1680				AND salesanalysis.periodno='" . $PeriodNo . "'
1681				AND salesanalysis.cust " . LIKE . " '" . $_SESSION['Items'.$identifier]->DebtorNo . "'
1682				AND salesanalysis.custbranch " . LIKE . " '" . $_SESSION['Items'.$identifier]->Branch . "'
1683				AND salesanalysis.stockid " . LIKE . " '" . $OrderLine->StockID . "'
1684				AND salesanalysis.budgetoractual=1
1685				GROUP BY salesanalysis.stockid,
1686					salesanalysis.stkcategory,
1687					salesanalysis.cust,
1688					salesanalysis.custbranch,
1689					salesanalysis.area,
1690					salesanalysis.periodno,
1691					salesanalysis.typeabbrev,
1692					salesanalysis.salesperson";
1693
1694			$ErrMsg = _('The count of existing Sales analysis records could not run because');
1695			$DbgMsg = _('SQL to count the no of sales analysis records');
1696			$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1697
1698			$MyRow = DB_fetch_row($Result);
1699
1700			if ($MyRow[0]>0) {  /*Update the existing record that already exists */
1701
1702				$SQL = "UPDATE salesanalysis
1703							SET amt=amt+" . ($SalesValue) . ",
1704								cost=cost+" . ($OrderLine->StandardCost * $OrderLine->Quantity) . ",
1705								qty=qty +" . $OrderLine->Quantity . ",
1706								disc=disc+" . ($OrderLine->DiscountPercent * $SalesValue) . "
1707							WHERE salesanalysis.area='" . $MyRow[5] . "'
1708							AND salesanalysis.salesperson='" . $_SESSION['Items'.$identifier]->SalesPerson . "'
1709							AND typeabbrev ='" . $_SESSION['Items'.$identifier]->DefaultSalesType . "'
1710							AND periodno = '" . $PeriodNo . "'
1711							AND cust " . LIKE . " '" . $_SESSION['Items'.$identifier]->DebtorNo . "'
1712							AND custbranch " . LIKE . " '" . $_SESSION['Items'.$identifier]->Branch . "'
1713							AND stockid " . LIKE . " '" . $OrderLine->StockID . "'
1714							AND salesanalysis.stkcategory ='" . $MyRow[2] . "'
1715							AND budgetoractual=1";
1716
1717			} else { /* insert a new sales analysis record */
1718
1719				$SQL = "INSERT INTO salesanalysis (	typeabbrev,
1720													periodno,
1721													amt,
1722													cost,
1723													cust,
1724													custbranch,
1725													qty,
1726													disc,
1727													stockid,
1728													area,
1729													budgetoractual,
1730													salesperson,
1731													stkcategory	)
1732					SELECT '" . $_SESSION['Items'.$identifier]->DefaultSalesType . "',
1733						'" . $PeriodNo . "',
1734						'" . ($SalesValue) . "',
1735						'" . ($OrderLine->StandardCost * $OrderLine->Quantity) . "',
1736						'" . $_SESSION['Items'.$identifier]->DebtorNo . "',
1737						'" . $_SESSION['Items'.$identifier]->Branch . "',
1738						'" . $OrderLine->Quantity . "',
1739						'" . ($OrderLine->DiscountPercent * $SalesValue) . "',
1740						'" . $OrderLine->StockID . "',
1741						custbranch.area,
1742						1,
1743						'" . $_SESSION['Items'.$identifier]->SalesPerson . "',
1744						stockmaster.categoryid
1745					FROM stockmaster,
1746						custbranch
1747					WHERE stockmaster.stockid = '" . $OrderLine->StockID . "'
1748					AND custbranch.debtorno = '" . $_SESSION['Items'.$identifier]->DebtorNo . "'
1749					AND custbranch.branchcode='" . $_SESSION['Items'.$identifier]->Branch . "'";
1750			}
1751
1752			$ErrMsg = _('Sales analysis record could not be added or updated because');
1753			$DbgMsg = _('The following SQL to insert the sales analysis record was used');
1754			$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1755
1756		/* If GLLink_Stock then insert GLTrans to credit stock and debit cost of sales at standard cost*/
1757
1758			if ($_SESSION['CompanyRecord']['gllink_stock']==1 AND $OrderLine->StandardCost !=0) {
1759
1760		/*first the cost of sales entry*/
1761
1762				$SQL = "INSERT INTO gltrans (	type,
1763												typeno,
1764												trandate,
1765												periodno,
1766												account,
1767												narrative,
1768												amount)
1769										VALUES ( 10,
1770												'" . $InvoiceNo . "',
1771												'" . $DefaultDispatchDate . "',
1772												'" . $PeriodNo . "',
1773												'" . GetCOGSGLAccount($Area, $OrderLine->StockID, $_SESSION['Items'.$identifier]->DefaultSalesType) . "',
1774												'" . $_SESSION['Items'.$identifier]->DebtorNo . " - " . $OrderLine->StockID . " x " . $OrderLine->Quantity . " @ " . $OrderLine->StandardCost . "',
1775												'" . $OrderLine->StandardCost * $OrderLine->Quantity . "')";
1776
1777				$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The cost of sales GL posting could not be inserted because');
1778				$DbgMsg = _('The following SQL to insert the GLTrans record was used');
1779				$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1780
1781		/*now the stock entry*/
1782				$StockGLCode = GetStockGLCode($OrderLine->StockID);
1783
1784				$SQL = "INSERT INTO gltrans (type,
1785											typeno,
1786											trandate,
1787											periodno,
1788											account,
1789											narrative,
1790											amount )
1791										VALUES ( 10,
1792											'" . $InvoiceNo . "',
1793											'" . $DefaultDispatchDate . "',
1794											'" . $PeriodNo . "',
1795											'" . $StockGLCode['stockact'] . "',
1796											'" . $_SESSION['Items'.$identifier]->DebtorNo . " - " . $OrderLine->StockID . " x " . $OrderLine->Quantity . " @ " . $OrderLine->StandardCost . "',
1797											'" . (-$OrderLine->StandardCost * $OrderLine->Quantity) . "')";
1798
1799				$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The stock side of the cost of sales GL posting could not be inserted because');
1800				$DbgMsg = _('The following SQL to insert the GLTrans record was used');
1801				$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1802			} /* end of if GL and stock integrated and standard cost !=0 */
1803
1804			if ($_SESSION['CompanyRecord']['gllink_debtors']==1 AND $OrderLine->Price !=0) {
1805
1806		//Post sales transaction to GL credit sales
1807				$SalesGLAccounts = GetSalesGLAccount($Area, $OrderLine->StockID, $_SESSION['Items'.$identifier]->DefaultSalesType);
1808
1809				$SQL = "INSERT INTO gltrans (type,
1810											typeno,
1811											trandate,
1812											periodno,
1813											account,
1814											narrative,
1815											amount )
1816										VALUES ( 10,
1817											'" . $InvoiceNo . "',
1818											'" . $DefaultDispatchDate . "',
1819											'" . $PeriodNo . "',
1820											'" . $SalesGLAccounts['salesglcode'] . "',
1821											'" . $_SESSION['Items'.$identifier]->DebtorNo . " - " . $OrderLine->StockID . " x " . $OrderLine->Quantity . " @ " . $OrderLine->Price . "',
1822											'" . (-$OrderLine->Price * $OrderLine->Quantity/$ExRate) . "')";
1823
1824				$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The sales GL posting could not be inserted because');
1825				$DbgMsg = '<br />' ._('The following SQL to insert the GLTrans record was used');
1826				$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1827
1828				if ($OrderLine->DiscountPercent !=0) {
1829
1830					$SQL = "INSERT INTO gltrans (type,
1831												typeno,
1832												trandate,
1833												periodno,
1834												account,
1835												narrative,
1836												amount )
1837												VALUES ( 10,
1838													'" . $InvoiceNo . "',
1839													'" . $DefaultDispatchDate . "',
1840													'" . $PeriodNo . "',
1841													'" . $SalesGLAccounts['discountglcode'] . "',
1842													'" . $_SESSION['Items'.$identifier]->DebtorNo . " - " . $OrderLine->StockID . " @ " . ($OrderLine->DiscountPercent * 100) . "%',
1843													'" . ($OrderLine->Price * $OrderLine->Quantity * $OrderLine->DiscountPercent/$ExRate) . "')";
1844
1845					$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The sales discount GL posting could not be inserted because');
1846					$DbgMsg = _('The following SQL to insert the GLTrans record was used');
1847					$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1848				} /*end of if discount !=0 */
1849			} /*end of if sales integrated with debtors */
1850		} /*end of OrderLine loop */
1851
1852		if ($_SESSION['CompanyRecord']['gllink_debtors']==1) {
1853
1854	/*Post debtors transaction to GL debit debtors, credit freight re-charged and credit sales */
1855			if (($_SESSION['Items'.$identifier]->total + filter_number_format($_POST['TaxTotal'])) !=0) {
1856				$SQL = "INSERT INTO gltrans (	type,
1857												typeno,
1858												trandate,
1859												periodno,
1860												account,
1861												narrative,
1862												amount	)
1863											VALUES ( 10,
1864												'" . $InvoiceNo . "',
1865												'" . $DefaultDispatchDate . "',
1866												'" . $PeriodNo . "',
1867												'" . $_SESSION['CompanyRecord']['debtorsact'] . "',
1868												'" . $_SESSION['Items'.$identifier]->DebtorNo . "',
1869												'" . (($_SESSION['Items'.$identifier]->total + filter_number_format($_POST['TaxTotal']))/$ExRate) . "')";
1870
1871				$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The total debtor GL posting could not be inserted because');
1872				$DbgMsg = _('The following SQL to insert the total debtors control GLTrans record was used');
1873				$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1874			}
1875
1876
1877			foreach ( $_SESSION['Items'.$identifier]->TaxTotals as $TaxAuthID => $TaxAmount) {
1878				if ($TaxAmount !=0 ) {
1879					$SQL = "INSERT INTO gltrans (	type,
1880													typeno,
1881													trandate,
1882													periodno,
1883													account,
1884													narrative,
1885													amount	)
1886												VALUES ( 10,
1887													'" . $InvoiceNo . "',
1888													'" . $DefaultDispatchDate . "',
1889													'" . $PeriodNo . "',
1890													'" . $_SESSION['Items'.$identifier]->TaxGLCodes[$TaxAuthID] . "',
1891													'" . $_SESSION['Items'.$identifier]->DebtorNo . "',
1892													'" . (-$TaxAmount/$ExRate) . "')";
1893
1894					$ErrMsg = _('CRITICAL ERROR') . '! ' . _('NOTE DOWN THIS ERROR AND SEEK ASSISTANCE') . ': ' . _('The tax GL posting could not be inserted because');
1895					$DbgMsg = _('The following SQL to insert the GLTrans record was used');
1896					$Result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1897				}
1898			}
1899
1900			EnsureGLEntriesBalance(10,$InvoiceNo);
1901
1902			/*Also if GL is linked to debtors need to process the debit to bank and credit to debtors for the payment */
1903			/*Need to figure out the cross rate between customer currency and bank account currency */
1904
1905			if ($_POST['AmountPaid']!=0) {
1906				$ReceiptNumber = GetNextTransNo(12);
1907				$SQL="INSERT INTO gltrans (type,
1908											typeno,
1909											trandate,
1910											periodno,
1911											account,
1912											narrative,
1913											amount)
1914						VALUES (12,
1915							'" . $ReceiptNumber . "',
1916							'" . $DefaultDispatchDate . "',
1917							'" . $PeriodNo . "',
1918							'" . $_POST['BankAccount'] . "',
1919							'" . $_SESSION['Items'.$identifier]->LocationName . ' ' . _('Counter Sale') . ' ' . $InvoiceNo . "',
1920							'" . (filter_number_format($_POST['AmountPaid'])/$ExRate) . "')";
1921				$DbgMsg = _('The SQL that failed to insert the GL transaction for the bank account debit was');
1922				$ErrMsg = _('Cannot insert a GL transaction for the bank account debit');
1923				$result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1924
1925				/* Now Credit Debtors account with receipt */
1926				$SQL="INSERT INTO gltrans ( type,
1927						typeno,
1928						trandate,
1929						periodno,
1930						account,
1931						narrative,
1932						amount)
1933				VALUES (12,
1934					'" . $ReceiptNumber . "',
1935					'" . $DefaultDispatchDate . "',
1936					'" . $PeriodNo . "',
1937					'" . $_SESSION['CompanyRecord']['debtorsact'] . "',
1938					'" . $_SESSION['Items'.$identifier]->LocationName . ' ' . _('Counter Sale') . ' ' . $InvoiceNo . "',
1939					'" . -(filter_number_format($_POST['AmountPaid'])/$ExRate) . "')";
1940				$DbgMsg = _('The SQL that failed to insert the GL transaction for the debtors account credit was');
1941				$ErrMsg = _('Cannot insert a GL transaction for the debtors account credit');
1942				$result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1943			}//amount paid we not zero
1944
1945			EnsureGLEntriesBalance(12,$ReceiptNumber);
1946
1947		} /*end of if Sales and GL integrated */
1948		if ($_POST['AmountPaid']!=0) {
1949			if (!isset($ReceiptNumber)) {
1950				$ReceiptNumber = GetNextTransNo(12);
1951			}
1952			//Now need to add the receipt banktrans record
1953			//First get the account currency that it has been banked into
1954			$result = DB_query("SELECT rate FROM currencies
1955								INNER JOIN bankaccounts
1956								ON currencies.currabrev=bankaccounts.currcode
1957								WHERE bankaccounts.accountcode='" . $_POST['BankAccount'] . "'");
1958			$MyRow = DB_fetch_row($result);
1959			$BankAccountExRate = $MyRow[0];
1960
1961			/*
1962			 * Some interesting exchange rate conversion going on here
1963			 * Say :
1964			 * The business's functional currency is NZD
1965			 * Customer location counter sales are in AUD - 1 NZD = 0.80 AUD
1966			 * Banking money into a USD account - 1 NZD = 0.68 USD
1967			 *
1968			 * Customer sale is for $100 AUD
1969			 * GL entries  conver the AUD 100 to NZD  - 100 AUD / 0.80 = $125 NZD
1970			 * Banktrans entries convert the AUD 100 to USD using 100/0.8 * 0.68
1971			*/
1972
1973			//insert the banktrans record in the currency of the bank account
1974
1975			$SQL="INSERT INTO banktrans (type,
1976						transno,
1977						bankact,
1978						ref,
1979						exrate,
1980						functionalexrate,
1981						transdate,
1982						banktranstype,
1983						amount,
1984						currcode)
1985					VALUES (12,
1986						'" . $ReceiptNumber . "',
1987						'" . $_POST['BankAccount'] . "',
1988						'" . mb_substr($_SESSION['Items'.$identifier]->LocationName . ' ' . _('Counter Sale') . ' ' . $InvoiceNo, 0, 50) . "',
1989						'" . $ExRate . "',
1990						'" . $BankAccountExRate . "',
1991						'" . $DefaultDispatchDate . "',
1992						'" . $_POST['PaymentMethod'] . "',
1993						'" . filter_number_format($_POST['AmountPaid']) * $BankAccountExRate/$ExRate . "',
1994						'" . $_SESSION['Items'.$identifier]->DefaultCurrency . "')";
1995
1996			$DbgMsg = _('The SQL that failed to insert the bank account transaction was');
1997			$ErrMsg = _('Cannot insert a bank transaction');
1998			$result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
1999
2000			//insert a new debtortrans for the receipt
2001
2002			$SQL = "INSERT INTO debtortrans (transno,
2003							type,
2004							debtorno,
2005							trandate,
2006							inputdate,
2007							prd,
2008							reference,
2009							rate,
2010							ovamount,
2011							alloc,
2012							invtext,
2013							settled,
2014							salesperson)
2015					VALUES ('" . $ReceiptNumber . "',
2016						12,
2017						'" . $_SESSION['Items'.$identifier]->DebtorNo . "',
2018						'" . $DefaultDispatchDate . "',
2019						'" . date('Y-m-d H-i-s') . "',
2020						'" . $PeriodNo . "',
2021						'" . $InvoiceNo . "',
2022						'" . $ExRate . "',
2023						'" . -filter_number_format($_POST['AmountPaid']) . "',
2024						'" . -filter_number_format($_POST['AmountPaid']) . "',
2025						'" . $_SESSION['Items'.$identifier]->LocationName . ' ' . _('Counter Sale') ."',
2026						'1',
2027						'" . $_SESSION['Items'.$identifier]->SalesPerson . "')";
2028
2029			$DbgMsg = _('The SQL that failed to insert the customer receipt transaction was');
2030			$ErrMsg = _('Cannot insert a receipt transaction against the customer because') ;
2031			$result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
2032
2033			$ReceiptDebtorTransID = DB_Last_Insert_ID('debtortrans','id');
2034
2035			$SQL = "UPDATE debtorsmaster SET lastpaiddate = '" . $DefaultDispatchDate . "',
2036											lastpaid='" . filter_number_format($_POST['AmountPaid']) . "'
2037									WHERE debtorsmaster.debtorno='" . $_SESSION['Items'.$identifier]->DebtorNo . "'";
2038
2039			$DbgMsg = _('The SQL that failed to update the date of the last payment received was');
2040			$ErrMsg = _('Cannot update the customer record for the date of the last payment received because');
2041			$result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
2042
2043			//and finally add the allocation record between receipt and invoice
2044
2045			$SQL = "INSERT INTO custallocns (	amt,
2046												datealloc,
2047												transid_allocfrom,
2048												transid_allocto )
2049									VALUES  ('" . filter_number_format($_POST['AmountPaid']) . "',
2050											'" . $DefaultDispatchDate . "',
2051											 '" . $ReceiptDebtorTransID . "',
2052											 '" . $DebtorTransID . "')";
2053			$DbgMsg = _('The SQL that failed to insert the allocation of the receipt to the invoice was');
2054			$ErrMsg = _('Cannot insert the customer allocation of the receipt to the invoice because');
2055			$result = DB_query($SQL,$ErrMsg,$DbgMsg,true);
2056		} //end if $_POST['AmountPaid']!= 0
2057
2058		DB_Txn_Commit();
2059	// *************************************************************************
2060	//   E N D   O F   I N V O I C E   S Q L   P R O C E S S I N G
2061	// *************************************************************************
2062
2063		unset($_SESSION['Items'.$identifier]->LineItems);
2064		unset($_SESSION['Items'.$identifier]);
2065
2066		echo prnMsg( _('Invoice number'). ' '. $InvoiceNo .' '. _('processed'), 'success');
2067
2068		echo '<br /><div class="centre">';
2069
2070		if ($_SESSION['InvoicePortraitFormat']==0) {
2071			echo '<meta http-equiv="Refresh" content="0; url=' . $RootPath.'/PrintCustTrans.php?FromTransNo='.$InvoiceNo.'&amp;InvOrCredit=Invoice&amp;PrintPDF=True" />';
2072
2073			//echo '<img src="'.$RootPath.'/css/'.$Theme.'/images/printer.png" title="' . _('Print') . '" alt="" />' . ' ' . '<a target="_blank" href="'.$RootPath.'/PrintCustTrans.php?FromTransNo='.$InvoiceNo.'&amp;InvOrCredit=Invoice&amp;PrintPDF=True">' .  _('Print this invoice'). ' (' . _('Landscape') . ')</a><br /><br />';
2074		} else {
2075			//echo '<img src="'.$RootPath.'/css/'.$Theme.'/images/printer.png" title="' . _('Print') . '" alt="" />' . ' ' . '<a target="_blank" href="'.$RootPath.'/PrintCustTransPortrait.php?FromTransNo='.$InvoiceNo.'&amp;InvOrCredit=Invoice&amp;PrintPDF=True">' .  _('Print this invoice'). ' (' . _('Portrait') . ')</a><br /><br />';
2076			echo '<meta http-equiv="Refresh" content="0; url=' . $RootPath.'/PrintCustTransPortrait.php?FromTransNo='.$InvoiceNo.'&amp;InvOrCredit=Invoice&amp;PrintPDF=True" />';
2077		}
2078
2079		echo '<br /><br /><a href="' .htmlspecialchars($_SERVER['PHP_SELF'],ENT_QUOTES,'UTF-8') . '">' . _('Start a new Counter Sale') . '</a></div>';
2080
2081	}
2082	// There were input errors so don't process nuffin
2083} else {
2084	//pretend the user never tried to commit the sale
2085	unset($_POST['ProcessSale']);
2086}
2087/*******************************
2088 * end of Invoice Processing
2089 * *****************************
2090*/
2091
2092/* Now show the stock item selection search stuff below */
2093if (!isset($_POST['ProcessSale'])) {
2094	 if (isset($_POST['PartSearch']) and $_POST['PartSearch']!='') {
2095
2096		echo '<input type="hidden" name="PartSearch" value="' .  _('Yes Please') . '" />';
2097
2098		if ($_SESSION['FrequentlyOrderedItems']>0) { //show the Frequently Order Items selection where configured to do so
2099
2100	// Select the most recently ordered items for quick select
2101			$SixMonthsAgo = DateAdd (Date($_SESSION['DefaultDateFormat']),'m',-6);
2102
2103			$SQL="SELECT stockmaster.units,
2104						stockmaster.description,
2105						stockmaster.stockid,
2106						salesorderdetails.stkcode,
2107						SUM(qtyinvoiced) Sales
2108				  FROM salesorderdetails INNER JOIN stockmaster
2109				  ON salesorderdetails.stkcode = stockmaster.stockid
2110				  WHERE ActualDispatchDate >= '" . FormatDateForSQL($SixMonthsAgo) . "'
2111				  AND stockmaster.controlled=0
2112				  GROUP BY stkcode
2113				  ORDER BY sales DESC
2114				  LIMIT " . $_SESSION['FrequentlyOrderedItems'];
2115			$result2 = DB_query($SQL);
2116			echo '<p class="page_title_text"><img src="'.$RootPath.'/css/'.$Theme.'/images/magnifier.png" title="' . _('Search') . '" alt="" />' . ' ';
2117			echo _('Frequently Ordered Items') . '</p><br />';
2118			echo '<div class="page_help_text">' . _('Frequently Ordered Items') . _(', shows the most frequently ordered items in the last 6 months.  You can choose from this list, or search further for other items') . '.</div><br />';
2119			echo '<table class="table1">';
2120			$TableHeader = '<tr><th>' . _('Code') . '</th>
2121								<th>' . _('Description') . '</th>
2122								<th>' . _('Units') . '</th>
2123								<th>' . _('On Hand') . '</th>
2124								<th>' . _('On Demand') . '</th>
2125								<th>' . _('On Order') . '</th>
2126								<th>' . _('Available') . '</th>
2127								<th>' . _('Quantity') . '</th></tr>';
2128			echo $TableHeader;
2129			$i = 0;
2130			$j = 1;
2131
2132			while ($MyRow=DB_fetch_array($result2)) {
2133	// This code needs sorting out, but until then :
2134				$ImageSource = _('No Image');
2135	// Find the quantity in stock at location
2136				$QohSql = "SELECT sum(quantity)
2137						   FROM locstock
2138						   WHERE stockid='" .$MyRow['stockid'] . "' AND
2139						   loccode = '" . $_SESSION['Items'.$identifier]->Location . "'";
2140				$QohResult =  DB_query($QohSql);
2141				$QohRow = DB_fetch_row($QohResult);
2142				$QOH = $QohRow[0];
2143
2144				// Find the quantity on outstanding sales orders
2145				$SQL = "SELECT SUM(salesorderdetails.quantity-salesorderdetails.qtyinvoiced) AS dem
2146						FROM salesorderdetails INNER JOIN salesorders
2147						ON salesorders.orderno = salesorderdetails.orderno
2148						WHERE  salesorders.fromstkloc='" . $_SESSION['Items'.$identifier]->Location . "'
2149						AND salesorderdetails.completed=0
2150						AND salesorders.quotation=0
2151						AND salesorderdetails.stkcode='" . $MyRow['stockid'] . "'";
2152
2153				$ErrMsg = _('The demand for this product from') . ' ' . $_SESSION['Items'.$identifier]->Location . ' ' .
2154					 _('cannot be retrieved because');
2155				$DemandResult = DB_query($SQL,$ErrMsg);
2156
2157				$DemandRow = DB_fetch_row($DemandResult);
2158				if ($DemandRow[0] != null) {
2159				  $DemandQty =  $DemandRow[0];
2160				} else {
2161				  $DemandQty = 0;
2162				}
2163
2164				// Get the QOO due to Purchase orders for all locations. Function defined in SQL_CommonFunctions.inc
2165				$QOO = GetQuantityOnOrderDueToPurchaseOrders($MyRow['stockid'], '');
2166				// Get the QOO due to Work Orders for all locations. Function defined in SQL_CommonFunctions.inc
2167				$QOO += GetQuantityOnOrderDueToWorkOrders($MyRow['stockid'], '');
2168
2169				$Available = $QOH - $DemandQty + $QOO;
2170
2171				printf('<tr class="striped_row">
2172						<td>%s</td>
2173						<td>%s</td>
2174						<td>%s</td>
2175						<td class="number">%s</td>
2176						<td class="number">%s</td>
2177						<td class="number">%s</td>
2178						<td class="number">%s</td>
2179						<td><input class="number" tabindex="'.strval($j+7).'" type="text" ' . ($i==0?'autofocus="autofocus"':'') . ' size="6" required="required" name="OrderQty%s" value="0" />
2180							<input type="hidden" name="StockID%s" value="%s" />
2181						</td>
2182						</tr>',
2183						$MyRow['stockid'],
2184						$MyRow['description'],
2185						$MyRow['units'],
2186						$QOH,
2187						$DemandQty,
2188						$QOO,
2189						$Available,
2190						$i,
2191						$i,
2192						$MyRow['stockid']);
2193				$j++;//counter for paging
2194				$i++;//index for controls
2195	#end of page full new headings if
2196			}
2197	#end of while loop for Frequently Ordered Items
2198			echo '<td class="centre" colspan="8"><input type="hidden" name="SelectingOrderItems" value="1" /><input tabindex="'.strval($j+8).'" type="submit" value="'._('Add to Sale').'" /></td>';
2199			echo '</table>';
2200		} //end of if Frequently Ordered Items > 0
2201		if (isset($msg)) {
2202			echo '<div class="page_help_text"><p><b>' . $msg . '</b></p></div>';
2203		}
2204		echo '<p class="page_title_text"><img src="'.$RootPath.'/css/'.$Theme.'/images/magnifier.png" title="' . _('Search') . '" alt="" />' . ' ' . _('Search for Items') . '</p>
2205			<div class="page_help_text">' . _('Search for Items') . _(', Searches the database for items, you can narrow the results by selecting a stock category, or just enter a partial item description or partial item code') . '.</div>
2206			<br />
2207			<table class="selection">
2208				<tr>
2209					<td><b>' . _('Select a Stock Category') . ': </b><select tabindex="1" name="StockCat">';
2210
2211		if (!isset($_POST['StockCat']) OR $_POST['StockCat']=='All') {
2212			echo '<option selected="selected" value="All">' . _('All') . '</option>';
2213			$_POST['StockCat'] ='All';
2214		} else {
2215			echo '<option value="All">' . _('All') . '</option>';
2216		}
2217		$SQL="SELECT categoryid,
2218					categorydescription
2219				FROM stockcategory
2220				WHERE stocktype='F' OR stocktype='D'
2221				ORDER BY categorydescription";
2222		$result1 = DB_query($SQL);
2223		while ($MyRow1 = DB_fetch_array($result1)) {
2224			if ($_POST['StockCat']==$MyRow1['categoryid']) {
2225				echo '<option selected="selected" value="' . $MyRow1['categoryid'] . '">' . $MyRow1['categorydescription'] . '</option>';
2226			} else {
2227				echo '<option value="'. $MyRow1['categoryid'] . '">' . $MyRow1['categorydescription'] . '</option>';
2228			}
2229		}
2230
2231		echo '</select></td>
2232				<td><b>' . _('Enter partial Description') . ':</b>
2233				<input tabindex="2" type="text" autofocus="autofocus" name="Keywords" size="20" maxlength="25" value="';
2234        if (isset($_POST['Keywords'])) echo $_POST['Keywords'];
2235        echo '" /></td>
2236				<td align="right"><b> ' . _('OR') . ' </b><b>' . _('Enter extract of the Stock Code') . ':</b>
2237				<input tabindex="3" type="text" name="StockCode" size="15" maxlength="18" value="';
2238        if (isset($_POST['StockCode'])) echo $_POST['StockCode'];
2239        echo '" /></td>
2240			</tr>
2241			<tr>
2242				<td class="centre" colspan="1"><input tabindex="4" type="submit" name="Search" value="' . _('Search Now') . '" /></td>
2243				<td class="centre" colspan="1"><input tabindex="5" type="submit" name="QuickEntry" value="' . _('Use Quick Entry') . '" /></td>
2244			</tr>
2245		</table>
2246		<br />
2247		</div>';
2248	// Add some useful help as the order progresses
2249		if (isset($SearchResult)) {
2250			echo '<br />
2251					<div class="page_help_text">' . _('Select an item by entering the quantity required.  Click Order when ready.') . '</div>
2252				<br />';
2253		}
2254
2255
2256		if (isset($SearchResult)) {
2257			$j = 1;
2258			echo '<div>';
2259			echo '<table class="table1">';
2260			echo '<tr>
2261					<td><input type="hidden" name="PreviousList" value="'.strval($Offset-1).'" /><input tabindex="'.strval($j+7).'" type="submit" name="Previous" value="'._('Prev').'" /></td>
2262					<td class="centre" colspan="6"><input type="hidden" name="SelectingOrderItems" value="1" /><input tabindex="'.strval($j+8).'" type="submit" value="'._('Add to Sale').'" /></td>
2263					<td><input type="hidden" name="NextList" value="'.strval($Offset+1).'" /><input tabindex="'.strval($j+9).'" type="submit" name="Next" value="'._('Next').'" /></td>
2264				</tr>
2265				<tr>
2266					<th>' . _('Code') . '</th>
2267		   			<th>' . _('Description') . '</th>
2268		   			<th>' . _('Units') . '</th>
2269		   			<th>' . _('On Hand') . '</th>
2270		   			<th>' . _('On Demand') . '</th>
2271		   			<th>' . _('On Order') . '</th>
2272		   			<th>' . _('Available') . '</th>
2273		   			<th>' . _('Quantity') . '</th>
2274		   		</tr>';
2275			$i=0;
2276
2277			while ($MyRow=DB_fetch_array($SearchResult)) {
2278
2279				// Find the quantity in stock at location
2280				$QOHSql = "SELECT sum(quantity) AS qoh
2281 					   FROM locstock
2282					   WHERE locstock.stockid='" .$MyRow['stockid'] . "'
2283					   AND loccode = '" . $_SESSION['Items'.$identifier]->Location . "'";
2284				$QOHResult =  DB_query($QOHSql);
2285				$QOHRow = DB_fetch_array($QOHResult);
2286				$QOH = $QOHRow['qoh'];
2287
2288				// Find the quantity on outstanding sales orders
2289				$SQL = "SELECT SUM(salesorderdetails.quantity-salesorderdetails.qtyinvoiced) AS dem
2290						 FROM salesorderdetails INNER JOIN salesorders
2291						 ON salesorders.orderno = salesorderdetails.orderno
2292						 WHERE salesorders.fromstkloc='" . $_SESSION['Items'.$identifier]->Location . "'
2293						 AND salesorderdetails.completed=0
2294						 AND salesorders.quotation=0
2295						 AND salesorderdetails.stkcode='" . $MyRow['stockid'] . "'";
2296
2297				$ErrMsg = _('The demand for this product from') . ' ' . $_SESSION['Items'.$identifier]->Location . ' ' . _('cannot be retrieved because');
2298				$DemandResult = DB_query($SQL,$ErrMsg);
2299
2300				$DemandRow = DB_fetch_row($DemandResult);
2301				if ($DemandRow[0] != null) {
2302				  $DemandQty =  $DemandRow[0];
2303				} else {
2304				  $DemandQty = 0;
2305				}
2306
2307				// Get the QOO due to Purchase orders for all locations. Function defined in SQL_CommonFunctions.inc
2308				$QOO = GetQuantityOnOrderDueToPurchaseOrders($MyRow['stockid'], '');
2309				// Get the QOO dues to Work Orders for all locations. Function defined in SQL_CommonFunctions.inc
2310				$QOO += GetQuantityOnOrderDueToWorkOrders($MyRow['stockid'], '');
2311
2312				$Available = $QOH - $DemandQty + $QOO;
2313
2314				printf('<tr class="striped_row">
2315						<td>%s</td>
2316						<td>%s</td>
2317						<td>%s</td>
2318						<td class="number">%s</td>
2319						<td class="number">%s</td>
2320						<td class="number">%s</td>
2321						<td class="number">%s</td>
2322						<td><input class="number"  tabindex="'.strval($j+7).'" type="text" size="6" required="required" ' . ($i==0?'autofocus="autofocus"':'') . ' name="OrderQty%s" value="0" /><input type="hidden" name="StockID%s" value="%s" /></td>
2323						</tr>',
2324						$MyRow['stockid'],
2325						$MyRow['description'],
2326						$MyRow['units'],
2327						locale_number_format($QOH, $MyRow['decimalplaces']),
2328						locale_number_format($DemandQty, $MyRow['decimalplaces']),
2329						locale_number_format($QOO, $MyRow['decimalplaces']),
2330						locale_number_format($Available, $MyRow['decimalplaces']),
2331						$i,
2332						$i,
2333						$MyRow['stockid']);
2334				$i++;
2335			}
2336	#end of while loop
2337            echo '<tr>
2338					<td>
2339						<input type="hidden" name="CustRef" value="'.$_SESSION['Items'.$identifier]->CustRef.'" />
2340						<input type="hidden" name="Comments" value="'.$_SESSION['Items'.$identifier]->Comments.'" />
2341						<input type="hidden" name="DeliverTo" value="'.$_SESSION['Items'.$identifier]->DeliverTo.'" />
2342						<input type="hidden" name="PhoneNo" value="'.$_SESSION['Items'.$identifier]->PhoneNo.'" />
2343						<input type="hidden" name="Email" value="'.$_SESSION['Items'.$identifier]->Email.'" />
2344					</td>
2345				</tr>
2346				<tr>
2347					<td><input type="hidden" name="previous" value="' . strval($Offset-1) . '" /><input tabindex="' . strval($j+7) . '" type="submit" name="Prev" value="' . _('Prev') . '" /></td>
2348					<td class="centre" colspan="6"><input type="hidden" name="SelectingOrderItems" value="1" /><input tabindex="'.strval($j+8).'" type="submit" value="'._('Add to Sale').'" /></td>
2349					<td><input type="hidden" name="NextList" value="'.strval($Offset+1).'" /><input tabindex="'.strval($j+9).'" type="submit" name="Next" value="'._('Next').'" /></td>
2350				</tr>
2351				</table>
2352				</div>';
2353		}#end if SearchResults to show
2354	} /*end of PartSearch options to be displayed */
2355		else { /* show the quick entry form variable */
2356
2357		echo '<div class="page_help_text"><b>' . _('Use this form to add items quickly if the item codes are already known') . '</b></div><br />';
2358        if (count($_SESSION['Items'.$identifier]->LineItems)==0) {
2359            echo '<input type="hidden" name="CustRef" value="' . $_SESSION['Items'.$identifier]->CustRef . '" />';
2360            echo '<input type="hidden" name="Comments" value="' . $_SESSION['Items'.$identifier]->Comments . '" />';
2361            echo '<input type="hidden" name="DeliverTo" value="' . $_SESSION['Items'.$identifier]->DeliverTo . '" />';
2362            echo '<input type="hidden" name="PhoneNo" value="' . $_SESSION['Items'.$identifier]->PhoneNo . '" />';
2363            echo '<input type="hidden" name="Email" value="' . $_SESSION['Items'.$identifier]->Email . '" />';
2364		}
2365
2366		$SQL = "SELECT stockid
2367				FROM stockmaster
2368				WHERE controlled = 0";
2369		$ErrMsg = _('Could not fetch items list because');
2370		$DbgMsg = _('The sql that was used to fetch items list was ');
2371		$ItemsResult = DB_query($SQL, $ErrMsg, $DbgMsg);
2372		$ItemCount = DB_num_rows($ItemsResult);
2373
2374		if ($ItemCount==0)
2375		{
2376			prnMsg( _('There are no available item(s) retrieved from the database'),'warn');
2377		}
2378		else if(!isset($_SESSION['ItemList']) || $ItemCount != count($_SESSION['ItemList']))
2379		{
2380			unset($_SESSION['ItemList']);
2381
2382			$_SESSION['ItemList'] = array();
2383			while($myrow=DB_fetch_array($ItemsResult))
2384			{
2385				$_SESSION['ItemList'][] = $myrow['stockid'];
2386			}
2387		}
2388
2389		echo '<input type="text" autofocus="autofocus" onkeydown="if (event.keyCode == 13 || event.which == 13) AddQuickEntry(this);" onchange="AddQuickEntry(this);" placeholder="Item Code";  /><br><br>';
2390
2391		echo '<table id="QuickEntryTable" border="1">
2392				<tr>
2393					<th>' . _('Item Code') . '</th>
2394					<th>' . _('Quantity') . '</th>
2395				</tr>';
2396		$DefaultDeliveryDate = DateAdd(Date($_SESSION['DefaultDateFormat']),'d',$_SESSION['Items'.$identifier]->DeliveryDays);
2397		for ($i=1;$i<=$_SESSION['QuickEntries'];$i++) {
2398
2399	 		echo '<tr class="striped_row">';
2400	 		/* Do not display colum unless customer requires po line number by sales order line*/
2401	 		echo '<td><input type="text" name="part_' . $i . '"' . ($i==1 ? ' autofocus="autofocus"':'') . ' data-type="no-illegal-chars" title="' . _('Enter a part code to be sold. Part codes can contain any alpha-numeric characters underscore or hyphen.') . '"size="21" maxlength="20" /></td>
2402					<td><input type="text" class="number" name="qty_' . $i . '" size="6" maxlength="6" />
2403						<input type="hidden" class="date" name="ItemDue_' . $i . '" value="' . $DefaultDeliveryDate . '" /></td></tr>';
2404   		}
2405	 	echo '</table>
2406				<br />
2407				<div class="centre">
2408					<input type="hidden" id="TotalQuickEntryRows" name="TotalQuickEntryRows" value="' .$_SESSION['QuickEntries'] . '" />
2409					<input type="submit" name="QuickEntry" value="' . _('Quick Entry') . '" />
2410					<input type="submit" name="PartSearch" value="' . _('Search Parts') . '" />
2411				</div>
2412			</div>';
2413
2414  	}
2415	if ($_SESSION['Items'.$identifier]->ItemsOrdered >=1) {
2416  		echo '<br /><div class="centre"><input type="submit" name="CancelOrder" value="' . _('Cancel Sale') . '" onclick="return confirm(\'' . _('Are you sure you wish to cancel this sale?') . '\');" /></div>';
2417	}
2418	echo '</form>';
2419}
2420echo '<script src="', $RootPath, 'javscripts/CounterSalesFunctions.js"></script>';
2421?>
2422<script defer="defer">
2423	CounterSales.SetItemList(<?php echo json_encode($_SESSION['ItemList']); ?>);
2424	CounterSales.SetQuickEntryTableId('QuickEntryTable');
2425	CounterSales.SetRowCounter(<?php echo empty($i) ? 0 : $i; ?>);
2426	CounterSales.SetDefaultDeliveryDate(<?php echo empty($DefaultDeliveryDate) ? '""' : $DefaultDeliveryDate; ?>);
2427	CounterSales.SetTotalQuickEntryRowsId('TotalQuickEntryRows');
2428
2429	CounterSales.SetTotalDue(<?php echo round($_SESSION['Items'.$identifier]->total + filter_number_format($_POST['TaxTotal']) + filter_number_format($RoundingAdjustment), $_SESSION['Items'.$identifier]->CurrDecimalPlaces) ?>);
2430	CounterSales.SetDecimal(<?php echo $_SESSION['Items'.$identifier]->CurrDecimalPlaces; ?>);
2431	CounterSales.SetCashReceivedId('CashReceived');
2432	CounterSales.SetAmountPaidId('AmountPaid');
2433	CounterSales.SetChangeDueId('ChangeDue');
2434</script>
2435<?php
2436include('includes/footer.php');
2437?>
2438