// #PSTEST-473 Fixed OrderHistory
This commit is contained in:
+111
-91
@@ -28,19 +28,19 @@
|
||||
class OrderHistoryCore extends ObjectModel
|
||||
{
|
||||
/** @var integer Order id */
|
||||
public $id_order;
|
||||
public $id_order;
|
||||
|
||||
/** @var integer Order state id */
|
||||
public $id_order_state;
|
||||
public $id_order_state;
|
||||
|
||||
/** @var integer Employee id for this history entry */
|
||||
public $id_employee;
|
||||
public $id_employee;
|
||||
|
||||
/** @var string Object creation date */
|
||||
public $date_add;
|
||||
public $date_add;
|
||||
|
||||
/** @var string Object last modification date */
|
||||
public $date_upd;
|
||||
public $date_upd;
|
||||
|
||||
/**
|
||||
* @see ObjectModel::$definition
|
||||
@@ -52,12 +52,14 @@ class OrderHistoryCore extends ObjectModel
|
||||
'id_order' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
|
||||
'id_order_state' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
|
||||
'id_employee' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
|
||||
'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
|
||||
'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
protected $webserviceParameters = array(
|
||||
/**
|
||||
* @see ObjectModel::$webserviceParameters
|
||||
*/
|
||||
protected $webserviceParameters = array(
|
||||
'objectsNodeName' => 'order_histories',
|
||||
'fields' => array(
|
||||
'id_order_state' => array('required' => true, 'xlink_resource'=> 'order_states'),
|
||||
@@ -65,68 +67,74 @@ class OrderHistoryCore extends ObjectModel
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets the new state of the given order
|
||||
*
|
||||
* @param int $new_order_state
|
||||
* @param int $id_order
|
||||
*/
|
||||
public function changeIdOrderState($new_order_state, $id_order)
|
||||
{
|
||||
if (!$new_order_state)
|
||||
if (!$new_order_state || !$id_order)
|
||||
return;
|
||||
|
||||
// sets order and states
|
||||
$order = new Order($id_order);
|
||||
$newOS = new OrderState((int)$new_order_state, $order->id_lang);
|
||||
$new_os = new OrderState((int)$new_order_state, $order->id_lang);
|
||||
$old_os = OrderHistory::getLastOrderState((int)$id_order);
|
||||
$is_validated = $this->isValidated();
|
||||
|
||||
// Execute pre hooks
|
||||
if ($newOS->id == Configuration::get('PS_OS_PAYMENT'))
|
||||
Hook::exec('actionPaymentConfirmation', array(
|
||||
'id_order' => (int)$order->id
|
||||
));
|
||||
// executes hook
|
||||
if ($new_os->id == Configuration::get('PS_OS_PAYMENT'))
|
||||
Hook::exec('actionPaymentConfirmation', array('id_order' => (int)$order->id));
|
||||
|
||||
// executes hook
|
||||
Hook::exec('actionOrderStatusUpdate', array(
|
||||
'newOrderStatus' => $newOS,
|
||||
'newOrderStatus' => $new_os,
|
||||
'id_order' => (int)$order->id
|
||||
));
|
||||
|
||||
$oldOrderStatus = OrderHistory::getLastOrderState((int)$id_order);
|
||||
$isValidated = $this->isValidated();
|
||||
if (Validate::isLoadedObject($order))
|
||||
if (Validate::isLoadedObject($order) && ($old_os instanceof OrderState) && ($new_os instanceof OrderState))
|
||||
{
|
||||
// @since 1.5.0 : gets the stock manager
|
||||
$manager = null;
|
||||
if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))
|
||||
$manager = StockManagerFactory::getManager();
|
||||
// foreach products of the order
|
||||
foreach ($order->getProductsDetail() as $product)
|
||||
{
|
||||
/* If becoming logable => adding sale */
|
||||
if ($newOS->logable
|
||||
&& !($oldOrderStatus instanceof OrderState
|
||||
&& $oldOrderStatus->logable))
|
||||
// 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']) &&
|
||||
($old_os->id == Configuration::get('PS_OS_ERROR') || $old_os->id == Configuration::get('PS_OS_CANCELED')))
|
||||
StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], -(int)$product['product_quantity'], $order->id_shop);
|
||||
}
|
||||
/* If becoming unlogable => removing sale */
|
||||
else if (!$newOS->logable
|
||||
&& $oldOrderStatus instanceof OrderState
|
||||
&& $oldOrderStatus->logable)
|
||||
// if becoming unlogable => removes sale
|
||||
else if (!$new_os->logable && $old_os->logable)
|
||||
{
|
||||
ProductSale::removeProductSale($product['product_id'], $product['product_quantity']);
|
||||
// @since 1.5.0
|
||||
if ($newOS->id == Configuration::get('PS_OS_ERROR') || $newOS->id == Configuration::get('PS_OS_CANCELED'))
|
||||
|
||||
// @since 1.5.0 - Stock Management
|
||||
if (!Pack::isPack($product['product_id']) &&
|
||||
($new_os->id == Configuration::get('PS_OS_ERROR') || $new_os->id == Configuration::get('PS_OS_CANCELED')))
|
||||
StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], (int)$product['product_quantity'], $order->id_shop);
|
||||
}
|
||||
|
||||
if ((!Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') || (int)$product['advanced_stock_management'] != 1)
|
||||
&& !$isValidated
|
||||
&& $newOS->logable
|
||||
&& $oldOrderStatus instanceof OrderState
|
||||
&& $oldOrderStatus->id == Configuration::get('PS_OS_ERROR')
|
||||
)
|
||||
StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], (int)$product['product_quantity'], $order->id_shop);
|
||||
// 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 instanceof OrderState
|
||||
&& $oldOrderStatus->shipped == 0
|
||||
&& Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')
|
||||
&& ((int)$product['advanced_stock_management'] == 1 || Pack::usesAdvancedStockManagement($product['product_id'])))
|
||||
// @since 1.5.0 : if the order is being shipped and this products uses the advanced stock management :
|
||||
// decrements the physical stock using $id_warehouse
|
||||
if ($new_os->shipped == 1 && $old_os->shipped == 0 &&
|
||||
Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') &&
|
||||
Warehouse::exists($product['id_warehouse']) &&
|
||||
$manager != null &&
|
||||
((int)$product['advanced_stock_management'] == 1 || Pack::usesAdvancedStockManagement($product['product_id'])))
|
||||
{
|
||||
$manager = StockManagerFactory::getManager();
|
||||
// gets the warehouse
|
||||
$warehouse = new Warehouse($product['id_warehouse']);
|
||||
|
||||
// decrements the stock (if it's a pack, the StockManager does what is needed)
|
||||
$manager->removeProduct(
|
||||
$product['product_id'],
|
||||
$product['product_attribute_id'],
|
||||
@@ -136,20 +144,15 @@ class OrderHistoryCore extends ObjectModel
|
||||
true,
|
||||
(int)$id_order
|
||||
);
|
||||
|
||||
if (StockAvailable::dependsOnStock($product['product_id'], $order->id_shop))
|
||||
StockAvailable::synchronize($product['product_id']);
|
||||
else
|
||||
StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], -(int)$product['product_quantity'], $order->id_shop);
|
||||
//@TODO Synchronize for products in pack if needed ?!
|
||||
}
|
||||
else if ($newOS->shipped == 0
|
||||
&& $oldOrderStatus instanceof OrderState
|
||||
&& $oldOrderStatus->shipped == 1
|
||||
&& Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')
|
||||
&& ((int)$product['advanced_stock_management'] == 1 || Pack::usesAdvancedStockManagement($product['product_id'])))
|
||||
// @since.1.5.0 : if the order was shipped, and is not anymore, we need to restock products
|
||||
else if ($new_os->shipped == 0 && $old_os->shipped == 1 &&
|
||||
Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') &&
|
||||
Warehouse::exists($product['id_warehouse']) &&
|
||||
$manager != null &&
|
||||
((int)$product['advanced_stock_management'] == 1 || Pack::usesAdvancedStockManagement($product['product_id'])))
|
||||
{
|
||||
$manager = StockManagerFactory::getManager();
|
||||
// if the product is a pack, we restock every products in the pack using the last negative stock mvts
|
||||
if (Pack::isPack($product['product_id']))
|
||||
{
|
||||
$pack_products = Pack::getItems($product['product_id'], Configuration::get('PS_LANG_DEFAULT'));
|
||||
@@ -174,9 +177,9 @@ class OrderHistoryCore extends ObjectModel
|
||||
}
|
||||
}
|
||||
}
|
||||
// else, it's not a pack, re-stock using the last negative stock mvts
|
||||
else
|
||||
{
|
||||
|
||||
$mvts = StockMvt::getNegativeStockMvts($order->id, $product['product_id'], $product['product_attribute_id'], $product['product_quantity']);
|
||||
foreach ($mvts as $mvt)
|
||||
{
|
||||
@@ -190,30 +193,26 @@ class OrderHistoryCore extends ObjectModel
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
if (StockAvailable::dependsOnStock($product['product_id'], $order->id_shop))
|
||||
StockAvailable::synchronize($product['product_id']);
|
||||
else
|
||||
StockAvailable::updateQuantity($product['product_id'], $product['product_attribute_id'], (int)$product['physical_quantity'], $order->id_shop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->id_order_state = (int)($new_order_state);
|
||||
$this->id_order_state = (int)$new_order_state;
|
||||
|
||||
/* Change invoice number of order ? */
|
||||
if (!Validate::isLoadedObject($newOS) OR !Validate::isLoadedObject($order))
|
||||
// changes invoice number of order ?
|
||||
if (!Validate::isLoadedObject($new_os) || !Validate::isLoadedObject($order))
|
||||
die(Tools::displayError('Invalid new order state'));
|
||||
|
||||
/* The order is valid only if the invoice is available and the order is not cancelled */
|
||||
$order->valid = $newOS->logable;
|
||||
// the order is valid if and only if the invoice is available and the order is not cancelled
|
||||
$order->valid = $new_os->logable;
|
||||
$order->update();
|
||||
|
||||
if ($newOS->invoice AND !$order->invoice_number)
|
||||
if ($new_os->invoice && !$order->invoice_number)
|
||||
$order->setInvoice();
|
||||
|
||||
// Set order as paid
|
||||
if ($newOS->paid == 1)
|
||||
// set orders as paid
|
||||
if ($new_os->paid == 1)
|
||||
{
|
||||
$invoices = $order->getInvoicesCollection();
|
||||
$payment_method = Module::getInstanceByName($order->module);
|
||||
@@ -234,33 +233,49 @@ class OrderHistoryCore extends ObjectModel
|
||||
}
|
||||
}
|
||||
|
||||
// Update delivery date even if it was already set by another state change
|
||||
if ($newOS->delivery)
|
||||
// updates delivery date even if it was already set by another state change
|
||||
if ($new_os->delivery)
|
||||
$order->setDelivery();
|
||||
|
||||
// executes hook
|
||||
Hook::exec('actionOrderStatusPostUpdate', array(
|
||||
'newOrderStatus' => $newOS,
|
||||
'newOrderStatus' => $new_os,
|
||||
'id_order' => (int)$order->id,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last order state
|
||||
* @param int $id_order
|
||||
* @return OrderState|bool
|
||||
*/
|
||||
public static function getLastOrderState($id_order)
|
||||
{
|
||||
$id_order_state = Db::getInstance()->getValue('
|
||||
SELECT `id_order_state`
|
||||
FROM `'._DB_PREFIX_.'order_history`
|
||||
WHERE `id_order` = '.(int)($id_order).'
|
||||
WHERE `id_order` = '.(int)$id_order.'
|
||||
ORDER BY `date_add` DESC, `id_order_history` DESC');
|
||||
|
||||
// returns false if there is no state
|
||||
if (!$id_order_state)
|
||||
return false;
|
||||
|
||||
// else, returns an OrderState object
|
||||
return new OrderState($id_order_state, Configuration::get('PS_LANG_DEFAULT'));
|
||||
}
|
||||
|
||||
public function addWithemail($autodate = true, $templateVars = false, Context $context = null)
|
||||
/**
|
||||
* @param bool $autodate Optional
|
||||
* @param array $template_vars Optional
|
||||
* @param Context $context Optional
|
||||
* @return bool
|
||||
*/
|
||||
public function addWithemail($autodate = true, $template_vars = false, Context $context = null)
|
||||
{
|
||||
if (!$context)
|
||||
$context = Context::getContext();
|
||||
$lastOrderState = $this->getLastOrderState($this->id_order);
|
||||
$last_order_state = $this->getLastOrderState($this->id_order);
|
||||
|
||||
if (!parent::add($autodate))
|
||||
return false;
|
||||
@@ -272,36 +287,38 @@ class OrderHistoryCore extends ObjectModel
|
||||
LEFT JOIN `'._DB_PREFIX_.'customer` c ON o.`id_customer` = c.`id_customer`
|
||||
LEFT JOIN `'._DB_PREFIX_.'order_state` os ON oh.`id_order_state` = os.`id_order_state`
|
||||
LEFT JOIN `'._DB_PREFIX_.'order_state_lang` osl ON (os.`id_order_state` = osl.`id_order_state` AND osl.`id_lang` = o.`id_lang`)
|
||||
WHERE oh.`id_order_history` = '.(int)($this->id).' AND os.`send_email` = 1');
|
||||
WHERE oh.`id_order_history` = '.(int)$this->id.' AND os.`send_email` = 1');
|
||||
|
||||
if (isset($result['template']) AND Validate::isEmail($result['email']))
|
||||
if (isset($result['template']) && Validate::isEmail($result['email']))
|
||||
{
|
||||
$topic = $result['osname'];
|
||||
$data = array('{lastname}' => $result['lastname'], '{firstname}' => $result['firstname'], '{id_order}' => (int)$this->id_order);
|
||||
if ($templateVars)
|
||||
$data = array_merge($data, $templateVars);
|
||||
if ($template_vars)
|
||||
$data = array_merge($data, $template_vars);
|
||||
$order = new Order((int)$this->id_order);
|
||||
$data['{total_paid}'] = Tools::displayPrice((float)$order->total_paid, new Currency((int)$order->id_currency), false);
|
||||
$data['{order_name}'] = sprintf("#%06d", (int)$order->id);
|
||||
$data['{order_name}'] = sprintf('#%06d', (int)$order->id);
|
||||
|
||||
// An additional email is sent the first time a virtual item is validated
|
||||
if ($virtualProducts = $order->getVirtualProducts() AND (!$lastOrderState OR !$lastOrderState->logable) AND $newOrderState = new OrderState($this->id_order_state, Configuration::get('PS_LANG_DEFAULT')) AND $newOrderState->logable)
|
||||
$virtual_products = $order->getVirtualProducts();
|
||||
$new_order_state = new OrderState($this->id_order_state, Configuration::get('PS_LANG_DEFAULT'));
|
||||
if ($virtual_products && (!$last_order_state || !$last_order_state->logable) && $new_order_state && $new_order_state->logable)
|
||||
{
|
||||
$assign = array();
|
||||
foreach ($virtualProducts AS $key => $virtualProduct)
|
||||
foreach ($virtual_products as $key => $virtual_product)
|
||||
{
|
||||
$id_product_download = ProductDownload::getIdFromIdAttribute($virtualProduct['product_id'], $virtualProduct['product_attribute_id']);
|
||||
$id_product_download = ProductDownload::getIdFromIdAttribute($virtual_product['product_id'], $virtual_product['product_attribute_id']);
|
||||
$product_download = new ProductDownload($id_product_download);
|
||||
// If this virtual item has an associated file, we'll provide the link to download the file in the email
|
||||
if ($product_download->display_filename != '')
|
||||
{
|
||||
$assign[$key]['name'] = $product_download->display_filename;
|
||||
$dl_link = $product_download->getTextLink(false, $virtualProduct['download_hash'])
|
||||
$dl_link = $product_download->getTextLink(false, $virtual_product['download_hash'])
|
||||
.'&id_order='.$order->id
|
||||
.'&secure_key='.$order->secure_key;
|
||||
$assign[$key]['link'] = $dl_link;
|
||||
if ($virtualProduct['download_deadline'] != '0000-00-00 00:00:00')
|
||||
$assign[$key]['deadline'] = Tools::displayDate($virtualProduct['download_deadline'], $order->id_lang);
|
||||
if ($virtual_product['download_deadline'] != '0000-00-00 00:00:00')
|
||||
$assign[$key]['deadline'] = Tools::displayDate($virtual_product['download_deadline'], $order->id_lang);
|
||||
if ($product_download->nb_downloadable != 0)
|
||||
$assign[$key]['downloadable'] = $product_download->nb_downloadable;
|
||||
}
|
||||
@@ -310,8 +327,8 @@ class OrderHistoryCore extends ObjectModel
|
||||
$context->smarty->assign('id_order', $order->id);
|
||||
$iso = Language::getIsoById((int)($order->id_lang));
|
||||
$links = $context->smarty->fetch(_PS_MAIL_DIR_.$iso.'/download-product.tpl');
|
||||
$tmpArray = array('{nbProducts}' => count($virtualProducts), '{virtualProducts}' => $links);
|
||||
$data = array_merge ($data, $tmpArray);
|
||||
$tmp_array = array('{nbProducts}' => count($virtual_products), '{virtualProducts}' => $links);
|
||||
$data = array_merge ($data, $tmp_array);
|
||||
// If there's at least one downloadable file
|
||||
if (!empty($assign))
|
||||
Mail::Send((int)$order->id_lang, 'download_product', Mail::l('Virtual product to download', $order->id_lang), $data, $result['email'], $result['firstname'].' '.$result['lastname']);
|
||||
@@ -324,6 +341,9 @@ class OrderHistoryCore extends ObjectModel
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function isValidated()
|
||||
{
|
||||
return Db::getInstance()->getValue('
|
||||
|
||||
Reference in New Issue
Block a user