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 . '&StockID=' . $OrderLine->StockID . '&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 . '&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.'&InvOrCredit=Invoice&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.'&InvOrCredit=Invoice&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.'&InvOrCredit=Invoice&PrintPDF=True">' . _('Print this invoice'). ' (' . _('Portrait') . ')</a><br /><br />'; 2076 echo '<meta http-equiv="Refresh" content="0; url=' . $RootPath.'/PrintCustTransPortrait.php?FromTransNo='.$InvoiceNo.'&InvOrCredit=Invoice&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