Author Topic: HOW is Stock Managed?  (Read 22183 times)

hellodave

  • Jr. Member
  • **
  • Posts: 100
Re: HOW is Stock Managed?
« Reply #30 on: May 29, 2009, 11:36:07 am »
Well I managed to get this working after a fashion.
I found 4 files where stock is adjusted -

ps_checkout.php
ps_order.php
ps_order_change.php
ps_order_edit.php

All are in -

\administrator\components\com_virtuemart\classes\

The last 2 are commented as - "...acts as a plugin for the order_print page"
so I have ignored them!

So in ps_checkout.php there is a function called "add" that "is the main function which stores the order information in the database."
Around line 1122 I found this -

Code: [Select]
// Update Stock Level and Product Sales, decrease - no matter if in stock or not!
$q = "UPDATE #__{vm}_product ";
$q .= "SET product_in_stock = product_in_stock - ".(int)$cart[$i]["quantity"];
$q .= " WHERE product_id = '" . $cart[$i]["product_id"]. "'";
$db->query($q);

$q = "UPDATE #__{vm}_product ";
$q .= "SET product_sales= product_sales + ".(int)$cart[$i]["quantity"];
$q .= " WHERE product_id='".$cart[$i]["product_id"]."'";
$db->query($q);

I commented the whole thing out, I don't want any stock adjusted here.

In ps_order.php there is a function called "order_status_update."
Around line 160 I found this -

Code: [Select]
// Do we need to re-update the Stock Level?
if( (strtoupper($d["order_status"]) == "X" || strtoupper($d["order_status"])=="R")
// && CHECK_STOCK == '1'
&& $curr_order_status != $d["order_status"]
) {
// Get the order items and update the stock level
// to the number before the order was placed
$q = "SELECT product_id, product_quantity FROM #__{vm}_order_item WHERE order_id='".$db->getEscaped($d["order_id"])."'";
$db->query( $q );
$dbu = new ps_DB;
// Now update each ordered product
while( $db->next_record() ) {
$q = "UPDATE #__{vm}_product SET product_in_stock=product_in_stock+".$db->f("product_quantity").", product_sales=product_sales-".$db->f("product_quantity")." WHERE product_id='".$db->f("product_id")."'";
$dbu->query( $q );
}
}

So this is restocking the item if the status is changed from anything to cancelled or refunded. Not really what I want so again I commented out the entire thing.
This is where I want the stock adjusted though so immediately after that I added this -

Code: [Select]
if( $curr_order_status!="C" && strtoupper($d["order_status"])=="C") { //going from anything to confirmed
$q = "SELECT product_id, product_quantity FROM #__{vm}_order_item WHERE order_id='".$db->getEscaped($d["order_id"])."'";
$db->query( $q );
$dbu = new ps_DB;
// Now update each ordered product
while( $db->next_record() ) {
$q = "UPDATE #__{vm}_product SET product_in_stock=product_in_stock-".$db->f("product_quantity").", product_sales=product_sales+".$db->f("product_quantity")." WHERE product_id='".$db->f("product_id")."'";
$dbu->query( $q );
}
}

This is reducing stock levels if the status is changed from anything to confirmed.

What has this achieved?
Now stock is only reduced when order status is changed to confirmed.
Stock is only increased when the order is removed from the system, on the order list page, select the order, click remove, stock is added back.
In reality, I don't think we will be removing orders to restock them, I think that will be done by hand.
This might prove problematic if we get a large number of orders, but Ill cross that bridge when I get to it.
There is only 1 of most of the items in my store so this works for me.

This does feel decidedly hacky, like I have probably missed something.
So feedback is welcome  8) Can you see any problems with what I've done?
currently working with -
Joomla 2.5.8
VM 2.0.18a

Lylene

  • Jr. Member
  • **
  • Posts: 118
Re: HOW is Stock Managed?
« Reply #31 on: January 06, 2010, 00:32:58 am »
hellodave

Thanks for this trick, this is what I was looking for !!!

Has anyone tested it yet ? :)

Thanks
Lylene

Lylene

  • Jr. Member
  • **
  • Posts: 118
Re: HOW is Stock Managed?
« Reply #32 on: February 23, 2010, 18:35:08 pm »
works great by the way :)

Sid.

  • Beginner
  • *
  • Posts: 42
    • SidFilmz
Re: HOW is Stock Managed?
« Reply #33 on: April 14, 2011, 01:28:26 am »
I know this is an old topic, but specifically related to what I want to know.

@hellodave -

Quote
Stock is only increased when the order is removed from the system, on the order list page, select the order, click remove, stock is added back.

I'm having an issue where my webstore client has unique 1-of-a-kind products. So each product has an inventory of '1' only, and once ordered, should not be available to other customers. When an Order is Pending, Confirmed, or Shipped - it should have inventory of '0' - and the default inventory stock reduction works well for this.  When the Order Status is Cancelled or Refunded, the item is added back into inventory by default. Again, this works for our needs.

