diff --git a/classes/order/OrderHistory.php b/classes/order/OrderHistory.php index dbdc07049..e97422fb7 100644 --- a/classes/order/OrderHistory.php +++ b/classes/order/OrderHistory.php @@ -89,7 +89,7 @@ class OrderHistoryCore extends ObjectModel if ($newOS->logable AND (!$oldOrderStatus OR !$oldOrderStatus->logable)) { ProductSale::addProductSale($product['id_product'], $product['cart_quantity']); - StockAvailable::updateQuantity($product['id_product'], $product['id_product_attribute'], -(int)$product['cart_quantity']); + } /* If becoming unlogable => removing sale */ elseif (!$newOS->logable AND ($oldOrderStatus AND $oldOrderStatus->logable)) @@ -100,20 +100,41 @@ class OrderHistoryCore extends ObjectModel // If order is shipped for the first time and // if we use advanced stock management system, decrement stock preperly. // The product is removed from the physical stock. $id_warehouse is needed + // @TODO Checks $id_warehouse else if ($newOS->shipped == 1 && $oldOrderStatus->shipped == 0 && Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) { $manager = StockManagerFactory::getManager(); $warehouse = new Warehouse($id_warehouse); - $manager->removeProduct($product['id_product'], - $product['id_product_attribute'], - $warehouse, - $product['cart_quantity'], - Configuration::get('PS_STOCK_CUSTOMER_ORDER_REASON'), - true, - (int)$id_order); + $manager->removeProduct( + $product['id_product'], + $product['id_product_attribute'], + $warehouse, + $product['cart_quantity'], + Configuration::get('PS_STOCK_CUSTOMER_ORDER_REASON'), + true, + (int)$id_order + ); + } + else if ($newOS->shipped == 0 && $oldOrderStatus->shipped == 1 && Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) + { + $manager = StockManagerFactory::getManager(); + $warehouse = new Warehouse($id_warehouse); + + $mvts = StockMvt::getNegativeStockMvts($order->id, $product['id_product'], $product['id_product_attribute'], $product['cart_quantity']); + foreach ($mvts as $mvt) + { + $manager->addProduct( + $product['id_product'], + $product['id_product_attribute'], + new Warehouse($mvt['id_warehouse']), + $mvt['physical_quantity'], + null, + $mvt['price_te'], + true + ); + } } - // @todo If the old order states was "shipped" and the new is "not shipped" the stock is not decremented } $this->id_order_state = (int)($new_order_state); diff --git a/classes/stock/StockMvt.php b/classes/stock/StockMvt.php index 23811a48e..05dc90241 100644 --- a/classes/stock/StockMvt.php +++ b/classes/stock/StockMvt.php @@ -194,4 +194,40 @@ class StockMvtCore extends ObjectModel { Tools::displayAsDeprecated(); } + + /** + * Gets the negative stock mvts that corresponds to the given order, for the given product, in the given quantity + * + * @since 1.5.0 + * @param int $id_order + * @param int $id_product + * @param int $id_product_attribute + * @param int $quantity + * @return Array mvts + */ + public static function getNegativeStockMvts($id_order, $id_product, $id_product_attribute, $quantity) + { + $mvts = array(); + $quantity_total = 0; + + $query = new DbQuery(); + $query->select('sm.*, s.id_warehouse'); + $query->from('stock_mvt sm'); + $query->innerJoin('stock s ON (s.id_stock = sm.id_stock)'); + $query->where('sm.sign = -1'); + $query->where('sm.id_order = '.(int)$id_order); + $query->where('s.id_product = '.(int)$id_product.' AND s.id_product_attribute = '.(int)$id_product_attribute); + $query->orderBy('date_add DESC'); + + $res = Db::getInstance(_PS_USE_SQL_SLAVE_)->query($query); + while ($row = Db::getInstance(_PS_USE_SQL_SLAVE_)->nextRow($res)) + { + if ($quantity_total >= $quantity) + break; + $quantity_total += (int)$row['physical_quantity']; + $mvts[] = $row; + } + + return $mvts; + } } \ No newline at end of file diff --git a/controllers/admin/AdminOrdersController.php b/controllers/admin/AdminOrdersController.php index f4d1a6ec7..a01daef8d 100755 --- a/controllers/admin/AdminOrdersController.php +++ b/controllers/admin/AdminOrdersController.php @@ -441,22 +441,24 @@ class AdminOrdersControllerCore extends AdminController $product_to_inject = new Product($order_detail->product_id, false, $this->context->language->id, $order->id_shop); if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && $order_detail->id_warehouse != 0) { - $id_supplier = $product_to_inject->id_supplier; - $price = ProductSupplier::getProductPrice($id_supplier, $order_detail->product_id, $order_detail->product_attribute_id); - $price_te = $price['price_te']; - $id_currency = $price['id_currency']; - $warehouse = new Warehouse($id_warehouse); + $mvts = StockMvt::getNegativeStockMvts( + $order_detail->id_order, + $order_detail->product_id, + $order_detail->product_attribute_id, + $quantity_to_reinject); - $price_te = Tools::convertPriceFull($price_te, $from = new Currency($id_currency), $to = new Currency($warehouse->id_currency)); - - $stock_manager = StockManagerFactory::getManager(); - $stock_manager->addProduct($qty_cancel_product->product_id, - $qty_cancel_product->product_attribute_id, - $warehouse, - $quantity_to_reinject, - null, - $price_te, - true); + foreach ($mvts as $mvt) + { + $manager->addProduct( + $order_detail->product_id, + $order_detail->product_attribute_id, + new Warehouse($mvt['id_warehouse']), + $mvt['physical_quantity'], + null, + $mvt['price_te'], + true + ); + } StockAvailable::synchronize($order_detail->product_id); } else if ($order_detail->id_warehouse == 0)