I tried with following observer code.
...
public function automaticallyInvoiceShipCompleteOrder($observer)
{
$order = $observer->getEvent()->getOrder();
$orders = Mage::getModel('sales/order_invoice')->getCollection()
->addAttributeToFilter('order_id', array('eq'=>$order->getId()));
$orders->getSelect()->limit(1);
if ((int)$orders->count() !== 0) {
return $this;
}
try {
if($order->canShip())
{
$itemQty = $order->getItemsCollection()->count();
$items[] = $itemQty;
// This first definition and 2nd look overlapping, our one is obsolete?
$shipment = Mage::getModel('sales/service_order', $order)->prepareShipment($itemQty);
$ship = new Mage_Sales_Model_Order_Shipment_Api();
$shipmentId = $ship->create($order->getId(), $items, 'Shipment created through ShipMailInvoice', true, true);
//getting Error here
}
}
} catch (Exception $e) {
$order->addStatusHistoryComment(' Exception occurred during automaticallyInvoiceShipCompleteOrder action. Exception message: '.$e->getMessage(), false);
$order->save();
}
return $this;
}
.....
When i place the order, i can capture the order success event using observer. Finally getting "Fatal error: Maximum function nesting level of '100' reached, aborting!" in ajax call itself.
I could not found the solution. Kindly give some advice on this
Each time your order is saved, this observer method is called, which again saves your order due to some error in try block. That's the reason I think it will endlessly execute and after 100th time Fatal error will be thrown.
In your try block's $ship->create(), you need to pass Order Increment ID and not Order Entity ID.
I tried with below code,
public function automaticallyInvoiceShipCompleteOrder($observer)
{
//$order = $observer->getEvent()->getOrder();
$incrementid = $observer->getEvent()->getOrder()->getIncrementId();
$order = Mage::getModel('sales/order')->loadByIncrementId($incrementid);
try {
// Is the order shipable?
if($order->canShip())
{
$shipmentid = Mage::getModel('sales/order_shipment_api')->create($order->getIncrementId(), array());
}
//END Handle Shipment
} catch (Exception $e) {
$order->addStatusHistoryComment(' Exception occurred during automaticallyInvoiceShipCompleteOrder action. Exception message: '.$e->getMessage(), false);
}
return $this;
}
Shipment Created now...
Related
I'm testing on Magento 2.2.3 and I've created an observer for the event sales_order_save_after which I'm using to automatically create an invoice.
Here is the current error that I'm receiving after placing an order:
Order saving error: Rolled back transaction has not been completed correctly.
And my MyCompany/MyModule/Observer/SalesOrderSaveAfter.php
<?php
namespace MyCompany\MyModule\Observer;
use Magento\Framework\Event\ObserverInterface;
class SalesOrderSaveAfter implements ObserverInterface
{
protected $_invoiceService;
protected $_transactionFactory;
public function __construct(
\Magento\Sales\Model\Service\InvoiceService $invoiceService,
\Magento\Framework\DB\TransactionFactory $transactionFactory
) {
$this->_invoiceService = $invoiceService;
$this->_transactionFactory = $transactionFactory;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$order = $observer->getEvent()->getOrder();
try {
if(!$order->canInvoice()) {
return null;
}
if(!$order->getState() == 'new') {
return null;
}
$invoice = $this->_invoiceService->prepareInvoice($order);
$invoice->setRequestedCaptureCase(\Magento\Sales\Model\Order\Invoice::CAPTURE_ONLINE);
$invoice->register();
$transaction = $this->_transactionFactory->create()
->addObject($invoice)
->addObject($invoice->getOrder());
$transaction->save();
} catch (\Exception $e) {
$order->addStatusHistoryComment('Exception message: '.$e->getMessage(), false);
$order->save();
return null;
}
}
}
If I remove the transaction portion of the code, eg:
$transaction = $this->_transactionFactory->create()
->addObject($invoice)
->addObject($invoice->getOrder());
$transaction->save();
then the order will pass through with the products marked as invoiced, but no invoice is actually created or saved to the order.
Any ideas what I could be missing?
https://magento.stackexchange.com/questions/217045/magento-2-how-to-automatically-create-invoice-from-order-observer
The answer to this is that I was using the wrong event. With the event sales_order_save_after the order hasn't been committed to the Database yet.
I changed my event to fire on checkout_submit_all_after and my observer is now working.
I'm using the PDFParser and encountering a thrown exception that breaks my script even if I put it in a try/catch block like below. Meaning, the exception gets echoed but the "Caught exception: " part does not. I thought this was exactly what try/catch was for?
try {
$text = $pdf->getText();
}
catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
The github issue comments don't address this issue so I thought SO could help.
I was also facing the same problem of missing catalog fatal error.
I have tried try, throw and catch and now i am not getting any missing catalog fatal error.
Below is the code where i have applied try, throw and catch:
public function getPages()
{
try{
if (isset($this->dictionary['Catalog'])) {
// Search for catalog to list pages.
$id = reset($this->dictionary['Catalog']);
/** #var Pages $object */
$object = $this->objects[$id]->get('Pages');
if (method_exists($object, 'getPages')) {
$pages = $object->getPages(true);
return $pages;
}
}
if (isset($this->dictionary['Pages'])) {
// Search for pages to list kids.
$pages = array();
/** #var Pages[] $objects */
$objects = $this->getObjectsByType('Pages');
foreach ($objects as $object) {
$pages = array_merge($pages, $object->getPages(true));
}
return $pages;
}
if (isset($this->dictionary['Page'])) {
// Search for 'page' (unordered pages).
$pages = $this->getObjectsByType('Page');
return array_values($pages);
}
throw new \Exception('Missing catalog.');
}
catch(\Exception $e)
{
$pages = '0';
}
}
Best of luck!!
I want to integrate my functional test result with TestRail . Since test rail accept status update means whether the test is success or fail for integrating with it . But PHPunit functions like assertEqual, assertTrue, etc do not return any values.
How can we do this?
public function testGetItem()
{
$this->specify("Verify the functionality of the method ", function ($itemId, $orgId, $expectedResult) {
$result = $this->itemRepository->getItemInfo($ItemId , $orgId);
//$this->assertEquals($expectedResult , $result)
$testRail=new TestRailIntegration();
if($this->assertEquals($expectedResult , $result)){
$testRail->postResultsToTestRail("34530","1");
} else{
$testRail->postResultsToTestRail("34530","");
}
//34530 is testrail id
}
when a test fails it does not go to the else condition.
A straightforward answer is to catch exception, post result and rethrow exception.
public function testGetItem()
{
$this->specify("Verify the functionality of the method ", function ($itemId, $orgId, $expectedResult) {
$testRail = new TestRailIntegration();
try {
$result = $this->itemRepository->getItemInfo($ItemId , $orgId);
$this->assertEquals($expectedResult, $result);
$testRail->postResultsToTestRail("34530", "1");
} catch (\Exception $e) {
$testRail->postResultsToTestRail("34530", "");
throw $e;
}
}
I'm working on an api, it handles the requests which comes from clients, then gets the response from server(developed using codeigniter 3) and forwards that back to client.
But, in case of any database errors, like duplicate id, or null values, the model class cannot handle that error to display a proper error message. I've tried the try catch block but not succeeded yet.
Here's the model:
public function add() {
try {
$this->db->trans_start(FALSE);
$this->db->insert('users', $preparedData);
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE) {
throw new Exception("Database error:");
return false;
}
return TRUE;
} catch (Exception $e) {
log_message('error: ',$e->getMessage());
return;
}
}
One thing to mention, I've set db_debug to FALSE.
Any help would be appreciated.
As for CI 3, below code gets database error code and error message. db_debug is set to FALSE.
public function add() {
try {
$this->db->trans_start(FALSE);
$this->db->insert('users', $preparedData);
$this->db->trans_complete();
// documentation at
// https://www.codeigniter.com/userguide3/database/queries.html#handling-errors
// says; "the error() method will return an array containing its code and message"
$db_error = $this->db->error();
if (!empty($db_error)) {
throw new Exception('Database error! Error Code [' . $db_error['code'] . '] Error: ' . $db_error['message']);
return false; // unreachable retrun statement !!!
}
return TRUE;
} catch (Exception $e) {
// this will not catch DB related errors. But it will include them, because this is more general.
log_message('error: ',$e->getMessage());
return;
}
}
Refer to documentation at https://www.codeigniter.com/userguide3/database/queries.html#handling-errors
saying
If you need to get the last error that has occurred, the error() method will return an array containing its code and message.
It is a bit incomplete in my opinion because it does not show error code and error message in the example code.
I just lost an hour trying to figure out why I can't get the error in my code. You have to check for an error after each statement! Working solution:
function insertUpdate($data) {
$order = $data->order;
$order_products = $data->order_products;
$this->db->trans_start();
$order->user_id = $this->session->user_id;
$error = "OK";
if (!$this->db->insert('_order', $order)) {
$error = $this->db->error()["message"];
}
$id = $this->db->insert_id();
foreach ($order_products as $row) {
$row->order_id = $id;
if (!$this->db->insert('_order_product', $row)) {
$error = $this->db->error()["message"];
break;
}
}
$order_code = substr(md5($id), 0, 6);
if (!$this->db->where('order_id', $id)) {
$error = $this->db->error()["message"];
}
if (!$this->db->update('_order', ["order_code" => $order_code])) {
$error = $this->db->error()["message"];
}
$this->db->trans_complete();
return [
'result' => $error, 'order_code' => $order_code
];
}
Suggestion in above code
Remove line $this->db->trans_complete();
If we see $this->db->error() after completing transaction it will be always empty
Remove semicolon - log_message('error :',$e->getMessage());
return;
public function add()
{
try {
$this->db->trans_start(FALSE);
$this->db->insert('users', $preparedData);
// documentation at
// https://www.codeigniter.com/userguide3/database/queries.html#handling-errors
// says; "the error() method will return an array containing its code and message"
$db_error = $this->db->error();
if (!empty($db_error)) {
throw new Exception('Database error! Error Code [' . $db_error['code'] . '] Error: ' . $db_error['message']);
return false; // unreachable return statement !!!`enter code here`
}
return TRUE;
} catch (Exception $e) {
// this will not catch DB related `enter code here`errors. But it will include them, because this is more general.
log_message('error ',$e->getMessage());
return;
}
}
I wanted to add an action on Sales>Order in Magento admin.
Screenshot-
I followed the second method from this blog- www.blog.magepsycho.com/adding-new-mass-action-to-admin-grid-in-magento/
My problem-
I am not able to get the order id (for performing the action on it) in the action controller.
My code in class MyPackage_MyModule_IndexController extends Mage_Adminhtml_Controller_Action
protected function _initOrder()
{
$id = $this->getRequest()->getParam('order_id'); ///TROUBLE HERE
$order = Mage::getModel('sales/order')->load($id);
if (!$order->getId()) {
$this->_getSession()->addError($this->__('This order no longer exists.'));
$this->_redirect('dash/sales_order');
$this->setFlag('', self::FLAG_NO_DISPATCH, true);
return false;
}
Mage::register('sales_order', $order);
Mage::register('current_order', $order);
return $order;
}
public function approvecodAction() {
if ($order = $this->_initOrder()) {
try {
$order->setStatus('codapproved')
->save();
$this->_getSession()->addSuccess(
$this->__('The order has been approved for COD.')
);
}catch (Mage_Core_Exception $e) {
$this->_getSession()->addError($e->getMessage());
}catch (Exception $e) {
$this->_getSession()->addError($this->__('The order has not been approved for COD.'));
Mage::logException($e);
}
$this->_redirect('*/sales_order/view', array('order_id' => $order->getId()));
}
}
Note I copied the above two functions from app/code/core/Mage/Adminhtml/controllers/Sales/OrderController.php and modified for my purpose.
Please tell me how and where to set the parameter order id? Or if they are getting set, then how to get them?
Thanks!
You're dealing with a mass action callback on the controller, so you will be getting an array of values in the parameter instead of a single value. You're going to need to do something more like this in your action method:
public function approvecodAction() {
$orderIds = $this->getRequest()->getPost('order_ids', array());
foreach ($orderIds as $orderId) {
$order = Mage::getModel('sales/order')->load($orderId);
try {
$order->setStatus('codapproved')
->save();
$this->_getSession()->addSuccess(
$this->__('The order has been approved for COD.')
);
}catch (Mage_Core_Exception $e) {
$this->_getSession()->addError($e->getMessage());
}catch (Exception $e) {
$this->_getSession()->addError($this->__('The order has not been approved for COD.'));
Mage::logException($e);
}
}
$this->_redirect('*/sales_order/view', array('order_id' => $order->getId()));
}
Hope that helps!