1<?php 2 3 4/* Definition of the cart class 5this class can hold all the information for: 6 7i) a sales order 8ii) an invoice 9iii) a credit note 10 11*/ 12 13 14Class Cart { 15 16 var $LineItems; /*array of objects of class LineDetails using the product id as the pointer */ 17 var $total; /*total cost of the items ordered */ 18 var $totalVolume; 19 var $totalWeight; 20 var $LineCounter; 21 var $ItemsOrdered; /*no of different line items ordered */ 22 var $DeliveryDate; 23 var $DefaultSalesType; 24 var $SalesTypeName; 25 var $DefaultCurrency; 26 var $CurrDecimalPlaces; 27 var $PaymentTerms; 28 var $DeliverTo; 29 var $DelAdd1; 30 var $DelAdd2; 31 var $DelAdd3; 32 var $DelAdd4; 33 var $DelAdd5; 34 var $DelAdd6; 35 var $SalesPerson; 36 var $PhoneNo; 37 var $Email; 38 var $CustRef; 39 var $Comments; 40 var $Location; 41 var $LocationName; 42 var $DebtorNo; 43 var $CustomerName; 44 var $Orig_OrderDate; 45 var $Branch; 46 var $TransID; 47 var $ShipVia; 48 var $FreightCost; 49 var $FreightTaxes; 50 Var $OrderNo; 51 Var $Consignment; 52 Var $Quotation; 53 Var $DeliverBlind; 54 Var $CreditAvailable; //in customer currency 55 Var $TaxGroup; 56 Var $DispatchTaxProvince; 57 Var $DefaultPOLine; 58 Var $DeliveryDays; 59 var $TaxTotals; 60 var $TaxGLCodes; 61 var $BuyerName; 62 var $SpecialInstructions; 63 64 function __construct(){ 65 /*Constructor function initialises a new shopping cart */ 66 $this->LineItems = array(); 67 $this->total=0; 68 $this->ItemsOrdered=0; 69 $this->LineCounter=0; 70 $this->DefaultSalesType=''; 71 $this->FreightCost =0; 72 $this->FreightTaxes = array(); 73 $this->CurrDecimalPlaces=2; //default 74 } 75 76 function cart() { 77 self::__construct(); 78 } 79 80 function add_to_cart($StockID, 81 $Qty, 82 $Descr, 83 $LongDescr, 84 $Price, 85 $Disc=0, 86 $UOM, 87 $Volume, 88 $Weight, 89 $QOHatLoc=0, 90 $MBflag='B', 91 $ActDispatchDate=NULL, 92 $QtyInvoiced=0, 93 $DiscCat='', 94 $Controlled=0, 95 $Serialised=0, 96 $DecimalPlaces=0, 97 $Narrative='', 98 $UpdateDB='No', 99 $LineNumber=-1, 100 $TaxCategory=0, 101 $vtigerProductID='', 102 $ItemDue = '', 103 $POLine='', 104 $StandardCost=0, 105 $EOQ=1, 106 $NextSerialNo=0, 107 $ExRate=1, 108 $identifier=0){ 109 110 if (isset($StockID) AND $StockID!="" AND $Qty>0 AND isset($Qty)){ 111 112 if ($Price<0){ /*madness check - use a credit note to give money away!*/ 113 $Price=0; 114 } 115 116 if ($LineNumber==-1){ 117 $LineNumber = $this->LineCounter; 118 } 119 120 $this->LineItems[$LineNumber] = new LineDetails($LineNumber, 121 $StockID, 122 $Descr, 123 $LongDescr, 124 $Qty, 125 $Price, 126 $Disc, 127 $UOM, 128 $Volume, 129 $Weight, 130 $QOHatLoc, 131 $MBflag, 132 $ActDispatchDate, 133 $QtyInvoiced, 134 $DiscCat, 135 $Controlled, 136 $Serialised, 137 $DecimalPlaces, 138 $Narrative, 139 $TaxCategory, 140 $ItemDue, 141 $POLine, 142 $StandardCost, 143 $EOQ, 144 $NextSerialNo, 145 $ExRate); 146 $this->ItemsOrdered++; 147 148 if ($UpdateDB=='Yes'){ 149 /*ExistingOrder !=0 set means that an order is selected or created for entry 150 of items - ExistingOrder is set to 0 in scripts that should not allow 151 adding items to the order - New orders have line items added at the time of 152 committing the order to the DB in DeliveryDetails.php 153 GET['ModifyOrderNumber'] is only set when the items are first 154 being retrieved from the DB - dont want to add them again - would return 155 errors anyway */ 156 157 $sql = "INSERT INTO salesorderdetails (orderlineno, 158 orderno, 159 stkcode, 160 quantity, 161 unitprice, 162 discountpercent, 163 itemdue, 164 poline) 165 VALUES(" . $LineNumber . ", 166 " . $_SESSION['ExistingOrder' . $identifier] . ", 167 '" . trim(mb_strtoupper($StockID)) ."', 168 " . $Qty . ", 169 " . $Price . ", 170 " . $Disc . ",' 171 " . FormatDateForSQL($ItemDue) . "', 172 " . $POLine . ")"; 173 $result = DB_query($sql, 174 _('The order line for') . ' ' . mb_strtoupper($StockID) . ' ' ._('could not be inserted')); 175 } 176 177 $this->LineCounter = $LineNumber + 1; 178 Return 1; 179 } 180 Return 0; 181 } 182 183 function update_cart_item( $UpdateLineNumber, 184 $Qty, 185 $Price, 186 $Disc, 187 $Narrative, 188 $UpdateDB='No', 189 $ItemDue, 190 $POLine, 191 $GPPercent, 192 $identifier){ 193 194 if ($Qty>0){ 195 $this->LineItems[$UpdateLineNumber]->Quantity = $Qty; 196 } 197 $this->LineItems[$UpdateLineNumber]->Price = $Price; 198 $this->LineItems[$UpdateLineNumber]->DiscountPercent = $Disc; 199 $this->LineItems[$UpdateLineNumber]->Narrative = $Narrative; 200 $this->LineItems[$UpdateLineNumber]->ItemDue = $ItemDue; 201 $this->LineItems[$UpdateLineNumber]->POLine = $POLine; 202 $this->LineItems[$UpdateLineNumber]->GPPercent = $GPPercent; 203 if ($UpdateDB=='Yes'){ 204 $result = DB_query("UPDATE salesorderdetails SET quantity=" . $Qty . ", 205 unitprice=" . $Price . ", 206 discountpercent=" . $Disc . ", 207 narrative ='" . $Narrative . "', 208 itemdue = '" . FormatDateForSQL($ItemDue) . "', 209 poline = '" . $POLine . "' 210 WHERE orderno=" . $_SESSION['ExistingOrder'.$identifier] . " 211 AND orderlineno=" . $UpdateLineNumber, 212 _('The order line number') . ' ' . $UpdateLineNumber . ' ' . _('could not be updated')); 213 } 214 } 215 216 function remove_from_cart($LineNumber, $UpdateDB='No', $identifier=0){ 217 218 if (!isset($LineNumber) OR $LineNumber=='' OR $LineNumber < 0){ /* over check it */ 219 prnMsg(_('No Line Number passed to remove_from_cart, so nothing has been removed.'), 'error'); 220 return; 221 } 222 if ($UpdateDB=='Yes'){ 223 if ($this->Some_Already_Delivered($LineNumber)==0){ 224 /* nothing has been delivered, delete it. */ 225 $result = DB_query("DELETE FROM salesorderdetails 226 WHERE orderno='" . $_SESSION['ExistingOrder' . $identifier] . "' 227 AND orderlineno='" . $LineNumber . "'", 228 _('The order line could not be deleted because') 229 ); 230 prnMsg( _('Deleted Line Number'). ' ' . $LineNumber . ' ' . _('from existing Order Number').' ' . $_SESSION['ExistingOrder' . $identifier], 'success'); 231 } else { 232 /* something has been delivered. Clear the remaining Qty and Mark Completed */ 233 $result = DB_query("UPDATE salesorderdetails SET quantity=qtyinvoiced, 234 completed=1 235 WHERE orderno='" . $_SESSION['ExistingOrder' . $identifier] ."' 236 AND orderlineno='" . $LineNumber . "'" , 237 _('The order line could not be updated as completed because') 238 ); 239 prnMsg(_('Removed Remaining Quantity and set Line Number '). ' ' . $LineNumber . ' ' . _('as Completed for existing Order Number').' ' . $_SESSION['ExistingOrder'], 'success'); 240 } 241 } 242 /* Since we need to check the LineItem above and might affect the DB, don't unset until after DB is updates occur */ 243 $this->CreditAvailable += ($this->LineItems[$LineNumber]->Quantity*$this->LineItems[$LineNumber]->Price*(1-$this->LineItems[$LineNumber]->DiscountPercent)); 244 unset($this->LineItems[$LineNumber]); 245 $this->ItemsOrdered--; 246 247 }//remove_from_cart() 248 249 function Get_StockID_List(){ 250 /* Makes a comma seperated list of the stock items ordered 251 for use in SQL expressions */ 252 253 $StockID_List=''; 254 foreach ($this->LineItems as $StockItem) { 255 $StockID_List .= ",'" . $StockItem->StockID . "'"; 256 } 257 258 return mb_substr($StockID_List, 1); 259 260 } 261 262 function Any_Already_Delivered(){ 263 /* Checks if there have been deliveries of line items */ 264 265 foreach ($this->LineItems as $StockItem) { 266 if ($StockItem->QtyInv !=0){ 267 return 1; 268 } 269 } 270 271 return 0; 272 273 } 274 275 function Some_Already_Delivered($LineNumber){ 276 /* Checks if there have been deliveries of a specific line item */ 277 278 if ($this->LineItems[$LineNumber]->QtyInv !=0){ 279 return $this->LineItems[$LineNumber]->QtyInv; 280 } 281 return 0; 282 } 283 284 function AllDummyLineItems(){ 285 foreach ($this->LineItems as $StockItem) { 286 if($StockItem->MBflag !='D'){ 287 return false; 288 } 289 } 290 return true; 291 } 292 293 function GetExistingTaxes($LineNumber, $stkmoveno){ 294 /*Gets the Taxes and rates applicable to this line from the TaxGroup of the branch and TaxCategory of the item 295 and the taxprovince of the dispatch location */ 296 297 $sql = "SELECT stockmovestaxes.taxauthid, 298 taxauthorities.description, 299 taxauthorities.taxglcode, 300 stockmovestaxes.taxcalculationorder, 301 stockmovestaxes.taxontax, 302 stockmovestaxes.taxrate 303 FROM stockmovestaxes INNER JOIN taxauthorities 304 ON stockmovestaxes.taxauthid = taxauthorities.taxid 305 WHERE stkmoveno = '" . $stkmoveno . "' 306 ORDER BY taxcalculationorder"; 307 308 $ErrMsg = _('The taxes and rates for this item could not be retrieved because'); 309 $GetTaxRatesResult = DB_query($sql,$ErrMsg); 310 $i=1; 311 while ($myrow = DB_fetch_array($GetTaxRatesResult)){ 312 313 $this->LineItems[$LineNumber]->Taxes[$i] = new Tax($myrow['taxcalculationorder'], 314 $myrow['taxauthid'], 315 $myrow['description'], 316 $myrow['taxrate'], 317 $myrow['taxontax'], 318 $myrow['taxglcode']); 319 $i++; 320 } 321 } //end method GetExistingTaxes 322 323 function GetTaxes($LineNumber){ 324 /*Gets the Taxes and rates applicable to this line from the TaxGroup of the branch and TaxCategory of the item 325 and the taxprovince of the dispatch location */ 326 327 $SQL = "SELECT taxgrouptaxes.calculationorder, 328 taxauthorities.description, 329 taxgrouptaxes.taxauthid, 330 taxauthorities.taxglcode, 331 taxgrouptaxes.taxontax, 332 taxauthrates.taxrate 333 FROM taxauthrates INNER JOIN taxgrouptaxes ON 334 taxauthrates.taxauthority=taxgrouptaxes.taxauthid 335 INNER JOIN taxauthorities ON 336 taxauthrates.taxauthority=taxauthorities.taxid 337 WHERE taxgrouptaxes.taxgroupid=" . $this->TaxGroup . " 338 AND taxauthrates.dispatchtaxprovince=" . $this->DispatchTaxProvince . " 339 AND taxauthrates.taxcatid = " . $this->LineItems[$LineNumber]->TaxCategory . " 340 ORDER BY taxgrouptaxes.calculationorder"; 341 342 $ErrMsg = _('The taxes and rates for this item could not be retrieved because'); 343 $GetTaxRatesResult = DB_query($SQL,$ErrMsg); 344 unset($this->LineItems[$LineNumber]->Taxes); 345 if (DB_num_rows($GetTaxRatesResult)==0){ 346 prnMsg(_('It appears that taxes are not defined correctly for this customer tax group') ,'error'); 347 } else { 348 $i=1; 349 while ($myrow = DB_fetch_array($GetTaxRatesResult)){ 350 $this->LineItems[$LineNumber]->Taxes[$i] = new Tax($myrow['calculationorder'], 351 $myrow['taxauthid'], 352 $myrow['description'], 353 $myrow['taxrate'], 354 $myrow['taxontax'], 355 $myrow['taxglcode']); 356 $i++; 357 } //end loop around different taxes 358 } //end if there are some taxes defined 359 } //end method GetTaxes 360 361 function GetFreightTaxes () { 362 /*Gets the Taxes and rates applicable to the freight based on the tax group of the branch combined with the tax category for this particular freight 363 and SESSION['FreightTaxCategory'] the taxprovince of the dispatch location */ 364 365 $sql = "SELECT taxcatid FROM taxcategories WHERE taxcatname='Freight'";// This tax category is hardcoded inside the database. 366 $TaxCatQuery = DB_query($sql); 367 368 if ($TaxCatRow = DB_fetch_array($TaxCatQuery)) { 369 $TaxCatID = $TaxCatRow['taxcatid']; 370 } else { 371 prnMsg( _('Cannot find tax category Freight which must always be defined'),'error'); 372 exit(); 373 } 374 375 $SQL = "SELECT taxgrouptaxes.calculationorder, 376 taxauthorities.description, 377 taxgrouptaxes.taxauthid, 378 taxauthorities.taxglcode, 379 taxgrouptaxes.taxontax, 380 taxauthrates.taxrate 381 FROM taxauthrates INNER JOIN taxgrouptaxes ON 382 taxauthrates.taxauthority=taxgrouptaxes.taxauthid 383 INNER JOIN taxauthorities ON 384 taxauthrates.taxauthority=taxauthorities.taxid 385 WHERE taxgrouptaxes.taxgroupid='" . $this->TaxGroup . "' 386 AND taxauthrates.dispatchtaxprovince='" . $this->DispatchTaxProvince . "' 387 AND taxauthrates.taxcatid = '" . $TaxCatID . "' 388 ORDER BY taxgrouptaxes.calculationorder"; 389 390 $ErrMsg = _('The taxes and rates for this item could not be retrieved because'); 391 $GetTaxRatesResult = DB_query($SQL,$ErrMsg); 392 $i=1; 393 while ($myrow = DB_fetch_array($GetTaxRatesResult)){ 394 395 $this->FreightTaxes[$i] = new Tax($myrow['calculationorder'], 396 $myrow['taxauthid'], 397 $myrow['description'], 398 $myrow['taxrate'], 399 $myrow['taxontax'], 400 $myrow['taxglcode']); 401 $i++; 402 } 403 } //end method GetFreightTaxes() 404 405} /* end of cart class defintion */ 406 407Class LineDetails { 408 Var $LineNumber; 409 Var $StockID; 410 Var $ItemDescription; 411 Var $LongDescription; 412 Var $Quantity; 413 Var $Price; 414 Var $DiscountPercent; 415 Var $Units; 416 Var $Volume; 417 Var $Weight; 418 Var $ActDispDate; 419 Var $QtyInv; 420 Var $QtyDispatched; 421 Var $StandardCost; 422 Var $QOHatLoc; 423 Var $MBflag; /*Make Buy Dummy, Assembly or Kitset */ 424 Var $DiscCat; /* Discount Category of the item if any */ 425 Var $Controlled; 426 Var $Serialised; 427 Var $DecimalPlaces; 428 Var $SerialItems; 429 Var $Narrative; 430 Var $TaxCategory; 431 Var $Taxes; 432 Var $WorkOrderNo; 433 Var $ItemDue; 434 Var $POLine; 435 Var $EOQ; 436 Var $NextSerialNo; 437 Var $GPPercent; 438 439 function __construct ($LineNumber, 440 $StockItem, 441 $Descr, 442 $LongDescr, 443 $Qty, 444 $Prc, 445 $DiscPercent, 446 $UOM, 447 $Volume, 448 $Weight, 449 $QOHatLoc, 450 $MBflag, 451 $ActDispatchDate, 452 $QtyInvoiced, 453 $DiscCat, 454 $Controlled, 455 $Serialised, 456 $DecimalPlaces, 457 $Narrative, 458 $TaxCategory, 459 $ItemDue, 460 $POLine, 461 $StandardCost, 462 $EOQ, 463 $NextSerialNo, 464 $ExRate ){ 465 466/* Constructor function to add a new LineDetail object with passed params */ 467 $this->LineNumber = $LineNumber; 468 $this->StockID =$StockItem; 469 $this->ItemDescription = $Descr; 470 $this->LongDescription = $LongDescr; 471 $this->Quantity = $Qty; 472 $this->Price = $Prc; 473 $this->DiscountPercent = $DiscPercent; 474 $this->Units = $UOM; 475 $this->Volume = $Volume; 476 $this->Weight = $Weight; 477 $this->ActDispDate = $ActDispatchDate; 478 $this->QtyInv = $QtyInvoiced; 479 if ($Controlled==1){ 480 $this->QtyDispatched = 0; 481 } else { 482 if ($_SESSION['InvoiceQuantityDefault']==1){ 483 $this->QtyDispatched = $Qty - $QtyInvoiced; 484 } else { 485 $this->QtyDispathced = 0; 486 } 487 } 488 $this->QOHatLoc = $QOHatLoc; 489 $this->MBflag = $MBflag; 490 $this->DiscCat = $DiscCat; 491 $this->Controlled = $Controlled; 492 $this->Serialised = $Serialised; 493 $this->DecimalPlaces = $DecimalPlaces; 494 $this->SerialItems = array(); 495 $this->Narrative = $Narrative; 496 $this->Taxes = array(); 497 $this->TaxCategory = $TaxCategory; 498 $this->WorkOrderNo = 0; 499 $this->ItemDue = $ItemDue; 500 $this->POLine = $POLine; 501 $this->StandardCost = $StandardCost; 502 $this->EOQ = $EOQ; 503 $this->NextSerialNo = $NextSerialNo; 504 505 if ($Prc > 0){ 506 $this->GPPercent = ((($Prc * (1 - $DiscPercent)) - ($StandardCost * $ExRate))*100)/$Prc; 507 } else { 508 $this->GPPercent = 0; 509 } 510 } //end constructor function for LineDetails 511 512 function LineDetails($LineNumber, 513 $StockItem, 514 $Descr, 515 $LongDescr, 516 $Qty, 517 $Prc, 518 $DiscPercent, 519 $UOM, 520 $Volume, 521 $Weight, 522 $QOHatLoc, 523 $MBflag, 524 $ActDispatchDate, 525 $QtyInvoiced, 526 $DiscCat, 527 $Controlled, 528 $Serialised, 529 $DecimalPlaces, 530 $Narrative, 531 $TaxCategory, 532 $ItemDue, 533 $POLine, 534 $StandardCost, 535 $EOQ, 536 $NextSerialNo, 537 $ExRate ) { 538 self::__construct($LineNumber, 539 $StockItem, 540 $Descr, 541 $LongDescr, 542 $Qty, 543 $Prc, 544 $DiscPercent, 545 $UOM, 546 $Volume, 547 $Weight, 548 $QOHatLoc, 549 $MBflag, 550 $ActDispatchDate, 551 $QtyInvoiced, 552 $DiscCat, 553 $Controlled, 554 $Serialised, 555 $DecimalPlaces, 556 $Narrative, 557 $TaxCategory, 558 $ItemDue, 559 $POLine, 560 $StandardCost, 561 $EOQ, 562 $NextSerialNo, 563 $ExRate ); 564 } 565 566} 567 568Class Tax { 569 Var $TaxCalculationOrder; /*the index for the array */ 570 Var $TaxAuthID; 571 Var $TaxAuthDescription; 572 Var $TaxRate; 573 Var $TaxOnTax; 574 var $TaxGLCode; 575 576 function __construct ($TaxCalculationOrder, 577 $TaxAuthID, 578 $TaxAuthDescription, 579 $TaxRate, 580 $TaxOnTax, 581 $TaxGLCode){ 582 583 $this->TaxCalculationOrder = $TaxCalculationOrder; 584 $this->TaxAuthID = $TaxAuthID; 585 $this->TaxAuthDescription = $TaxAuthDescription; 586 $this->TaxRate = $TaxRate; 587 $this->TaxOnTax = $TaxOnTax; 588 $this->TaxGLCode = $TaxGLCode; 589 } 590 function Tax ($TaxCalculationOrder, 591 $TaxAuthID, 592 $TaxAuthDescription, 593 $TaxRate, 594 $TaxOnTax, 595 $TaxGLCode) { 596 597 self::__construct($TaxCalculationOrder, 598 $TaxAuthID, 599 $TaxAuthDescription, 600 $TaxRate, 601 $TaxOnTax, 602 $TaxGLCode); 603 } 604} 605 606?> 607