Unable to getParam() - php

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!

Related

Catch Guzzle Exception and return string

So I need some help on building out one of my methods for retrieving twitter lists using IDs. Below, I will describe and go into detail on what it's returning.
Code:
public static function get_list($list_id)
{
$lists = self::get_lists();
$params = [
'list.fields' => 'created_at,follower_count,member_count,private,description,owner_id',
'user.fields' => 'created_at,description,entities,id,location,name,pinned_tweet_id,profile_image_url,protected,public_metrics,url,username,verified,withheld'
];
try {
$list = $lists->get($list_id, $params);
} catch (\GuzzleHttp\Exception\ClientException $e) {
return $e;
}
return $list;
}
When $lists->get() has an issue, it throws the following items object(GuzzleHttp\Exception\ClientException)#1640 (10) { ["request":"GuzzleHttp\Exception\RequestException":private]=> error.
What I'd like to achieve:
Return $e so that I can read the error (Unable to get this to work).
If I switch out return $e for return 'Hello', I still see the object and not the string.
The IDE suggests that it #throws GuzzleException.
Does anyone see anything wrong in how I'm handling my exception and why I'm unable to properly return the exception error?
Try to use exception hierarchy to catch any exception. ClientException only catches status code between 400x-499. To catch other exception or catch within the same Exception you can use RequestException.
public static function get_list($list_id)
{
$lists = self::get_lists();
$params = [
'list.fields' => 'created_at,follower_count,member_count,private,description,owner_id',
'user.fields' => 'created_at,description,entities,id,location,name,pinned_tweet_id,profile_image_url,protected,public_metrics,url,username,verified,withheld'
];
try {
$list = $lists->get($list_id, $params);
if($list->getStatusCode() == 200)){
$return_list = json_decode($list->getBody(),true);
}
} catch (\GuzzleHttp\Exception\ClientException $e) {
$error['error'] = $e->getMessage();
$error['request'] = $e->getRequest();
if($e->hasResponse()){
// you can pass a specific status code to catch a particular error here I have catched 400 Bad Request.
if ($e->getResponse()->getStatusCode() == '400'){
$error['response'] = $e->getResponse();
}
}
return $error;
} catch(\GuzzleHttp\Exception\RequestException $se){
$error['error'] = $e->getMessage();
$error['request'] = $e->getRequest();
return $error;
} catch(Exception $e){
//other errors
}
return $list;
}

How to commit just part of transaction PHP?

I need ideas to solve the problem where there's an order to be updated, and payments to be created to this order. But if the order charging fails. The updates made to the order should be undone, but the charges created to it should persist.
Example controller code:
$order = Order::find(1);
DB::beginTransaction();
try {
$order->update(['status' => 1]);
chargeOrder ($order);
} catch (PaymentErrorException $e) {
DB::rollback();
throw $e;
}
catch (\Exception $e) {
DB::rollback();
throw $e;
}
DB::commit();
Example function that make the order charging:
function chargeOrder( $order ) {
$payments_service->charge($order);
$order->payments()->create( new Payment() );
}
What i need is, when a PaymentErrorException occurs, only the $order->update() should be undone, but the changes made inside chargeOrder function, should persist.
If I understand the question correctly:
$order = Order::find(1);
$previousStatus = $order->status;
DB::beginTransaction();
try {
$order->update(['status' => 1]);
chargeOrder ($order);
} catch (PaymentErrorException $e) {
$order->update(['status' => $previousStatus]);
}
catch (\Exception $e) {
DB::rollback();
throw $e;
}
DB::commit();

How can I use db transaction in laravel?

I try this :
public function destroy($id)
{
DB::beginTransaction();
try {
$product = $this->product_repository->find($id);
$result = $product->categories()->detach();
if($result) {
list($status,$instance) = $this->product_repository->delete($id);
}
DB::commit();
return ['status'=>true,'data'=>$status];
} catch (\Exception $e) {
DB::rollback();
return ['status'=>false, 'message'=>$e->getMessage()];
}
}
If the code executed, $this->product_repository->delete($id) not work / not success delete.
But this : $product->categories()->detach();, it works / success deleted.
How to if delete product failed, delete category also failed?
You can't add return statement inside transaction that halts entire process and DB::rollback() is executed.
To switch the return, You can define a boolean variable and make false while you catch exception.
Like this:
public function destroy($id)
{
$success = true;
DB::beginTransaction();
try{
// Your Code
$product = $this->product_repository->find($id);
$result = $product->categories()->detach();
if($result) {
list($status,$instance) = $this->product_repository->delete($id);
}
DB::commit();
}catch(\Exception $e){
DB::rollback();
$success = false;
}
if($success){
// Return data for successful delete
}
else{
// Return data for unsuccessful delete
}
}
Hope you understand.
You can use it like this:
$returnResult = [];
DB::beginTransaction();
try {
...
DB::commit();
$returnResult['status'] = true;
$returnResult['data'] = $status;
} catch (...) {
...
DB::rollback();
$returnResult['status'] = true;
$returnResult['message'] = $e->getMessage();
}
return $returnResult;

If condition on save laravel

I had 2 tables. driver and part_time_available in the same form, when I select driver type = parttime, it'll show part_time_available field(day, start_time, end_time).
How to make condition if user choose fulltime. it didn't store part_time_available field to database.
here's my savehandler code so far :
public function saveHandler(Request $request, $obj)
{
try {
DB::beginTransaction();
$obj->fill($request->all());
if (!$obj->save()) {
throw new ValidationException($obj->errors());
}
foreach($request->parttimeAvailabilities as $pta) {
\Log::info($pta);
if (empty($pta['id'])) {
$parttimeAvailability = new PartTimeAvailability();
}
else {
$parttimeAvailability = PartTimeAvailability::find($pta['id']);
}
$parttimeAvailability->driver()->associate($obj);
$pta['driver_id'] = isset($pta['driver_id']);
$parttimeAvailability->day = $pta['day'];
$parttimeAvailability->start_time = isset($pta['start_time']) ? $pta['start_time'] : '00:00:00';
$parttimeAvailability->end_time = isset($pta['end_time']) ? $pta['end_time'] : '00:00:00';
$parttimeAvailability->available = isset($pta['available']);
$parttimeAvailability->save();
};
$obj->save();
if (!$parttimeAvailability->save()) {
throw new ValidationException($parttimeAvailability->errors());
}
DB::commit();
return $this->sendSuccessResponse($request);
} catch (ValidationException $e) {
DB::rollback();
\Log::error($e->errors);
return $this->sendErrorResponse($request, $e->errors);
} catch (Exception $e) {
DB::rollback();
\Log::error($e->getMessage());
return $this->sendErrorResponse($request,'Unable to process. Please contact system Administrator');
}
}
I mean before running foreach, it needs to check it's parttime or not.
any idea ?
You can give a condition before the whole foreach loop. such as:
if($request->get('driver_type') != 'full_time'){
foreach loop
}

How do i make auto shipping programatically in magento?

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...

Categories