yaseent:
Hey man! This is an excellent suggestion to add consistency! Brilliant, I'll throw that in. At least should it be somehow utilized further down the line then at least the calculations remain intact.
Much appreciated :P
It's always great to add functionality that is usable by many/more, but should also try to not disable other functionality/options.
That said, I've taken a quick look at the area of code in question, and at least for just this additional code, I can see a way that you can add your code without having to insert the code into the includes/classes/order.php file....
If you were to use this notifier:
$this->notify('NOTIFY_ORDER_PROCESSING_STOCK_DECREMENT_INIT', array('i'=>$i), $this->products[$i], $i);
You could control the stock decrement/increase through this "purchase" method... And possibly use/need the following notifier:
$this->notify('NOTIFY_ORDER_PROCESSING_STOCK_DECREMENT_END', $i);
The below code section opens with a for loop (included below for "presentation" but is not fully closed out), but it appears that the area of concern for your plugin/code is within the if statement of whether or not to decrement stock so there already is a problem with your additions if STOCK_LIMITED is not equal to 'true':
for ($i=0, $n=sizeof($this->products); $i<$n; $i++) {
$custom_insertable_text = '';
$this->doStockDecrement = (STOCK_LIMITED == 'true');
$this->notify('NOTIFY_ORDER_PROCESSING_STOCK_DECREMENT_INIT', array('i'=>$i), $this->products[$i], $i);
// Stock Update - Joao Correia
if ($this->doStockDecrement) { // This can be adjusted to false within the observer if previously true, but understand that if previously false that none of your current code will execute.
if (DOWNLOAD_ENABLED == 'true') {
$stock_query_raw = "select p.products_quantity, pad.products_attributes_filename, p.product_is_always_free_shipping
from " . TABLE_PRODUCTS . " p
left join " . TABLE_PRODUCTS_ATTRIBUTES . " pa
on p.products_id=pa.products_id
left join " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad
on pa.products_attributes_id=pad.products_attributes_id
WHERE p.products_id = '" . zen_get_prid($this->products[$i]['id']) . "'";
// Will work with only one option for downloadable products
// otherwise, we have to build the query dynamically with a loop
$products_attributes = $this->products[$i]['attributes'];
if (is_array($products_attributes)) {
$stock_query_raw .= " AND pa.options_id = '" . $products_attributes[0]['option_id'] . "' AND pa.options_values_id = '" . $products_attributes[0]['value_id'] . "'";
}
$stock_values = $db->Execute($stock_query_raw, false, false, 0, true);
} else {
$stock_values = $db->Execute("select * from " . TABLE_PRODUCTS . " where products_id = '" . zen_get_prid($this->products[$i]['id']) . "'", false, false, 0, true);
}
$this->notify('NOTIFY_ORDER_PROCESSING_STOCK_DECREMENT_BEGIN', $i, $stock_values);
if ($stock_values->RecordCount() > 0) {
// do not decrement quantities if products_attributes_filename exists
if ((DOWNLOAD_ENABLED != 'true') || $stock_values->fields['product_is_always_free_shipping'] == 2 || (!$stock_values->fields['products_attributes_filename']) ) {
$stock_left = $stock_values->fields['products_quantity'] - $this->products[$i]['qty'];
$this->products[$i]['stock_reduce'] = $this->products[$i]['qty'];
} else {
$stock_left = $stock_values->fields['products_quantity'];
}
// $this->products[$i]['stock_value'] = $stock_values->fields['products_quantity'];
$db->Execute("update " . TABLE_PRODUCTS . " set products_quantity = '" . $stock_left . "' where products_id = '" . zen_get_prid($this->products[$i]['id']) . "'");
// if ( ($stock_left < 1) && (STOCK_ALLOW_CHECKOUT == 'false') ) {
if ($stock_left <= 0) {
// only set status to off when not displaying sold out
if (SHOW_PRODUCTS_SOLD_OUT == '0') {
$db->Execute("update " . TABLE_PRODUCTS . " set products_status = 0 where products_id = '" . zen_get_prid($this->products[$i]['id']) . "'");
}
}
// for low stock email
if ( $stock_left <= STOCK_REORDER_LEVEL ) {
// WebMakers.com Added: add to low stock email
$this->email_low_stock .= 'ID# ' . zen_get_prid($this->products[$i]['id']) . "\t\t" . $this->products[$i]['model'] . "\t\t" . $this->products[$i]['name'] . "\t\t" . ' Qty Left: ' . $stock_left . "\n";
}
}
} // This is the end of the "if ($this->doStockDecrement)" section.
By using an observer off of the notifier: NOTIFY_ORDER_PROCESSING_STOCK_DECREMENT_INIT, you can check to see if the payment module being used is your 'adminpurchase' module, if it is, then you can set the calling classes doStockDecrement to false (could check first if it is not equal to false and then set to false if it is, otherwise leave it alone with whatever value it is set to. This would "affect" how someone else's code works, but if you want to not do so there are a few things that could be done which would include capturing the necessary data through this observer event, then listen to the follow on observer event and make modifications that are deemed necessary to the data and both/all plugins could live together copacetically.)
Then, if the payment module is your 'adminpurchase' module, you can take just the action you need to take against the data that is provided, and when the observer completes the expectation is that the builtin code will not do any builtin decrement code and your results can be further fed along with the change(s) made to them as you have done in the observer.
So for ZC 1.5.3 and above an observer would be stored in includes/modules/classes/observers:
filename something similar to: auto.admin_purchase.php (see includes/init_includes/init_observers.php for "instruction" and naming)
<?php
class zcObserverAdminPurchase extends base {
function __construct() {
$attachMe = array();
$attachMe[] = 'NOTIFY_ORDER_PROCESSING_STOCK_DECREMENT_INIT';
$this->attach($this, $attachMe);
}
function updateNotifyOrderProcessingStockDecrementInit(&$callingClass, $notifier, $varArray, &$products_i, &$i_passed) {
if ($callingClass->info['payment_module_code'] == "adminpurchase") {
if ($callingClass->doStockDecrement != false) { // Check to see if the current value/status will allow processing the stock decrement code, if so, disable it.
$callingClass->doStockDecrement = false;
}
if (DOWNLOAD_ENABLED == 'true') {
$stock_query_raw = "select p.products_quantity, pad.products_attributes_filename, p.product_is_always_free_shipping
from " . TABLE_PRODUCTS . " p
left join " . TABLE_PRODUCTS_ATTRIBUTES . " pa
on p.products_id=pa.products_id
left join " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad
on pa.products_attributes_id=pad.products_attributes_id
WHERE p.products_id = '" . zen_get_prid($products_i['id']) . "'";
// Will work with only one option for downloadable products
// otherwise, we have to build the query dynamically with a loop
$products_attributes = $products_i['attributes'];
if (is_array($products_attributes)) {
$stock_query_raw .= " AND pa.options_id = '" . $products_attributes[0]['option_id'] . "' AND pa.options_values_id = '" . $products_attributes[0]['value_id'] . "'";
}
$stock_values = $db->Execute($stock_query_raw, false, false, 0, true);
} else {
$stock_values = $db->Execute("select * from " . TABLE_PRODUCTS . " where products_id = '" . zen_get_prid($products_i['id']) . "'", false, false, 0, true);
}
$this->notify('NOTIFY_ORDER_PROCESSING_STOCK_DECREMENT_BEGIN', $i, $stock_values);
if ($stock_values->RecordCount() > 0) {
// do not decrement quantities if products_attributes_filename exists
if ((DOWNLOAD_ENABLED != 'true') || $stock_values->fields['product_is_always_free_shipping'] == 2 || (!$stock_values->fields['products_attributes_filename']) ) {
$stock_left = $stock_values->fields['products_quantity'] + $products_i['qty'];
$products_i['stock_reduce'] = (-1.0) * $products_i['qty'];
} else {
$stock_left = $stock_values->fields['products_quantity'];
}
// $products_i['stock_value'] = $stock_values->fields['products_quantity'];
$db->Execute("update " . TABLE_PRODUCTS . " set products_quantity = '" . $stock_left . "' where products_id = '" . zen_get_prid($products_i['id']) . "'");
// Section about setting the product to disabled is unnecessary generally speaking though it may be desirable to reenable product that are now
// in stock that previously weren't, though the problem with that "thought" is if they were not in stock (disabled) then how could they have been
// added to the cart in order to make this purchase so again, back to don't need the disable/enable condition of the product because this process
// without additional code work would not permit the purchase of out-of-stock product in order to reup the quantity.
// Can leave in the low stock email if you wish to be notified (again) that the stock quantity now still remains below the reorder level...
// for low stock email
if ( $stock_left <= STOCK_REORDER_LEVEL ) {
// WebMakers.com Added: add to low stock email
$this->email_low_stock .= 'ID# ' . zen_get_prid($products_i['id']) . "\t\t" . $products_i['model'] . "\t\t" . $products_i['name'] . "\t\t" . ' Qty Left: ' . $stock_left . "\n";
}
}
}
}
}
Now, the flip side to all of this? Could create (or support creation) of a "filter" for EasyPopulate that would allow you to enter just the stock quantity to be increased by (not the final value, but the change in quantity) and upload the file... No admin login as a user, no making sure that a product is first active, etc... Just another thought (which is something I'm looking to do for EasyPopulate V4)...