Reputation: 23
I'm totally new in PrestaShop. I'm stuck with an issue, can't find in code where PrestaShop subtracts items from stock.
When customer create an order and choose payment, item is subtract from stock, but if customer doesn't pay and go back, item doesn't return to stock. So I need to understand where it's happening in code, for to write function which does it automatically.
Upvotes: 2
Views: 1071
Reputation: 2987
In the PaymentModule::validateOrder
there is a call to the OrderDetail->createList
with:
// Insert new Order detail list using cart for the current order
$order_detail = new OrderDetail(null, null, $this->context);
$order_detail->createList($order, $this->context->cart, $id_order_state, $order->product_list, 0, true, $package_list[$id_address][$id_package]['id_warehouse']);
$order_detail_list[] = $order_detail;
In OrderDetail->createList
we have a call to $this->create
foreach product in the list. This is where that order detail data is "calculated", and there is a $this->checkProductStock($product, $id_order_state);
that checks if the order is not canceled and not an error and if that product depends on stock:
protected function checkProductStock($product, $id_order_state)
{
if ($id_order_state != Configuration::get('PS_OS_CANCELED') && $id_order_state != Configuration::get('PS_OS_ERROR')) {
$update_quantity = true;
if (!StockAvailable::dependsOnStock($product['id_product'])) {
$update_quantity = StockAvailable::updateQuantity($product['id_product'], $product['id_product_attribute'], -(int)$product['cart_quantity']);
}
if ($update_quantity) {
$product['stock_quantity'] -= $product['cart_quantity'];
}
if ($product['stock_quantity'] < 0 && Configuration::get('PS_STOCK_MANAGEMENT')) {
$this->outOfStock = true;
}
Product::updateDefaultAttribute($product['id_product']);
}
}
Btw, if you cancel an order, the stock is reset with that order amount.
But if you want to only decrease stock after payment, in your case I would add a config PS_WAITING_PAYMENT with the value the orders have if not confirmed, then override this last function to add the state awaiting payment
protected function checkProductStock($product, $id_order_state)
{
if ($id_order_state != Configuration::get('PS_OS_CANCELED') && $id_order_state != Configuration::get('PS_OS_ERROR') && $id_order_state != Configuration::get('PS_WAITING_PAYMENT')) {
$update_quantity = true;
if (!StockAvailable::dependsOnStock($product['id_product'])) {
$update_quantity = StockAvailable::updateQuantity($product['id_product'], $product['id_product_attribute'], -(int)$product['cart_quantity']);
}
if ($update_quantity) {
$product['stock_quantity'] -= $product['cart_quantity'];
}
if ($product['stock_quantity'] < 0 && Configuration::get('PS_STOCK_MANAGEMENT')) {
$this->outOfStock = true;
}
Product::updateDefaultAttribute($product['id_product']);
}
}
If you set the Waiting payment order state to not logable, and the new state is logable, when you change the state to confirmed payment it should decrease stock, because in OrderHistory->changeIdOrderState there is:
...
foreach ($order->getProductsDetail() as $product) {
if (Validate::isLoadedObject($old_os)) {
// if becoming logable => adds sale
if ($new_os->logable && !$old_os->logable) {
ProductSale::addProductSale($product['product_id'], $product['product_quantity']);
// @since 1.5.0 - Stock Management
if (!Pack::isPack($product['product_id']) &&
in_array($old_os->id, $error_or_canceled_statuses) &&
!StockAvailable::dependsOnStock($product['id_product'], (int)$order->id_shop)) {
StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], -(int)$product['product_quantity'], $order->id_shop);
}
}
...
Upvotes: 8