00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 class Mage_CatalogInventory_Model_Stock_Item extends Mage_Core_Model_Abstract
00036 {
00037 const XML_PATH_GLOBAL = 'cataloginventory/options/';
00038 const XML_PATH_CAN_SUBTRACT = 'cataloginventory/options/can_subtract';
00039 const XML_PATH_CAN_BACK_IN_STOCK = 'cataloginventory/options/can_back_in_stock';
00040
00041 const XML_PATH_ITEM = 'cataloginventory/item_options/';
00042 const XML_PATH_MIN_QTY = 'cataloginventory/item_options/min_qty';
00043 const XML_PATH_MIN_SALE_QTY = 'cataloginventory/item_options/min_sale_qty';
00044 const XML_PATH_MAX_SALE_QTY = 'cataloginventory/item_options/max_sale_qty';
00045 const XML_PATH_BACKORDERS = 'cataloginventory/item_options/backorders';
00046 const XML_PATH_NOTIFY_STOCK_QTY = 'cataloginventory/item_options/notify_stock_qty';
00047 const XML_PATH_MANAGE_STOCK = 'cataloginventory/item_options/manage_stock';
00048
00049
00050
00051
00052
00053
00054
00055 protected function _construct()
00056 {
00057 $this->_init('cataloginventory/stock_item');
00058 }
00059
00060
00061
00062
00063
00064
00065
00066 public function getStockId()
00067 {
00068 return 1;
00069 }
00070
00071
00072
00073
00074
00075
00076 public function getProductId()
00077 {
00078 return $this->_getData('product_id');
00079 }
00080
00081
00082
00083
00084
00085
00086
00087 public function loadByProduct($product)
00088 {
00089 if ($product instanceof Mage_Catalog_Model_Product) {
00090 $product = $product->getId();
00091 }
00092 $this->_getResource()->loadByProductId($this, $product);
00093 $this->setOrigData();
00094 return $this;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103 public function subtractQty($qty)
00104 {
00105 if (!$this->getManageStock()) {
00106 return $this;
00107 }
00108 $config = Mage::getStoreConfigFlag(self::XML_PATH_CAN_SUBTRACT);
00109 if (!$config) {
00110 return $this;
00111 }
00112 $this->setQty($this->getQty()-$qty);
00113 return $this;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122 public function addQty($qty)
00123 {
00124 if (!$this->getManageStock()) {
00125 return $this;
00126 }
00127 $config = Mage::getStoreConfigFlag(self::XML_PATH_CAN_SUBTRACT);
00128 if (!$config) {
00129 return $this;
00130 }
00131
00132 $this->setQty($this->getQty()+$qty);
00133 return $this;
00134 }
00135
00136
00137
00138
00139
00140
00141 public function getStoreId()
00142 {
00143 $storeId = $this->getData('store_id');
00144 if (is_null($storeId)) {
00145 $storeId = Mage::app()->getStore()->getId();
00146 $this->setData('store_id', $storeId);
00147 }
00148 return $storeId;
00149 }
00150
00151
00152
00153
00154
00155
00156
00157 public function assignProduct(Mage_Catalog_Model_Product $product)
00158 {
00159 if (!$this->getId() || !$this->getProductId()) {
00160 $this->_getResource()->loadByProductId($this, $product->getId());
00161 $this->setOrigData();
00162 }
00163
00164 $this->setProduct($product);
00165 $product->setStockItem($this);
00166
00167 $product->setIsInStock($this->getIsInStock());
00168 Mage::getSingleton('cataloginventory/stock_status')
00169 ->assignProduct($product, $this->getStockId(), $this->getStockStatus());
00170 return $this;
00171 }
00172
00173
00174
00175
00176
00177
00178 public function getMinQty()
00179 {
00180 if ($this->getUseConfigMinQty()) {
00181 return (float) Mage::getStoreConfig(self::XML_PATH_MIN_QTY);
00182 }
00183 return $this->getData('min_qty');
00184 }
00185
00186
00187
00188
00189
00190
00191 public function getMinSaleQty()
00192 {
00193 if ($this->getUseConfigMinSaleQty()) {
00194 return (float) Mage::getStoreConfig(self::XML_PATH_MIN_SALE_QTY);
00195 }
00196 return $this->getData('min_sale_qty');
00197 }
00198
00199
00200
00201
00202
00203
00204 public function getMaxSaleQty()
00205 {
00206 if ($this->getUseConfigMaxSaleQty()) {
00207 return (float) Mage::getStoreConfig(self::XML_PATH_MAX_SALE_QTY);
00208 }
00209 return $this->getData('max_sale_qty');
00210 }
00211
00212
00213
00214
00215
00216
00217 public function getNotifyStockQty()
00218 {
00219 if ($this->getUseConfigNotifyStockQty()) {
00220 return (float) Mage::getStoreConfig(self::XML_PATH_NOTIFY_STOCK_QTY);
00221 }
00222 return (float)$this->getData('notify_stock_qty');
00223 }
00224
00225
00226
00227
00228
00229
00230 public function getBackorders()
00231 {
00232 if ($this->getUseConfigBackorders()) {
00233 return (int) Mage::getStoreConfig(self::XML_PATH_BACKORDERS);
00234 }
00235 return $this->getData('backorders');
00236 }
00237
00238
00239
00240
00241
00242
00243 public function getManageStock()
00244 {
00245 if ($this->getUseConfigManageStock()) {
00246 return (int) Mage::getStoreConfigFlag(self::XML_PATH_MANAGE_STOCK);
00247 }
00248 return $this->getData('manage_stock');
00249 }
00250
00251
00252
00253
00254
00255
00256 public function getCanBackInStock()
00257 {
00258 return Mage::getStoreConfigFlag(self::XML_PATH_CAN_BACK_IN_STOCK);
00259 }
00260
00261
00262
00263
00264
00265
00266
00267
00268 public function checkQty($qty)
00269 {
00270 if ($this->getQty() - $qty < 0) {
00271 switch ($this->getBackorders()) {
00272 case Mage_CatalogInventory_Model_Stock::BACKORDERS_YES_NONOTIFY:
00273 case Mage_CatalogInventory_Model_Stock::BACKORDERS_YES_NOTIFY:
00274 break;
00275 default:
00276
00277
00278
00279
00280
00281
00282
00283
00284 return false;
00285 break;
00286 }
00287 }
00288 return true;
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 public function checkQuoteItemQty($qty, $summaryQty, $origQty = 0)
00300 {
00301 $result = new Varien_Object();
00302 $result->setHasError(false);
00303
00304 if (!is_numeric($qty)) {
00305 $qty = Mage::app()->getLocale()->getNumber($qty);
00306 }
00307
00308
00309
00310
00311 $result->setItemIsQtyDecimal($this->getIsQtyDecimal());
00312
00313 if (!$this->getIsQtyDecimal()) {
00314 $result->setHasQtyOptionUpdate(true);
00315 $qty = intval($qty);
00316
00317
00318
00319
00320 $result->setItemQty($qty);
00321
00322 if (!is_numeric($qty)) {
00323 $qty = Mage::app()->getLocale()->getNumber($qty);
00324 }
00325 $origQty = intval($origQty);
00326 $result->setOrigQty($origQty);
00327 }
00328
00329 if ($this->getMinSaleQty() && ($qty) < $this->getMinSaleQty()) {
00330 $result->setHasError(true)
00331 ->setMessage(Mage::helper('cataloginventory')->__('The minimum quantity allowed for purchase is %s.', $this->getMinSaleQty() * 1))
00332 ->setQuoteMessage(Mage::helper('cataloginventory')->__('Some of the products cannot be ordered in the requested quantity'))
00333 ->setQuoteMessageIndex('qty');
00334 return $result;
00335 }
00336
00337 if ($this->getMaxSaleQty() && ($qty) > $this->getMaxSaleQty()) {
00338 $result->setHasError(true)
00339 ->setMessage(Mage::helper('cataloginventory')->__('The maximum quantity allowed for purchase is %s.', $this->getMaxSaleQty() * 1))
00340 ->setQuoteMessage(Mage::helper('cataloginventory')->__('Some of the products can not be ordered in requested quantity'))
00341 ->setQuoteMessageIndex('qty');
00342 return $result;
00343 }
00344
00345 if (!$this->getManageStock()) {
00346 return $result;
00347 }
00348
00349 if (!$this->getIsInStock()) {
00350 $result->setHasError(true)
00351 ->setMessage(Mage::helper('cataloginventory')->__('This product is currently out of stock.'))
00352 ->setQuoteMessage(Mage::helper('cataloginventory')->__('Some of the products are currently out of stock'))
00353 ->setQuoteMessageIndex('stock');
00354 $result->setItemUseOldQty(true);
00355 return $result;
00356 }
00357
00358 if (!$this->checkQty($summaryQty)) {
00359 $message = Mage::helper('cataloginventory')->__('The requested quantity for "%s" is not available.', $this->getProductName());
00360 $result->setHasError(true)
00361 ->setMessage($message)
00362 ->setQuoteMessage($message)
00363 ->setQuoteMessageIndex('qty');
00364 return $result;
00365 }
00366 else {
00367 if (($this->getQty() - $summaryQty) < 0) {
00368 if ($this->getProductName()) {
00369 $backorderQty = ($this->getQty() > 0) ? ($summaryQty - $this->getQty()) * 1 : $qty * 1;
00370 if ($backorderQty>$qty) {
00371 $backorderQty = $qty;
00372 }
00373 $result->setItemBackorders($backorderQty);
00374 if ($this->getBackorders() == Mage_CatalogInventory_Model_Stock::BACKORDERS_YES_NOTIFY) {
00375 $result->setMessage(Mage::helper('cataloginventory')->__('This product is not available in the requested quantity. %d of the items will be backordered.',
00376 $backorderQty,
00377 $this->getProductName())
00378 )
00379 ;
00380 }
00381 }
00382 }
00383
00384 }
00385
00386 return $result;
00387 }
00388
00389
00390
00391
00392
00393
00394
00395 public function addCatalogInventoryToProductCollection($productCollection)
00396 {
00397 $this->_getResource()->addCatalogInventoryToProductCollection($productCollection);
00398 return $this;
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 protected function _addQuoteItemError(Mage_Sales_Model_Quote_Item $item, $itemError, $quoteError, $errorIndex='error')
00411 {
00412 $item->setHasError(true);
00413 $item->setMessage($itemError);
00414 $item->setQuoteMessage($quoteError);
00415 $item->setQuoteMessageIndex($errorIndex);
00416 return $this;
00417 }
00418
00419
00420
00421
00422
00423
00424 protected function _beforeSave()
00425 {
00426
00427 $typeId = $this->getTypeId();
00428 if ($productTypeId = $this->getProductTypeId()) {
00429 $typeId = $productTypeId;
00430 }
00431 $isQty = Mage::helper('catalogInventory')->isQty($typeId);
00432
00433 if ($isQty) {
00434 if ($this->getBackorders() == Mage_CatalogInventory_Model_Stock::BACKORDERS_NO
00435 && $this->getQty() <= $this->getMinQty()) {
00436 $this->setIsInStock(false)
00437 ->setStockStatusChangedAutomaticallyFlag(true);
00438 }
00439
00440
00441 $this->setLowStockDate(null);
00442 if ((float)$this->getQty() < $this->getNotifyStockQty()) {
00443 $this->setLowStockDate(Mage::app()->getLocale()->date(null, null, null, false)
00444 ->toString(Varien_Date::DATETIME_INTERNAL_FORMAT)
00445 );
00446 }
00447
00448 $this->setStockStatusChangedAutomatically(0);
00449 if ($this->hasStockStatusChangedAutomaticallyFlag()) {
00450 $this->setStockStatusChangedAutomatically((int)$this->getStockStatusChangedAutomaticallyFlag());
00451 }
00452 }
00453 else {
00454 $this->setQty(0);
00455 }
00456
00457 Mage::dispatchEvent('cataloginventory_stock_item_save_before', array('item' => $this));
00458 return $this;
00459 }
00460
00461
00462
00463
00464
00465
00466 protected function _afterSave()
00467 {
00468 parent::_afterSave();
00469 Mage::getSingleton('cataloginventory/stock_status')
00470 ->changeItemStatus($this);
00471 return $this;
00472 }
00473
00474
00475
00476
00477
00478
00479 public function getIsInStock()
00480 {
00481 if (!$this->getManageStock()) {
00482 return true;
00483 }
00484 return $this->_getData('is_in_stock');
00485 }
00486
00487
00488
00489
00490
00491
00492
00493 public function setProduct($product)
00494 {
00495 $this->setProductId($product->getId())
00496 ->setProductName($product->getName())
00497 ->setStoreId($product->getStoreId())
00498 ->setProductName($product->getName())
00499 ->setProductTypeId($product->getTypeId())
00500 ->setProductStatusChanged($product->dataHasChangedFor('status'))
00501 ->setProductChangedWebsites($product->getIsChangedWebsites());
00502
00503 return $this;
00504 }
00505 }