From: <dai...@us...> - 2010-05-30 05:53:47
|
Revision: 3477 http://web-erp.svn.sourceforge.net/web-erp/?rev=3477&view=rev Author: daintree Date: 2010-05-30 05:53:40 +0000 (Sun, 30 May 2010) Log Message: ----------- New script to allow sales to be entered from a single script. The customer is defaulted from the logged in users default stock location. Locations need to be defined with a customer account that is their default cash/counter sales account. The new script allows payments to be entered. Behind the scenes all the logic is the same as a normal order -> ConfirmDispatch_Invoice.php. It is not possible to invoice controlled/serial items using this script Modified Paths: -------------- trunk/BankMatching.php trunk/CustomerReceipt.php trunk/DeliveryDetails.php trunk/doc/Change.log.html trunk/includes/GetPrice.inc trunk/includes/MiscFunctions.php trunk/includes/SelectOrderItems_IntoCart.inc trunk/index.php Added Paths: ----------- trunk/CounterSales.php Modified: trunk/BankMatching.php =================================================================== --- trunk/BankMatching.php 2010-05-29 21:41:37 UTC (rev 3476) +++ trunk/BankMatching.php 2010-05-30 05:53:40 UTC (rev 3477) @@ -8,15 +8,22 @@ $title = _('Bank Account Matching'); include('includes/header.inc'); -if ((isset($_GET["Type"]) and $_GET["Type"]=='Receipts') OR (isset($_POST["Type"]) and $_POST["Type"]=='Receipts')){ +if ((isset($_GET['Type']) AND $_GET['Type']=='Receipts') OR + (isset($_POST['Type']) and $_POST['Type']=='Receipts')){ + $Type = 'Receipts'; $TypeName =_('Receipts'); -echo '<p class="page_title_text"><img src="'.$rootpath.'/css/'.$theme.'/images/money_add.png" title="' . _('Bank Matching') . '" alt="">' . ' ' . _('Bank Account Matching - Receipts') . '</p>'; -} elseif ((isset($_GET["Type"]) and $_GET["Type"]=='Payments') OR (isset($_POST["Type"]) and $_POST["Type"]=='Payments')) { + echo '<p class="page_title_text"><img src="'.$rootpath.'/css/'.$theme.'/images/money_add.png" title="' . _('Bank Matching') . '" alt="">' . ' ' . _('Bank Account Matching - Receipts') . '</p>'; + +} elseif ((isset($_GET['Type']) AND $_GET['Type']=='Payments') OR + (isset($_POST['Type']) and $_POST['Type']=='Payments')) { + $Type = 'Payments'; $TypeName =_('Payments'); -echo '<p class="page_title_text"><img src="'.$rootpath.'/css/'.$theme.'/images/money_delete.png" title="' . _('Bank Matching') . '" alt="">' . ' ' . _('Bank Account Matching - Payments') . '</p>'; + echo '<p class="page_title_text"><img src="'.$rootpath.'/css/'.$theme.'/images/money_delete.png" title="' . _('Bank Matching') . '" alt="">' . ' ' . _('Bank Account Matching - Payments') . '</p>'; + } else { + prnMsg(_('This page must be called with a bank transaction type') . '. ' . _('It should not be called directly'),'error'); include ('includes/footer.inc'); exit; @@ -26,54 +33,55 @@ for ($Counter=1;$Counter <= $_POST['RowCounter']; $Counter++){ if (isset($_POST["Clear_" . $Counter]) and $_POST["Clear_" . $Counter]==True){ /*Get amount to be cleared */ - $sql = "SELECT amount, + $sql = 'SELECT amount, exrate FROM banktrans - WHERE banktransid=" . $_POST["BankTrans_" . $Counter]; + WHERE banktransid=' . $_POST['BankTrans_' . $Counter]; $ErrMsg = _('Could not retrieve transaction information'); $result = DB_query($sql,$db,$ErrMsg); $myrow=DB_fetch_array($result); $AmountCleared = round($myrow[0] / $myrow[1],2); /*Update the banktrans recoord to match it off */ - $sql = "UPDATE banktrans SET amountcleared= ". $AmountCleared . - " WHERE banktransid=" . $_POST["BankTrans_" . $Counter]; + $sql = 'UPDATE banktrans SET amountcleared= '. $AmountCleared . + ' WHERE banktransid=' . $_POST['BankTrans_' . $Counter]; $ErrMsg = _('Could not match off this payment because'); $result = DB_query($sql,$db,$ErrMsg); - } elseif (isset($_POST["AmtClear_" . $Counter]) and is_numeric((float) $_POST["AmtClear_" . $Counter]) AND - ((isset($_POST["AmtClear_" . $Counter]) and $_POST["AmtClear_" . $Counter]<0 AND $Type=='Payments') OR - ($Type=='Receipts' AND (isset($_POST["AmtClear_" . $Counter]) and $_POST["AmtClear_" . $Counter]>0)))){ + } elseif (isset($_POST['AmtClear_' . $Counter]) AND + is_numeric((float) $_POST["AmtClear_" . $Counter]) AND + ((isset($_POST['AmtClear_' . $Counter]) AND $_POST['AmtClear_' . $Counter]<0 AND $Type=='Payments') OR + ($Type=='Receipts' AND (isset($_POST['AmtClear_' . $Counter]) and $_POST['AmtClear_' . $Counter]>0)))){ /*if the amount entered was numeric and negative for a payment or positive for a receipt */ - $sql = "UPDATE banktrans SET amountcleared=" . $_POST["AmtClear_" . $Counter] . " - WHERE banktransid=" . $_POST["BankTrans_" . $Counter]; + $sql = 'UPDATE banktrans SET amountcleared=' . $_POST['AmtClear_' . $Counter] . ' + WHERE banktransid=' . $_POST['BankTrans_' . $Counter]; $ErrMsg = _('Could not update the amount matched off this bank transaction because'); $result = DB_query($sql,$db,$ErrMsg); - } elseif (isset($_POST["Unclear_" . $Counter]) and $_POST["Unclear_" . $Counter]==True){ - $sql = "UPDATE banktrans SET amountcleared = 0 - WHERE banktransid=" . $_POST["BankTrans_" . $Counter]; + } elseif (isset($_POST['Unclear_' . $Counter]) and $_POST['Unclear_' . $Counter]==True){ + $sql = 'UPDATE banktrans SET amountcleared = 0 + WHERE banktransid=' . $_POST['BankTrans_' . $Counter]; $ErrMsg = _('Could not unclear this bank transaction because'); $result = DB_query($sql,$db,$ErrMsg); } } /*Show the updated position with the same criteria as previously entered*/ - $_POST["ShowTransactions"] = True; + $_POST['ShowTransactions'] = True; } echo '<div class="page_help_text">' . _('Use this screen to match webERP Receipts and Payments to your Bank Statement. Check your bank statement and click the check-box when you find the matching transaction.') . '</div><br>'; -echo "<form action='". $_SERVER['PHP_SELF'] . "?" . SID . "' method=post>"; +echo '<form action="'. $_SERVER['PHP_SELF'] . '?' . SID . '" method=post>'; -echo "<input type=hidden Name=Type Value=$Type>"; +echo '<input type="hidden" name="Type" Value="' . $Type . '">'; echo '<table><tr>'; echo '<td align=left>' . _('Bank Account') . ':</td><td colspan=3><select tabindex="1" name="BankAccount">'; -$sql = "SELECT accountcode, bankaccountname FROM bankaccounts"; +$sql = 'SELECT accountcode, bankaccountname FROM bankaccounts'; $resultBankActs = DB_query($sql,$db); while ($myrow=DB_fetch_array($resultBankActs)){ - if (isset($_POST['BankAccount']) and $myrow["accountcode"]==$_POST['BankAccount']){ + if (isset($_POST['BankAccount']) and $myrow['accountcode']==$_POST['BankAccount']){ echo "<option selected Value='" . $myrow['accountcode'] . "'>" . $myrow['bankaccountname']; } else { echo "<option Value='" . $myrow['accountcode'] . "'>" . $myrow['bankaccountname']; @@ -98,7 +106,7 @@ echo '<tr><td colspan=3>' . _('Choose outstanding') . ' ' . $TypeName . ' ' . _('only or all') . ' ' . $TypeName . ' ' . _('in the date range') . ':</td> <td><select tabindex="4" name="Ostg_or_All">'; -if ($_POST["Ostg_or_All"]=='All'){ +if ($_POST['Ostg_or_All']=='All'){ echo '<option selected Value="All">' . _('Show all') . ' ' . $TypeName . ' ' . _('in the date range'); echo '<option Value="Ostdg">' . _('Show unmatched') . ' ' . $TypeName . ' ' . _('only'); } else { @@ -109,7 +117,7 @@ echo '<tr><td colspan=3>' . _('Choose to display only the first 20 matching') . ' ' . $TypeName . ' ' . _('or all') . ' ' . $TypeName . ' ' . _('meeting the criteria') . ':</td><td><select tabindex="5" name="First20_or_All">'; -if ($_POST["First20_or_All"]=='All'){ +if ($_POST['First20_or_All']=='All'){ echo '<option selected Value="All">' . _('Show all') . ' ' . $TypeName . ' ' . _('in the date range'); echo '<option Value="First20">' . _('Show only the first 20') . ' ' . $TypeName; } else { @@ -137,7 +145,7 @@ $_SESSION['DefaultDateFormat'],'error'); } -if ($InputError !=1 AND isset($_POST["BankAccount"]) AND $_POST["BankAccount"]!="" AND isset($_POST["ShowTransactions"])){ +if ($InputError !=1 AND isset($_POST['BankAccount']) AND $_POST['BankAccount']!='' AND isset($_POST['ShowTransactions'])){ $SQLBeforeDate = FormatDateForSQL($_POST['BeforeDate']); $SQLAfterDate = FormatDateForSQL($_POST['AfterDate']); @@ -145,61 +153,61 @@ if ($_POST["Ostg_or_All"]=='All'){ if ($Type=='Payments'){ $sql = "SELECT banktransid, - ref, - amountcleared, - transdate, - amount/exrate as amt, - banktranstype - FROM banktrans - WHERE amount <0 - AND transdate >= '". $SQLAfterDate . "' - AND transdate <= '" . $SQLBeforeDate . "' - AND bankact=" .$_POST["BankAccount"] . " - ORDER BY transdate"; + ref, + amountcleared, + transdate, + amount/exrate as amt, + banktranstype + FROM banktrans + WHERE amount <0 + AND transdate >= '". $SQLAfterDate . "' + AND transdate <= '" . $SQLBeforeDate . "' + AND bankact=" .$_POST["BankAccount"] . " + ORDER BY transdate"; } else { /* Type must == Receipts */ $sql = "SELECT banktransid, - ref, - amountcleared, - transdate, - amount/exrate as amt, - banktranstype - FROM banktrans - WHERE amount >0 - AND transdate >= '". $SQLAfterDate . "' - AND transdate <= '" . $SQLBeforeDate . "' - AND bankact=" .$_POST['BankAccount'] . " - ORDER BY transdate"; + ref, + amountcleared, + transdate, + amount/exrate as amt, + banktranstype + FROM banktrans + WHERE amount >0 + AND transdate >= '". $SQLAfterDate . "' + AND transdate <= '" . $SQLBeforeDate . "' + AND bankact=" .$_POST['BankAccount'] . " + ORDER BY transdate"; } } else { /*it must be only the outstanding bank trans required */ if ($Type=='Payments'){ $sql = "SELECT banktransid, - ref, - amountcleared, - transdate, - amount/exrate as amt, - banktranstype - FROM banktrans - WHERE amount <0 - AND transdate >= '". $SQLAfterDate . "' - AND transdate <= '" . $SQLBeforeDate . "' - AND bankact=" .$_POST["BankAccount"] . " - AND ABS(amountcleared - (amount / exrate)) > 0.009 - ORDER BY transdate"; + ref, + amountcleared, + transdate, + amount/exrate as amt, + banktranstype + FROM banktrans + WHERE amount <0 + AND transdate >= '". $SQLAfterDate . "' + AND transdate <= '" . $SQLBeforeDate . "' + AND bankact=" .$_POST["BankAccount"] . " + AND ABS(amountcleared - (amount / exrate)) > 0.009 + ORDER BY transdate"; } else { /* Type must == Receipts */ $sql = "SELECT banktransid, - ref, - amountcleared, - transdate, - amount/exrate as amt, - banktranstype - FROM banktrans - WHERE amount >0 - AND transdate >= '". $SQLAfterDate . "' - AND transdate <= '" . $SQLBeforeDate . "' - AND bankact=" .$_POST["BankAccount"] . " - AND ABS(amountcleared - (amount / exrate)) > 0.009 - ORDER BY transdate"; + ref, + amountcleared, + transdate, + amount/exrate as amt, + banktranstype + FROM banktrans + WHERE amount >0 + AND transdate >= '". $SQLAfterDate . "' + AND transdate <= '" . $SQLBeforeDate . "' + AND bankact=" .$_POST["BankAccount"] . " + AND ABS(amountcleared - (amount / exrate)) > 0.009 + ORDER BY transdate"; } } if ($_POST["First20_or_All"]!='All'){ Added: trunk/CounterSales.php =================================================================== --- trunk/CounterSales.php (rev 0) +++ trunk/CounterSales.php 2010-05-30 05:53:40 UTC (rev 3477) @@ -0,0 +1,2269 @@ +<?php +/* $Id: SelectOrderItems.php 3453 2010-05-06 06:39:52Z lindsayh $*/ + +include('includes/DefineCartClass.php'); +$PageSecurity = 1; +/* Session started in session.inc for password checking and authorisation level check +config.php is in turn included in session.inc*/ + +include('includes/session.inc'); + +$title = _('Counter Sales'); + +include('includes/header.inc'); +include('includes/GetPrice.inc'); +include('includes/SQL_CommonFunctions.inc'); +include('includes/GetSalesTransGLCodes.inc'); + +if (empty($_GET['identifier'])) { + $identifier=date('U'); +} else { + $identifier=$_GET['identifier']; +} +if (isset($_SESSION['Items'.$identifier])){ + //update the Items object variable with the data posted from the form + $_SESSION['Items'.$identifier]->CustRef = $_POST['CustRef']; + $_SESSION['Items'.$identifier]->Comments = $_POST['Comments']; + $_SESSION['Items'.$identifier]->DeliverTo = $_POST['DeliverTo']; + $_SESSION['Items'.$identifier]->PhoneNo = $_POST['PhoneNo']; + $_SESSION['Items'.$identifier]->Email = $_POST['Email']; +} + +if (isset($_POST['QuickEntry'])){ + unset($_POST['PartSearch']); +} + +if (isset($_POST['order_items'])){ + foreach ($_POST as $key => $value) { + if (strstr($key,'itm')) { + $NewItem_array[substr($key,3)] = trim($value); + } + } +} + +if (isset($_GET['NewItem'])){ + $NewItem = trim($_GET['NewItem']); +} + +if (isset($_GET['NewOrder'])){ + /*New order entry - clear any existing order details from the Items object and initiate a newy*/ + if (isset($_SESSION['Items'.$identifier])){ + unset ($_SESSION['Items'.$identifier]->LineItems); + $_SESSION['Items'.$identifier]->ItemsOrdered=0; + unset ($_SESSION['Items'.$identifier]); + } +} + + +if (!isset($_SESSION['Items'.$identifier])){ + /* It must be a new order being created $_SESSION['Items'.$identifier] would be set up from the order + modification code above if a modification to an existing order. Also $ExistingOrder would be + set to 1. The delivery check screen is where the details of the order are either updated or + inserted depending on the value of ExistingOrder */ + + $_SESSION['ExistingOrder'] = 0; + $_SESSION['Items'.$identifier] = new cart; + $_SESSION['PrintedPackingSlip'] = 0; /*Of course 'cos the order ain't even started !!*/ + /*Get the default customer-branch combo from the user's default location record */ + $result = DB_query("SELECT cashsalecustomer, + locationname, + taxprovinceid + FROM locations + WHERE loccode='" . $_SESSION['UserStockLocation'] . "'",$db); + if (DB_num_rows($result)==0) { + 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'); + include('includes/footer.inc'); + exit; + } else { + $myrow = DB_fetch_array($result); //get the only row returned + $_SESSION['Items'.$identifier]->Branch = substr($myrow['cashsalecustomer'],strpos($myrow['cashsalecustomer'],' - ')+3); + + $_SESSION['Items'.$identifier]->DebtorNo = substr($myrow['cashsalecustomer'],0,strpos($myrow['cashsalecustomer'],' - ')); + $_SESSION['Items'.$identifier]->LocationName = $myrow['locationname']; + $_SESSION['Items'.$identifier]->Location = $_SESSION['UserStockLocation']; + $_SESSION['Items'.$identifier]->DispatchTaxProvince = $myrow['taxprovinceid']; + + // Now check to ensure this account exists and set defaults */ + $sql = "SELECT debtorsmaster.name, + holdreasons.dissallowinvoices, + debtorsmaster.salestype, + salestypes.sales_type, + debtorsmaster.currcode, + debtorsmaster.customerpoline, + paymentterms.terms + FROM debtorsmaster, + holdreasons, + salestypes, + paymentterms + WHERE debtorsmaster.salestype=salestypes.typeabbrev + AND debtorsmaster.holdreason=holdreasons.reasoncode + AND debtorsmaster.paymentterms=paymentterms.termsindicator + AND debtorsmaster.debtorno = '" . $_SESSION['Items'.$identifier]->DebtorNo . "'"; + + $ErrMsg = _('The details of the customer selected') . ': ' . $_SESSION['Items'.$identifier]->DebtorNo . ' ' . _('cannot be retrieved because'); + $DbgMsg = _('The SQL used to retrieve the customer details and failed was') . ':'; + $result =DB_query($sql,$db,$ErrMsg,$DbgMsg); + + $myrow = DB_fetch_row($result); + if ($myrow[1] != 1){ + if ($myrow[1]==2){ + prnMsg($myrow[0] . ' ' . _('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'); + } + + $_SESSION['RequireCustomerSelection']=0; + $_SESSION['Items'.$identifier]->CustomerName = $myrow[0]; + // the sales type is the price list to be used for this sale + $_SESSION['Items'.$identifier]->DefaultSalesType = $myrow[2]; + $_SESSION['Items'.$identifier]->SalesTypeName = $myrow[3]; + $_SESSION['Items'.$identifier]->DefaultCurrency = $myrow[4]; + $_SESSION['Items'.$identifier]->DefaultPOLine = $myrow[5]; + $_SESSION['Items'.$identifier]->PaymentTerms = $myrow[6]; + + /* now get the branch defaults from the customer branches table CustBranch. */ + + $sql = "SELECT custbranch.brname, + custbranch.defaultshipvia, + custbranch.deliverblind, + custbranch.specialinstructions, + custbranch.estdeliverydays, + custbranch.salesman, + custbranch.taxgroupid, + custbranch.defaultshipvia + FROM custbranch + WHERE custbranch.branchcode='" . $_SESSION['Items'.$identifier]->Branch . "' + AND custbranch.debtorno = '" . $_SESSION['Items'.$identifier]->DebtorNo . "'"; + + $ErrMsg = _('The customer branch record of the customer selected') . ': ' . $_SESSION['Items'.$identifier]->Branch . ' ' . _('cannot be retrieved because'); + $DbgMsg = _('SQL used to retrieve the branch details was') . ':'; + $result =DB_query($sql,$db,$ErrMsg,$DbgMsg); + + if (DB_num_rows($result)==0){ + + prnMsg(_('The branch details for branch code') . ': ' . $_SESSION['Items'.$identifier]->Branch . ' ' . _('against customer code') . ': ' . $_POST['Select'] . ' ' . _('could not be retrieved') . '. ' . _('Check the set up of the customer and branch'),'error'); + + if ($debug==1){ + echo '<br>' . _('The SQL that failed to get the branch details was') . ':<br>' . $sql; + } + include('includes/footer.inc'); + exit; + } + // add echo + echo '<br>'; + $myrow = DB_fetch_array($result); + + $_SESSION['Items'.$identifier]->DeliverTo = ''; + $_SESSION['Items'.$identifier]->DelAdd1 = $myrow['braddress1']; + $_SESSION['Items'.$identifier]->ShipVia = $myrow['defaultshipvia']; + $_SESSION['Items'.$identifier]->DeliverBlind = $myrow['deliverblind']; + $_SESSION['Items'.$identifier]->SpecialInstructions = $myrow['specialinstructions']; + $_SESSION['Items'.$identifier]->DeliveryDays = $myrow['estdeliverydays']; + $_SESSION['Items'.$identifier]->TaxGroup = $myrow['taxgroupid']; + + if ($_SESSION['Items'.$identifier]->SpecialInstructions) + prnMsg($_SESSION['Items'.$identifier]->SpecialInstructions,'warn'); + + if ($_SESSION['CheckCreditLimits'] > 0){ /*Check credit limits is 1 for warn and 2 for prohibit sales */ + $_SESSION['Items'.$identifier]->CreditAvailable = GetCreditAvailable($_SESSION['Items'.$identifier]->DebtorNo,$db); + + if ($_SESSION['CheckCreditLimits']==1 AND $_SESSION['Items'.$identifier]->CreditAvailable <=0){ + prnMsg(_('The') . ' ' . $myrow[0] . ' ' . _('account is currently at or over their credit limit'),'warn'); + } elseif ($_SESSION['CheckCreditLimits']==2 AND $_SESSION['Items'.$identifier]->CreditAvailable <=0){ + prnMsg(_('No more orders can be placed by') . ' ' . $myrow[0] . ' ' . _(' their account is currently at or over their credit limit'),'warn'); + include('includes/footer.inc'); + exit; + } + } + + } else { + prnMsg($myrow[0] . ' ' . _('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'); + } + + } +} // end if its a new sale to be set up ... + +if (isset($_POST['CancelOrder'])) { + + + unset($_SESSION['Items'.$identifier]->LineItems); + $_SESSION['Items'.$identifier]->ItemsOrdered = 0; + unset($_SESSION['Items'.$identifier]); + $_SESSION['Items'.$identifier] = new cart; + + echo '<br><br>'; + prnMsg(_('This sale has been cancelled as requested'),'success'); + echo '<br><br><a href="' .$_SERVER['PHP_SELF'] . '">' . _('Start a new Counter Sale') . '</a>'; + include('includes/footer.inc'); + exit; + +} else { /*Not cancelling the order */ + + echo '<p class="page_title_text"><img src="'.$rootpath.'/css/'.$theme.'/images/inventory.png" title="' . _('Counter Sales') . '" alt="">' . ' '; + + echo _('Counter Sale') . ' - ' . $_SESSION['Items'.$identifier]->LocationName . ' (' . _('all amounts in') . ' ' . $_SESSION['Items'.$identifier]->DefaultCurrency . ')'; + echo '</b></div>'; +} + +if (isset($_POST['Search']) or isset($_POST['Next']) or isset($_POST['Prev'])){ + + if ($_POST['Keywords']!=='' AND $_POST['StockCode']=='') { + $msg='</b><div class="page_help_text">' . _('Item description has been used in search') . '.</div>'; + } elseif ($_POST['StockCode']!=='' AND $_POST['Keywords']=='') { + $msg='</b><div class="page_help_text">' . _('Item Code has been used in search') . '.</div>'; + } elseif ($_POST['Keywords']=='' AND $_POST['StockCode']=='') { + $msg='</b><div class="page_help_text">' . _('Stock Category has been used in search') . '.</div>'; + } + if (isset($_POST['Keywords']) AND strlen($_POST['Keywords'])>0) { + //insert wildcard characters in spaces + $_POST['Keywords'] = strtoupper($_POST['Keywords']); + $SearchString = '%' . str_replace(' ', '%', $_POST['Keywords']) . '%'; + + if ($_POST['StockCat']=='All'){ + $SQL = "SELECT stockmaster.stockid, + stockmaster.description, + stockmaster.units + FROM stockmaster, + stockcategory + WHERE stockmaster.categoryid=stockcategory.categoryid + AND (stockcategory.stocktype='F' OR stockcategory.stocktype='D') + AND stockmaster.mbflag <>'G' + AND stockmaster.controlled <> 1 + AND stockmaster.description " . LIKE . " '$SearchString' + AND stockmaster.discontinued=0 + ORDER BY stockmaster.stockid"; + } else { + $SQL = "SELECT stockmaster.stockid, + stockmaster.description, + stockmaster.units + FROM stockmaster, stockcategory + WHERE stockmaster.categoryid=stockcategory.categoryid + AND (stockcategory.stocktype='F' OR stockcategory.stocktype='D') + AND stockmaster.mbflag <>'G' + AND stockmaster.controlled <> 1 + AND stockmaster.discontinued=0 + AND stockmaster.description " . LIKE . " '" . $SearchString . "' + AND stockmaster.categoryid='" . $_POST['StockCat'] . "' + ORDER BY stockmaster.stockid"; + } + + } elseif (strlen($_POST['StockCode'])>0){ + + $_POST['StockCode'] = strtoupper($_POST['StockCode']); + $SearchString = '%' . $_POST['StockCode'] . '%'; + + if ($_POST['StockCat']=='All'){ + $SQL = "SELECT stockmaster.stockid, + stockmaster.description, + stockmaster.units + FROM stockmaster, stockcategory + WHERE stockmaster.categoryid=stockcategory.categoryid + AND (stockcategory.stocktype='F' OR stockcategory.stocktype='D') + AND stockmaster.stockid " . LIKE . " '" . $SearchString . "' + AND stockmaster.mbflag <>'G' + AND stockmaster.controlled <> 1 + AND stockmaster.discontinued=0 + ORDER BY stockmaster.stockid"; + } else { + $SQL = "SELECT stockmaster.stockid, + stockmaster.description, + stockmaster.units + FROM stockmaster, stockcategory + WHERE stockmaster.categoryid=stockcategory.categoryid + AND (stockcategory.stocktype='F' OR stockcategory.stocktype='D') + AND stockmaster.stockid " . LIKE . " '" . $SearchString . "' + AND stockmaster.mbflag <>'G' + AND stockmaster.controlled <> 1 + AND stockmaster.discontinued=0 + AND stockmaster.categoryid='" . $_POST['StockCat'] . "' + ORDER BY stockmaster.stockid"; + } + + } else { + if ($_POST['StockCat']=='All'){ + $SQL = "SELECT stockmaster.stockid, + stockmaster.description, + stockmaster.units + FROM stockmaster, stockcategory + WHERE stockmaster.categoryid=stockcategory.categoryid + AND (stockcategory.stocktype='F' OR stockcategory.stocktype='D') + AND stockmaster.mbflag <>'G' + AND stockmaster.controlled <> 1 + AND stockmaster.discontinued=0 + ORDER BY stockmaster.stockid"; + } else { + $SQL = "SELECT stockmaster.stockid, + stockmaster.description, + stockmaster.units + FROM stockmaster, stockcategory + WHERE stockmaster.categoryid=stockcategory.categoryid + AND (stockcategory.stocktype='F' OR stockcategory.stocktype='D') + AND stockmaster.mbflag <>'G' + AND stockmaster.controlled <> 1 + AND stockmaster.discontinued=0 + AND stockmaster.categoryid='" . $_POST['StockCat'] . "' + ORDER BY stockmaster.stockid"; + } + } + + if (isset($_POST['Next'])) { + $Offset = $_POST['nextlist']; + } + if (isset($_POST['Prev'])) { + $Offset = $_POST['previous']; + } + if (!isset($Offset) or $Offset<0) { + $Offset=0; + } + $SQL = $SQL . ' LIMIT ' . $_SESSION['DefaultDisplayRecordsMax'].' OFFSET '.number_format($_SESSION['DefaultDisplayRecordsMax']*$Offset); + + $ErrMsg = _('There is a problem selecting the part records to display because'); + $DbgMsg = _('The SQL used to get the part selection was'); + $SearchResult = DB_query($SQL,$db,$ErrMsg, $DbgMsg); + + if (DB_num_rows($SearchResult)==0 ){ + prnMsg (_('There are no products available meeting the criteria specified'),'info'); + } + if (DB_num_rows($SearchResult)==1){ + $myrow=DB_fetch_array($SearchResult); + $NewItem = $myrow['stockid']; + DB_data_seek($SearchResult,0); + } + if (DB_num_rows($SearchResult)< $_SESSION['DisplayRecordsMax']){ + $Offset=0; + } + +} //end of if search + + +/* Always do the stuff below */ + +echo '<form action="' . $_SERVER['PHP_SELF'] . '?' . SID .'identifier='.$identifier . '"& name="SelectParts" method=post>'; + +//Get The exchange rate used for GPPercent calculations on adding or amending items +if ($_SESSION['Items'.$identifier]->DefaultCurrency != $_SESSION['CompanyRecord']['currencydefault']){ + $ExRateResult = DB_query("SELECT rate FROM currencies WHERE currabrev='" . $_SESSION['Items'.$identifier]->DefaultCurrency . "'",$db); + if (DB_num_rows($ExRateResult)>0){ + $ExRateRow = DB_fetch_row($ExRateResult); + $ExRate = $ExRateRow[0]; + } else { + $ExRate =1; + } +} else { + $ExRate = 1; +} + +/*Process Quick Entry */ +/* If enter is pressed on the quick entry screen, the default button may be Recalculate */ + if (isset($_POST['order_items']) + OR isset($_POST['QuickEntry']) + OR isset($_POST['Recalculate'])){ + + /* get the item details from the database and hold them in the cart object */ + + /*Discount can only be set later on -- after quick entry -- so default discount to 0 in the first place */ + $Discount = 0; + + $i=1; + while ($i<=$_SESSION['QuickEntries'] and isset($_POST['part_' . $i]) and $_POST['part_' . $i]!='') { + $QuickEntryCode = 'part_' . $i; + $QuickEntryQty = 'qty_' . $i; + $QuickEntryPOLine = 'poline_' . $i; + $QuickEntryItemDue = 'itemdue_' . $i; + + $i++; + + if (isset($_POST[$QuickEntryCode])) { + $NewItem = strtoupper($_POST[$QuickEntryCode]); + } + if (isset($_POST[$QuickEntryQty])) { + $NewItemQty = $_POST[$QuickEntryQty]; + } + if (isset($_POST[$QuickEntryItemDue])) { + $NewItemDue = $_POST[$QuickEntryItemDue]; + } else { + $NewItemDue = DateAdd (Date($_SESSION['DefaultDateFormat']),'d', $_SESSION['Items'.$identifier]->DeliveryDays); + } + if (isset($_POST[$QuickEntryPOLine])) { + $NewPOLine = $_POST[$QuickEntryPOLine]; + } else { + $NewPOLine = 0; + } + + if (!isset($NewItem)){ + unset($NewItem); + break; /* break out of the loop if nothing in the quick entry fields*/ + } + + if(!Is_Date($NewItemDue)) { + prnMsg(_('An invalid date entry was made for ') . ' ' . $NewItem . ' ' . _('The date entry') . ' ' . $NewItemDue . ' ' . _('must be in the format') . ' ' . $_SESSION['DefaultDateFormat'],'warn'); + //Attempt to default the due date to something sensible? + $NewItemDue = DateAdd (Date($_SESSION['DefaultDateFormat']),'d', $_SESSION['Items'.$identifier]->DeliveryDays); + } + /*Now figure out if the item is a kit set - the field MBFlag='K'*/ + $sql = "SELECT stockmaster.mbflag, stockmaster.controlled + FROM stockmaster + WHERE stockmaster.stockid='". $NewItem ."'"; + + $ErrMsg = _('Could not determine if the part being ordered was a kitset or not because'); + $DbgMsg = _('The sql that was used to determine if the part being ordered was a kitset or not was '); + $KitResult = DB_query($sql, $db,$ErrMsg,$DbgMsg); + + + if (DB_num_rows($KitResult)==0){ + prnMsg( _('The item code') . ' ' . $NewItem . ' ' . _('could not be retrieved from the database and has not been added to the order'),'warn'); + } elseif ($myrow=DB_fetch_array($KitResult)){ + if ($myrow['mbflag']=='K'){ /*It is a kit set item */ + $sql = "SELECT bom.component, + bom.quantity + FROM bom + WHERE bom.parent='" . $NewItem . "' + AND bom.effectiveto > '" . Date('Y-m-d') . "' + AND bom.effectiveafter < '" . Date('Y-m-d') . "'"; + + $ErrMsg = _('Could not retrieve kitset components from the database because') . ' '; + $KitResult = DB_query($sql,$db,$ErrMsg,$DbgMsg); + + $ParentQty = $NewItemQty; + while ($KitParts = DB_fetch_array($KitResult,$db)){ + $NewItem = $KitParts['component']; + $NewItemQty = $KitParts['quantity'] * $ParentQty; + $NewPOLine = 0; + include('includes/SelectOrderItems_IntoCart.inc'); + } + + } elseif ($myrow['mbflag']=='G'){ + 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'); + } elseif ($myrow['controlled']==1){ + prnMsg(_('The system does not currently cater for counter sales of lot controlled or serialised items'),'warn'); + } else { /*Its not a kit set item*/ + include('includes/SelectOrderItems_IntoCart.inc'); + } + } + } + unset($NewItem); + } /* end of if quick entry */ + + + /*Now do non-quick entry delete/edits/adds */ + +if ((isset($_SESSION['Items'.$identifier])) OR isset($NewItem)){ + + if(isset($_GET['Delete'])){ + $_SESSION['Items'.$identifier]->remove_from_cart($_GET['Delete']); /*Don't do any DB updates*/ + } + + foreach ($_SESSION['Items'.$identifier]->LineItems as $OrderLine) { + + if (isset($_POST['Quantity_' . $OrderLine->LineNumber])){ + + $Quantity = $_POST['Quantity_' . $OrderLine->LineNumber]; + + if (ABS($OrderLine->Price - $_POST['Price_' . $OrderLine->LineNumber])>0.01){ + $Price = $_POST['Price_' . $OrderLine->LineNumber]; + $_POST['GPPercent_' . $OrderLine->LineNumber] = (($Price*(1-($_POST['Discount_' . $OrderLine->LineNumber]/100))) - $OrderLine->StandardCost*$ExRate)/($Price *(1-$_POST['Discount_' . $OrderLine->LineNumber])/100); + } elseif (ABS($OrderLine->GPPercent - $_POST['GPPercent_' . $OrderLine->LineNumber])>=0.001) { + //then do a recalculation of the price at this new GP Percentage + $Price = ($OrderLine->StandardCost*$ExRate)/(1 -(($_POST['GPPercent_' . $OrderLine->LineNumber] + $_POST['Discount_' . $OrderLine->LineNumber])/100)); + } else { + $Price = $_POST['Price_' . $OrderLine->LineNumber]; + } + $DiscountPercentage = $_POST['Discount_' . $OrderLine->LineNumber]; + if ($_SESSION['AllowOrderLineItemNarrative'] == 1) { + $Narrative = $_POST['Narrative_' . $OrderLine->LineNumber]; + } else { + $Narrative = ''; + } + + if (!isset($OrderLine->DiscountPercent)) { + $OrderLine->DiscountPercent = 0; + } + + if ($Quantity<0 OR $Price <0 OR $DiscountPercentage >100 OR $DiscountPercentage <0){ + 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'); + } elseif ($OrderLine->Quantity !=$Quantity + OR $OrderLine->Price != $Price + OR ABS($OrderLine->DiscountPercent -$DiscountPercentage/100) >0.001 + OR $OrderLine->Narrative != $Narrative + OR $OrderLine->ItemDue != $_POST['ItemDue_' . $OrderLine->LineNumber] + OR $OrderLine->POLine != $_POST['POLine_' . $OrderLine->LineNumber]) { + + $_SESSION['Items'.$identifier]->update_cart_item($OrderLine->LineNumber, + $Quantity, + $Price, + ($DiscountPercentage/100), + $Narrative, + 'Yes', /*Update DB */ + $_POST['ItemDue_' . $OrderLine->LineNumber], + $_POST['POLine_' . $OrderLine->LineNumber], + $_POST['GPPercent_' . $OrderLine->LineNumber]); + } + } //page not called from itself - POST variables not set + } +} + + +if (isset($NewItem)){ +/* 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 +Now figure out if the item is a kit set - the field MBFlag='K' +* controlled items and ghost/phantom items cannot be selected because the SQL to show items to select doesn't show 'em +* */ + $sql = "SELECT stockmaster.mbflag, + stockmaster.taxcatid + FROM stockmaster + WHERE stockmaster.stockid='". $NewItem ."'"; + + $ErrMsg = _('Could not determine if the part being ordered was a kitset or not because'); + + $KitResult = DB_query($sql, $db,$ErrMsg); + + $NewItemQty = 1; /*By Default */ + $Discount = 0; /*By default - can change later or discount category override */ + + if ($myrow=DB_fetch_array($KitResult)){ + if ($myrow['mbflag']=='K'){ /*It is a kit set item */ + $sql = "SELECT bom.component, + bom.quantity + FROM bom + WHERE bom.parent='" . $NewItem . "' + AND bom.effectiveto > '" . Date('Y-m-d') . "' + AND bom.effectiveafter < '" . Date('Y-m-d') . "'"; + + $ErrMsg = _('Could not retrieve kitset components from the database because'); + $KitResult = DB_query($sql,$db,$ErrMsg); + + $ParentQty = $NewItemQty; + while ($KitParts = DB_fetch_array($KitResult,$db)){ + $NewItem = $KitParts['component']; + $NewItemQty = $KitParts['quantity'] * $ParentQty; + $NewPOLine = 0; + $NewItemDue = date($_SESSION['DefaultDateFormat']); + include('includes/SelectOrderItems_IntoCart.inc'); + $_SESSION['Items'.$identifier]->GetTaxes(($_SESSION['Items'.$identifier]->LineCounter - 1)); + } + + } else { /*Its not a kit set item*/ + $NewItemDue = date($_SESSION['DefaultDateFormat']); + $NewPOLine = 0; + + include('includes/SelectOrderItems_IntoCart.inc'); + $_SESSION['Items'.$identifier]->GetTaxes(($_SESSION['Items'.$identifier]->LineCounter - 1)); + } + + } /* end of if its a new item */ + +} /*end of if its a new item */ + +if (isset($NewItem_array) && isset($_POST['order_items'])){ +/* 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 */ +/*Now figure out if the item is a kit set - the field MBFlag='K'*/ + foreach($NewItem_array as $NewItem => $NewItemQty) { + if($NewItemQty > 0) { + $sql = "SELECT stockmaster.mbflag + FROM stockmaster + WHERE stockmaster.stockid='". $NewItem ."'"; + + $ErrMsg = _('Could not determine if the part being ordered was a kitset or not because'); + + $KitResult = DB_query($sql, $db,$ErrMsg); + + //$NewItemQty = 1; /*By Default */ + $Discount = 0; /*By default - can change later or discount category override */ + + if ($myrow=DB_fetch_array($KitResult)){ + if ($myrow['mbflag']=='K'){ /*It is a kit set item */ + $sql = "SELECT bom.component, + bom.quantity + FROM bom + WHERE bom.parent='" . $NewItem . "' + AND bom.effectiveto > '" . Date('Y-m-d') . "' + AND bom.effectiveafter < '" . Date('Y-m-d') . "'"; + + $ErrMsg = _('Could not retrieve kitset components from the database because'); + $KitResult = DB_query($sql,$db,$ErrMsg); + + $ParentQty = $NewItemQty; + while ($KitParts = DB_fetch_array($KitResult,$db)){ + $NewItem = $KitParts['component']; + $NewItemQty = $KitParts['quantity'] * $ParentQty; + $NewItemDue = date($_SESSION['DefaultDateFormat']); + $NewPOLine = 0; + include('includes/SelectOrderItems_IntoCart.inc'); + $_SESSION['Items'.$identifier]->GetTaxes(($_SESSION['Items'.$identifier]->LineCounter - 1)); + } + + } else { /*Its not a kit set item*/ + $NewItemDue = date($_SESSION['DefaultDateFormat']); + $NewPOLine = 0; + include('includes/SelectOrderItems_IntoCart.inc'); + $_SESSION['Items'.$identifier]->GetTaxes(($_SESSION['Items'.$identifier]->LineCounter - 1)); + } + } /* end of if its a new item */ + } /*end of if its a new item */ + } +} + + +/* Run through each line of the order and work out the appropriate discount from the discount matrix */ +$DiscCatsDone = array(); +$counter =0; +foreach ($_SESSION['Items'.$identifier]->LineItems as $OrderLine) { + + if ($OrderLine->DiscCat !="" AND ! in_array($OrderLine->DiscCat,$DiscCatsDone)){ + $DiscCatsDone[$counter]=$OrderLine->DiscCat; + $QuantityOfDiscCat =0; + + foreach ($_SESSION['Items'.$identifier]->LineItems as $StkItems_2) { + /* add up total quantity of all lines of this DiscCat */ + if ($StkItems_2->DiscCat==$OrderLine->DiscCat){ + $QuantityOfDiscCat += $StkItems_2->Quantity; + } + } + $result = DB_query("SELECT MAX(discountrate) AS discount + FROM discountmatrix + WHERE salestype='" . $_SESSION['Items'.$identifier]->DefaultSalesType . "' + AND discountcategory ='" . $OrderLine->DiscCat . "' + AND quantitybreak <" . $QuantityOfDiscCat,$db); + $myrow = DB_fetch_row($result); + if ($myrow[0]!=0){ /* need to update the lines affected */ + foreach ($_SESSION['Items'.$identifier]->LineItems as $StkItems_2) { + /* add up total quantity of all lines of this DiscCat */ + if ($StkItems_2->DiscCat==$OrderLine->DiscCat AND $StkItems_2->DiscountPercent == 0){ + $_SESSION['Items'.$identifier]->LineItems[$StkItems_2->LineNumber]->DiscountPercent = $myrow[0]; + } + } + } + } +} /* end of discount matrix lookup code */ + +if (count($_SESSION['Items'.$identifier]->LineItems)>0){ /*only show order lines if there are any */ +/* +// ************************************************************************* +// 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 +// ************************************************************************* +*/ + + echo '<br> + <table width="90%" cellpadding="2" colspan="7"> + <tr bgcolor=#800000>'; + echo '<th>' . _('Item Code') . '</th> + <th>' . _('Item Description') . '</th> + <th>' . _('Quantity') . '</th> + <th>' . _('QOH') . '</th> + <th>' . _('Unit') . '</th> + <th>' . _('Price') . '</th> + <th>' . _('Discount') . '</th> + <th>' . _('GP %') . '</th> + <th>' . _('Net') . '</th> + <th>' . _('Tax') . '</th> + <th>' . _('Total') . '<br>' . _('Incl Tax') . '</th> + </tr>'; + + $_SESSION['Items'.$identifier]->total = 0; + $_SESSION['Items'.$identifier]->totalVolume = 0; + $_SESSION['Items'.$identifier]->totalWeight = 0; + $TaxTotals = array(); + $TaxGLCodes = array(); + $TaxTotal =0; + $k =0; //row colour counter + foreach ($_SESSION['Items'.$identifier]->LineItems as $OrderLine) { + + $SubTotal = $OrderLine->Quantity * $OrderLine->Price * (1 - $OrderLine->DiscountPercent); + $DisplayDiscount = number_format(($OrderLine->DiscountPercent * 100),2); + $QtyOrdered = $OrderLine->Quantity; + $QtyRemain = $QtyOrdered - $OrderLine->QtyInv; + + if ($OrderLine->QOHatLoc < $OrderLine->Quantity AND ($OrderLine->MBflag=='B' OR $OrderLine->MBflag=='M')) { + /*There is a stock deficiency in the stock location selected */ + $RowStarter = '<tr bgcolor="#EEAABB">'; + } elseif ($k==1){ + $RowStarter = '<tr class="OddTableRows">'; + $k=0; + } else { + $RowStarter = '<tr class="EvenTableRows">'; + $k=1; + } + + echo $RowStarter; + echo '<input type="hidden" name="POLine_' . $OrderLine->LineNumber . '" value="">'; + + echo '<td><a target="_blank" href="' . $rootpath . '/StockStatus.php?' . SID .'identifier='.$identifier . '&StockID=' . $OrderLine->StockID . '&DebtorNo=' . $_SESSION['Items'.$identifier]->DebtorNo . '">' . $OrderLine->StockID . '</a></td> + <td>' . $OrderLine->ItemDescription . '</td>'; + + echo '<td><input class="number" tabindex=2 type=tect name="Quantity_' . $OrderLine->LineNumber . '" size=6 maxlength=6 value=' . $OrderLine->Quantity . '>'; + + echo '</td> + <td class="number">' . $OrderLine->QOHatLoc . '</td> + <td>' . $OrderLine->Units . '</td>'; + + echo '<td><input class="number" type=text name="Price_' . $OrderLine->LineNumber . '" size=16 maxlength=16 value=' . $OrderLine->Price . '></td> + <td><input class="number" type=text name="Discount_' . $OrderLine->LineNumber . '" size=5 maxlength=4 value=' . ($OrderLine->DiscountPercent * 100) . '></td> + <td><input class="number" type=text name="GPPercent_' . $OrderLine->LineNumber . '" size=3 maxlength=40 value=' . $OrderLine->GPPercent . '></td>'; + echo '</td><td class=number>' . number_format($SubTotal,2) . '</td>'; + $LineDueDate = $OrderLine->ItemDue; + if (!Is_Date($OrderLine->ItemDue)){ + $LineDueDate = DateAdd (Date($_SESSION['DefaultDateFormat']),'d', $_SESSION['Items'.$identifier]->DeliveryDays); + $_SESSION['Items'.$identifier]->LineItems[$OrderLine->LineNumber]->ItemDue= $LineDueDate; + } + $i=0; // initialise the number of taxes iterated through + $TaxLineTotal =0; //initialise tax total for the line + + foreach ($OrderLine->Taxes AS $Tax) { + if (empty($TaxTotals[$Tax->TaxAuthID])) { + $TaxTotals[$Tax->TaxAuthID]=0; + } + if ($Tax->TaxOnTax ==1){ + $TaxTotals[$Tax->TaxAuthID] += ($Tax->TaxRate * ($SubTotal + $TaxLineTotal)); + $TaxLineTotal += ($Tax->TaxRate * ($SubTotal + $TaxLineTotal)); + } else { + $TaxTotals[$Tax->TaxAuthID] += ($Tax->TaxRate * $SubTotal); + $TaxLineTotal += ($Tax->TaxRate * $SubTotal); + } + $TaxGLCodes[$Tax->TaxAuthID] = $Tax->TaxGLCode; + } + + $TaxTotal += $TaxLineTotal; + + echo '<td class="number">' . number_format($TaxLineTotal ,2) . '</td>'; + echo '<td class="number">' . number_format($SubTotal + $TaxLineTotal ,2) . '</td>'; + echo '<td><a href="' . $_SERVER['PHP_SELF'] . '?' . SID .'&identifier='.$identifier . '&Delete=' . $OrderLine->LineNumber . '" onclick="return confirm(\'' . _('Are You Sure?') . '\');">' . _('Delete') . '</a></td></tr>'; + + if ($_SESSION['AllowOrderLineItemNarrative'] == 1){ + echo $RowStarter; + echo '<td valign="top" colspan="11">' . _('Narrative') . ':<textarea name="Narrative_' . $OrderLine->LineNumber . '" cols="100" rows="1">' . stripslashes(AddCarriageReturns($OrderLine->Narrative)) . '</textarea><br></td></tr>'; + } else { + echo '<input type=hidden name="Narrative" value="">'; + } + + $_SESSION['Items'.$identifier]->total = $_SESSION['Items'.$identifier]->total + $SubTotal; + $_SESSION['Items'.$identifier]->totalVolume = $_SESSION['Items'.$identifier]->totalVolume + $OrderLine->Quantity * $OrderLine->Volume; + $_SESSION['Items'.$identifier]->totalWeight = $_SESSION['Items'.$identifier]->totalWeight + $OrderLine->Quantity * $OrderLine->Weight; + + } /* end of loop around items */ + + echo '<tr class="EvenTableRows"><td colspan="8" class="number"><b>' . _('Total') . '</b></td> + <td class=number>' . number_format(($_SESSION['Items'.$identifier]->total),2) . '</td> + <td class=number>' . number_format($TaxTotal,2) . '</td> + <td class=number>' . number_format(($_SESSION['Items'.$identifier]->total+$TaxTotal),2) . '</td> + </tr> + </table>'; + echo '<table><tr><td>'; + //nested table + echo '<table><tr> + <td>'. _('Picked Up By') .':</td> + <td><input type=text size=25 maxlength=25 name="DeliverTo" value="' . $_SESSION['Items'.$identifier]->DeliverTo . '"></td> + </tr>'; + echo '<tr> + <td>'. _('Contact Phone Number') .':</td> + <td><input type=text size=25 maxlength=25 name="PhoneNo" value="' . $_SESSION['Items'.$identifier]->PhoneNo . '"></td> + </tr>'; + + echo '<tr><td>' . _('Contact Email') . ':</td><td><input type=text size=25 maxlength=30 name="Email" value="' . $_SESSION['Items'.$identifier]->Email . '"></td></tr>'; + + echo '<tr><td>'. _('Customer Reference') .':</td> + <td><input type=text size=25 maxlength=25 name="CustRef" value="' . $_SESSION['Items'.$identifier]->CustRef . '"></td> + </tr>'; + + echo '<tr> + <td>'. _('Comments') .':</td> + <td><textarea name=Comments cols=23 rows=5>' . $_SESSION['Items'.$identifier]->Comments .'</textarea></td> + </tr>'; + echo '</table>'; //end the sub table in the first column of master table + echo '</td><th valign="bottom">'; //for the master table + echo '<table class="selection">'; // a new nested table in the second column of master table + //now the payment stuff in this column + $PaymentMethodsResult = DB_query('SELECT paymentid, paymentname FROM paymentmethods',$db); + + echo '<tr><td>' . _('Payment Type') . ':</td><td><select name="PaymentMethod">'; + while ($PaymentMethodRow = DB_fetch_array($PaymentMethodsResult)){ + if ($_POST['PaymentMethod'] == $PaymentMethodRow['paymentid']){ + echo '<option selected value=' . $PaymentMethodRow['paymentid'] . '>' . $PaymentMethodRow['paymentname'] . '</option>'; + } else { + echo '<option value=' . $PaymentMethodRow['paymentid'] . '>' . $PaymentMethodRow['paymentname'] . '</option>'; + } + } + echo '</select></td></tr>'; + + $BankAccountsResult = DB_query('SELECT bankaccountname, accountcode FROM bankaccounts',$db); + + echo '<tr><td>' . _('Banked to') . ':</td><td><select name="BankAccount">'; + while ($BankAccountsRow = DB_fetch_array($BankAccountsResult)){ + if ($_POST['BankAccount'] == $BankAccountsRow['accountcode']){ + echo '<option selected value=' . $BankAccountsRow['accountcode'] . '>' . $BankAccountsRow['bankaccountname'] . '</option>'; + } else { + echo '<option value=' . $BankAccountsRow['accountcode'] . '>' . $BankAccountsRow['bankaccountname'] . '</option>'; + } + } + echo '</select></td></tr>'; + + if (!isset($_POST['AmountPaid'])){ + $_POST['AmountPaid'] =0; + } + echo '<tr><td>' . _('Amount Paid') . ':</td><td><input type="text" class="number" name="AmountPaid" maxlength="12" size="12" value=' . $_POST['AmountPaid'] . '></td></tr>'; + + echo '</table>'; //end the sub table in the second column of master table + echo '</td></tr></table>'; //end of column/row/master table + echo '<br><div class="centre"><input type=submit name="Recalculate" Value="' . _('Re-Calculate') . '"> + <input type=submit name="ProcessSale" value="' . _('Process The Sale') . '"></div><hr>'; +} # end of if lines + +/* ********************************** + * Invoice Processing Here + * ********************************** + * */ +if (isset($_POST['ProcessSale']) && $_POST['ProcessSale'] != ""){ + + $InputError = false; //always assume the best + //but check for the worst + if ($_SESSION['Items'.$identifier]->LineCounter == 0){ + prnMsg(_('There are no lines on this sale. Please enter lines to invoice first'),'error'); + $InputError = true; + } + if (ABS($_POST['AmountPaid'] -($_SESSION['Items'.$identifier]->total+$TaxTotal))>=0.01) { + 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'); + $InputError = true; + } + + if ($_SESSION['ProhibitNegativeStock']==1){ // checks for negative stock after processing invoice + //sadly this check does not combine quantities occuring twice on and order and each line is considered individually :-( + $NegativesFound = false; + foreach ($_SESSION['Items'.$identifier]->LineItems as $OrderLine) { + $SQL = "SELECT stockmaster.description, + locstock.quantity, + stockmaster.mbflag + FROM locstock + INNER JOIN stockmaster + ON stockmaster.stockid=locstock.stockid + WHERE stockmaster.stockid='" . $OrderLine->StockID . "' + AND locstock.loccode='" . $_SESSION['Items'.$identifier]->Location . "'"; + + $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)'); + $Result = DB_query($SQL,$db,$ErrMsg); + $CheckNegRow = DB_fetch_array($Result); + if ($CheckNegRow['mbflag']=='B' OR $CheckNegRow['mbflag']=='M'){ + if ($CheckNegRow['quantity'] < $OrderLine->Quantity){ + 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')); + $NegativesFound = true; + } + } elseif ($CheckNegRow['mbflag']=='A') { + + /*Now look for assembly components that would go negative */ + $SQL = "SELECT bom.component, + stockmaster.description, + locstock.quantity-(" . $OrderLine->Quantity . "*bom.quantity) AS qtyleft + FROM bom + INNER JOIN locstock + ON bom.component=locstock.stockid + INNER JOIN stockmaster + ON stockmaster.stockid=bom.component + WHERE bom.parent='" . $OrderLine->StockID . "' + AND locstock.loccode='" . $_SESSION['Items'.$identifier]->Location . "' + AND effectiveafter <'" . Date('Y-m-d') . "' + AND effectiveto >='" . Date('Y-m-d') . "'"; + + $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)'); + $Result = DB_query($SQL,$db,$ErrMsg); + while ($NegRow = DB_fetch_array($Result)){ + if ($NegRow['qtyleft']<0){ + 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')); + $NegativesFound = true; + } // end if negative would result + } //loop around the components of an assembly item + }//end if its an assembly item - check component stock + + } //end of loop around items on the order for negative check + + if ($NegativesFound){ + 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'); + $InputError = true; + } + + }//end of testing for negative stocks + + + if ($InputError == false) { //all good so let's get on with the processing + + /* Now Get the area where the sale is to from the branches table */ + + $SQL = "SELECT area, + defaultshipvia + FROM custbranch + WHERE custbranch.debtorno ='". $_SESSION['Items'.$identifier]->DebtorNo . "' + AND custbranch.branchcode = '" . $_SESSION['Items'.$identifier]->Branch . "'"; + + $ErrMsg = _('We were unable to load the area where the sale is to from the custbranch table'); + $Result = DB_query($SQL,$db, $ErrMsg); + $myrow = DB_fetch_row($Result); + $Area = $myrow[0]; + $DefaultShipVia = $myrow[1]; + DB_free_result($Result); + + /*company record read in on login with info on GL Links and debtors GL account*/ + + if ($_SESSION['CompanyRecord']==0){ + /*The company data and preferences could not be retrieved for some reason */ + prnMsg( _('The company information and preferences could not be retrieved. See your system administrator'), 'error'); + include('includes/footer.inc'); + exit; + } + + // ************************************************************************* + // 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 + // ************************************************************************* + + /*First add the order to the database - it only exists in the session currently! */ + $OrderNo = GetNextTransNo(30, $db); + + $HeaderSQL = "INSERT INTO salesorders ( orderno, + debtorno, + branchcode, + customerref, + comments, + orddate, + ordertype, + shipvia, + deliverto, + deladd1, + contactphone, + contactemail, + fromstkloc, + deliverydate, + confirmeddate, + deliverblind) + VALUES ( + " . $OrderNo . ", + '" . $_SESSION['Items'.$identifier]->DebtorNo . "', + '" . $_SESSION['Items'.$identifier]->Branch . "', + '". DB_escape_string($_SESSION['Items'.$identifier]->CustRef) ."', + '". DB_escape_string($_SESSION['Items'.$identifier]->Comments) ."', + '" . Date("Y-m-d H:i") . "', + '" . $_SESSION['Items'.$identifier]->DefaultSalesType . "', + " . $_SESSION['Items'.$identifier]->ShipVia . ", + '". DB_escape_string($_SESSION['Items'.$identifier]->DeliverTo) . "', + '" . _('Counter Sale') . "', + '" . $_SESSION['Items'.$identifier]->PhoneNo . "', + '" . $_SESSION['Items'.$identifier]->Email . "', + '" . $_SESSION['Items'.$identifier]->Location ."', + '" . Date('Y-m-d') . "', + '" . Date('Y-m-d') . "', + 0)"; + + $ErrMsg = _('The order cannot be added because'); + $InsertQryResult = DB_query($HeaderSQL,$db,$ErrMsg); + + $StartOf_LineItemsSQL = 'INSERT INTO salesorderdetails (orderlineno, + orderno, + stkcode, + unitprice, + quantity, + discountpercent, + narrative, + itemdue, + actualdispatchdate, + qtyinvoiced, + completed) + VALUES ('; + + $DbgMsg = _('Trouble inserting a line of a sales order. The SQL that failed was'); + foreach ($_SESSION['Items'.$identifier]->LineItems as $StockItem) { + + $LineItemsSQL = $StartOf_LineItemsSQL . + $StockItem->LineNumber . ', + ' . $OrderNo . ", + '" . $StockItem->StockID . "', + ". $StockItem->Price . ', + ' . $StockItem->Quantity . ', + ' . floatval($StockItem->DiscountPercent) . ", + '" . DB_escape_string($StockItem->Narrative) . "', + '" . Date('Y-m-d') . "', + '" . Date('Y-m-d') . "', + " . $StockItem->Quantity . ', + 1)'; + + $ErrMsg = _('Unable to add the sales order line'); + $Ins_LineItemResult = DB_query($LineItemsSQL,$db,$ErrMsg,$DbgMsg,true); + + /*Now check to see if the item is manufactured + * and AutoCreateWOs is on + * and it is a real order (not just a quotation)*/ + + if ($StockItem->MBflag=='M' + AND $_SESSION['AutoCreateWOs']==1){ //oh yeah its all on! + + //now get the data required to test to see if we need to make a new WO + $QOHResult = DB_query("SELECT SUM(quantity) FROM locstock WHERE stockid='" . $StockItem->StockID . "'",$db); + $QOHRow = DB_fetch_row($QOHResult); + $QOH = $QOHRow[0]; + + $SQL = "SELECT SUM(salesorderdetails.quantity - salesorderdetails.qtyinvoiced) AS qtydemand + FROM salesorderdetails + WHERE salesorderdetails.stkcode = '" . $StockItem->StockID . "' + AND salesorderdetails.completed = 0"; + $DemandResult = DB_query($SQL,$db); + $DemandRow = DB_fetch_row($DemandResult); + $QuantityDemand = $DemandRow[0]; + + $SQL = "SELECT SUM((salesorderdetails.quantity-salesorderdetails.qtyinvoiced)*bom.quantity) AS dem + FROM salesorderdetails, + bom, + stockmaster + WHERE salesorderdetails.stkcode=bom.parent + AND salesorderdetails.quantity-salesorderdetails.qtyinvoiced > 0 + AND bom.component='" . $StockItem->StockID . "' + AND stockmaster.stockid=bom.parent + AND stockmaster.mbflag='A' + AND salesorderdetails.completed=0"; + $AssemblyDemandResult = DB_query($SQL,$db); + $AssemblyDemandRow = DB_fetch_row($AssemblyDemandResult); + $QuantityAssemblyDemand = $AssemblyDemandRow[0]; + + $SQL = "SELECT SUM(purchorderdetails.quantityord - purchorderdetails.quantityrecd) as qtyonorder + FROM purchorderdetails, + purchorders + WHERE purchorderdetails.orderno = purchorders.orderno + AND purchorderdetails.itemcode = '" . $StockItem->StockID . "' + AND purchorderdetails.completed = 0"; + $PurchOrdersResult = DB_query($SQL,$db); + $PurchOrdersRow = DB_fetch_row($PurchOrdersResult); + $QuantityPurchOrders = $PurchOrdersRow[0]; + + $SQL = "SELECT SUM(woitems.qtyreqd - woitems.qtyrecd) as qtyonorder + FROM woitems INNER JOIN workorders + ON woitems.wo=workorders.wo + WHERE woitems.stockid = '" . $StockItem->StockID . "' + AND woitems.qtyreqd > woitems.qtyrecd + AND workorders.closed = 0"; + $WorkOrdersResult = DB_query($SQL,$db); + $WorkOrdersRow = DB_fetch_row($WorkOrdersResult); + $QuantityWorkOrders = $WorkOrdersRow[0]; + + //Now we have the data - do we need to make any more? + $ShortfallQuantity = $QOH-$QuantityDemand-$QuantityAssemblyDemand+$QuantityPurchOrders+$QuantityWorkOrders; + + if ($ShortfallQuantity < 0) { //then we need to make a work order + //How many should the work order be for?? + if ($ShortfallQuantity + $StockItem->EOQ < 0){ + $WOQuantity = -$ShortfallQuantity; + } else { + $WOQuantity = $StockItem->EOQ; + } + + $WONo = GetNextTransNo(40,$db); + $ErrMsg = _('Unable to insert a new work order for the sales order item'); + $InsWOResult = DB_query("INSERT INTO workorders (wo, + loccode, + requiredby, + startdate) + VALUES (" . $WONo . ", + '" . $_SESSION['DefaultFactoryLocation'] . "', + '" . Date('Y-m-d') . "', + '" . Date('Y-m-d'). "')", + $db,$ErrMsg,$DbgMsg,true); + //Need to get the latest BOM to roll up cost + $CostResult = DB_query("SELECT SUM((materialcost+labourcost+overheadcost)*bom.quantity) AS cost + FROM stockmaster INNER JOIN bom + ON stockmaster.stockid=bom.component + WHERE bom.parent='" . $StockItem->StockID . "' + AND bom.loccode='" . $_SESSION['DefaultFactoryLocation'] . "'", + $db); + $CostRow = DB_fetch_row($CostResult); + if (is_null($CostRow[0]) OR $CostRow[0]==0){ + $Cost =0; + 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'); + } else { + $Cost = $CostRow[0]; + } + + // insert parent item info + $sql = "INSERT INTO woitems (wo, + stockid, + qtyreqd, + stdcost) + VALUES ( " . $WONo . ", + '" . $StockItem->StockID . "', + " . $WOQuantity . ", + " . $Cost . ")"; + $ErrMsg = _('The work order item could not be added'); + $result = DB_query($sql,$db,$ErrMsg,$DbgMsg,true); + + //Recursively insert real component requirements - see includes/SQL_CommonFunctions.in for function WoRealRequirements + WoRealRequirements($db, $WONo, $_SESSION['DefaultFactoryLocation'], $StockItem->StockID); + + $FactoryManagerEmail = _('A new work order has been created for') . + ":\n" . $StockItem->StockID . ' - ' . $StockItem->Descr . ' x ' . $WOQuantity . ' ' . $StockItem->UOM . + "\n" . _('These are for') . ' ' . $_SESSION['Items'.$identifier]->CustomerName . ' ' . _('there order ref') . ': ' . $_SESSION['Items'.$identifier]->CustRef . ' ' ._('our order number') . ': ' . $OrderNo; + + if ($StockItem->Serialised AND $StockItem->NextSerialNo>0){ + //then we must create the serial numbers for the new WO also + $FactoryManagerEmail .= "\n" . _('The following serial numbers ... [truncated message content] |