However, when you Delete an Order - each product from that order is added back into Inventory.  My client deletes the Orders regularly, to protect customer data, and though I persuade them to Delete the Products associated with it at the same time, this isn't always performed in the right order.  

So, when orders started coming in for long-ago sold items, Virtuemart and myself each got our share of the blame (as I had made a few hacks & mods to their installation already). The advice from @hellodave above led me to the right area, but if you dig further into the code located in ps_order.php to around line 770 (VM 1.1.6) you will see the following code:

Code: [Select]
/**
* Deletes one Record.
*/
function delete_record( $record_id, &$d ) {
global $db;
$record_id = intval( $record_id );


if ($this->validate_delete($record_id)) {
$dbu = new ps_db();
// Get the order items and update the stock level
// to the number before the order was placed
$q = "SELECT order_status, product_id, product_quantity FROM #__{vm}_order_item WHERE order_id=$record_id";
$db->query( $q );
require_once( CLASSPATH .'ps_product.php' );
// Now update each ordered product
while( $db->next_record() ) {
if( in_array( $db->f('order_status'), array('P', 'X', 'R') )) continue;

if( ENABLE_DOWNLOADS == '1' && ps_product::is_downloadable($db->f("product_id")) && VM_DOWNLOADABLE_PRODUCTS_KEEP_STOCKLEVEL == '1') {
$q = "UPDATE #__{vm}_product  
SET product_sales=product_sales-".$db->f("product_quantity")."
WHERE product_id=".$db->f("product_id");
$dbu->query( $q );
}
else {
$q = "UPDATE #__{vm}_product
SET product_in_stock=product_in_stock+".$db->f("product_quantity").",
product_sales=product_sales-".$db->f("product_quantity")."
WHERE product_id=".$db->f("product_id");
$dbu->query( $q );
}
}

$q = "DELETE from #__{vm}_orders where order_id='$record_id'";
$db->query($q);

$q = "DELETE from #__{vm}_order_item where order_id='$record_id'";
$db->query($q);

$q = "DELETE from #__{vm}_order_payment where order_id='$record_id'";
$db->query($q);

$q = "DELETE from #__{vm}_product_download where order_id='$record_id'";
$db->query($q);

$q = "DELETE from #__{vm}_order_history where order_id='$record_id'";
$db->query($q);

$q = "DELETE from #__{vm}_order_user_info where order_id='$record_id'";
$db->query($q);

$q = "DELETE FROM #__{vm}_shipping_label where order_id=$record_id";
$db->query($q);

return True;
}
else {
return False;
}
}
/**

which I commented out around line 778 like so:

Code: [Select]
/**
* Deletes one Record.
*/
function delete_record( $record_id, &$d ) {
global $db;
$record_id = intval( $record_id );


if ($this->validate_delete($record_id)) {
/*** REMOVE UPDATE STOCK INVENTORY WHEN ORDER IS DELETED

$dbu = new ps_db();
// Get the order items and update the stock level
// to the number before the order was placed
$q = "SELECT order_status, product_id, product_quantity FROM #__{vm}_order_item WHERE order_id=$record_id";
$db->query( $q );
require_once( CLASSPATH .'ps_product.php' );
// Now update each ordered product
while( $db->next_record() ) {
if( in_array( $db->f('order_status'), array('P', 'X', 'R') )) continue;

if( ENABLE_DOWNLOADS == '1' && ps_product::is_downloadable($db->f("product_id")) && VM_DOWNLOADABLE_PRODUCTS_KEEP_STOCKLEVEL == '1') {
$q = "UPDATE #__{vm}_product  
SET product_sales=product_sales-".$db->f("product_quantity")."
WHERE product_id=".$db->f("product_id");
$dbu->query( $q );
}
else {
$q = "UPDATE #__{vm}_product
SET product_in_stock=product_in_stock+".$db->f("product_quantity").",
product_sales=product_sales-".$db->f("product_quantity")."
WHERE product_id=".$db->f("product_id");
$dbu->query( $q );
}
} END REMOVE UPDATE STOCK INVENTORY WHEN ORDER IS DELETED ***/

$q = "DELETE from #__{vm}_orders where order_id='$record_id'";
$db->query($q);

$q = "DELETE from #__{vm}_order_item where order_id='$record_id'";
$db->query($q);

$q = "DELETE from #__{vm}_order_payment where order_id='$record_id'";
$db->query($q);

$q = "DELETE from #__{vm}_product_download where order_id='$record_id'";
$db->query($q);

$q = "DELETE from #__{vm}_order_history where order_id='$record_id'";
$db->query($q);

$q = "DELETE from #__{vm}_order_user_info where order_id='$record_id'";
$db->query($q);

$q = "DELETE FROM #__{vm}_shipping_label where order_id=$record_id";
$db->query($q);

return True;
}
else {
return False;
}
}
/**

This keeps the default VM functions for inventory management when an Order Status is changed, but it prevents the inventory from changing when an Order is Deleted.  I hope it helps others who were drawn to this post like I was.

Joomla 1.5.22
VirtueMart 1.1.6