I'm struggling with a special little problem related to the redirect out of some Magento observer.
I wrote an extension and put an observer to the "checkout_submit_all_after" event, which works out just fine. My little extension automatically creates an invoice and sets the order status to processing, once the payment method is "Invoice". Unfortunately the redirect after submitting an order in the one page checkout doesn't work anymore. It always redirects to "checkout/cart" instead of "checkout/onepage/success".
Someone any ideas what I'm doing wrong?
Here's my code:
class Shostra_AutoInvoice_Model_Order_Observer
{
public function __construct()
{
}
public function auto_create_invoice($observer)
{
$order = $observer->getEvent()->getOrder();
if (!$order->hasInvoices()) {
$payment = $order->getPayment()->getMethodInstance()->getTitle();
Mage::log("payment method: " . $payment);
if($payment=="Rechnung"){
Mage::log("autocreating invoice");
$invoice = $order->prepareInvoice();
$invoice->register();
$invoice->pay();
$invoice->save();
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();
Mage::log("invoice created and saved");
}
$this->addComment('Order automatically set to paid.');
} else {
$this->addComment('no invoices found.');
}
$response = $observer->getResponse();
$response->setRedirect(Mage::getUrl('checkout/onepage/success'));
Mage::getSingleton('checkout/session')->setNoCartRedirect(true);
}
}
Thanks a lot!
Why don't you try sales_order_save_after event and try saving it, so no issues with redirection manually as Magento will take its own course,
you can refer to this link for more explanation
http://inchoo.net/magento/magento-orders/automatically-invoice-ship-complete-order-in-magento/
Related
I wrote here because I has been looking for way how to resolve my issue for 2h+ )
I need in updating shopping cart in Magento. There are similar questions at StackOverFlow.com but They looks not appropriate to my task
Let me explain shortly
1) I overwrote Mage_Checkout_CartController
like
class IB_Ajax_IndexController extends Mage_Checkout_CartController
It works nice with ajax adding products
for updating I send request
/ajax/index/updatePost
with params
form_key=H7XpKxwBOWQCkIHk&cart[304][qty]=39&cart[305][qty]=1&cart[306][qty]=1&update_cart_action=upd
It goes to my controller "IB_Ajax_IndexController"
which has all methods "Mage_Checkout_CartController"
I detected that this method does update
public function updatePostAction()
and then some update go to $this->_updateShoppingCart(); in above method
case 'update_qty':
$this->_updateShoppingCart();
break;
I copied its code to my controller for rewriting it here )
and I encountered so much difficult with it
how to detect SUCCESS or ERROR in this method updatePostAction() after execution $this->_updateShoppingCart() in it (
????
Maybe someone has experience with updating shopping cart via ajax ?
and how to modify above methods
Thanks a lot in advance
First make an response array like this.
$response = array();
After add cart code like $cart->save();
try{ if (!$cart->getQuote()->getHasError()){
$message = $this->__('%s was added to your shopping cart.', Mage::helper('core')->htmlEscape($product->getName()));
$response['status'] = 'SUCCESS';
$response['message'] = $message;
}
} catch (Exception $e) {
$response['status'] = 'ERROR';
$response['message'] = $this->__('Cannot add the item to shopping cart.');
Mage::logException($e);
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($response));
return;
And when you get response, by $response['status'] you can fetch SUCCESS or ERROR.
people. i have a problem. I have an action in my custom module, that creates customer.
There is a code:
class SeosClub_BusinessCategory_CustomerController extends Mage_Core_Controller_Front_Action {
public function createAction(){
$requestData = Mage::app()->getRequest()->getParams();
if(!$requestData['id'] || !$requestData['activation_code']){
Mage::getSingleton('core/session')->addError('Request data invalid');
}
$company = Mage::getModel('businesscategory/company')->load($requestData['id']);
if (!$company->getId()){
Mage::getSingleton('core/session')->addError('Your company does not exist');
}
if($company->getCustomerId()){
Mage::getSingleton('core/session')->addNotice($this->__('Customer already created. Forgot password?'));
$this->_redirect('customer/account/forgotpassword/');
return;
}
$group = Mage::getModel('customer/group')->load('Companies', 'customer_group_code');;
$customer = Mage::getModel("customer/customer");
$customer->setWebsiteId(Mage::app()->getWebsite()->getId());
$customer->setStore(Mage::app()->getStore());
$customer->setData('group_id', $group->getId());
$customer->setFirstname($company->getName());
$customer->setLastname($this->__('Unknown'));
$customer->setEmail($company->getEmail());
$customer->setPassword(Mage::helper('core')->getRandomString(8));
try{
$customer->save();
$customer->sendNewAccountEmail();
$company->setCustomerId($customer->getId());
$company->save();
Mage::getSingleton('core/session')->addSuccess($this->__('Account was created succefully'));
}
catch (Exception $e) {
Mage::getSingleton('core/session')->addError($e->getMessage());
}
$this->loadLayout();
$this->renderLayout();
}
}
I have also installed theme on my magento. But, when i open the page, it renderes base magento theme, not my installed theme.
If i comment code from if($company->getCustomerId()) to $this->loadLayout(); (not including $this->loadLayout();), it renderes correct theme.
Any ideas?
Enable developer mode in magento. Uncomment display_errors in index.php. You should see some errors, since you have:
$company = Mage::getModel('businesscategory/company')->load($requestData['id']);
$requestData['id'] might not be set here, because your if condition is not ending the processing of the method. So further in the code you might not have $company and you call functions on null.
Check if $company is an object.
I think it renders the default theme becuse you have errors.
Ok, to fix that i needed to send customer email after rendering layout.
I'm just trying to set up terms and conditions page after a successful login. All seems to to working well. I am getting the post data through the form which I have placed in CMS Page with identifier 'general-conditions'. The problem is only in the
header('Location: '.Mage::getUrl('general-conditions'));
If I comment out this line.. page loads properly but if I don't it gets caught in infinite loop.
Could anyone please help me, that's the only thing left and I've spent a lot of time on it.
Thanks in advance.
<?php
Class Rik_Terms_Model_Observer{
public function checkGeneralTerms(){
if (Mage::helper('customer')->isLoggedIn()) {
$id = Mage::getModel('customer/session')->getId();
$customer = Mage::getModel('customer/customer')->load($id);
$customerData = $customer->getData();
$groupId = Mage::helper('customer')->getCustomer()->getGroupId();
$groupName = Mage::getModel('customer/group')->load($groupId)->getCode();
$storeId = Mage::app()->getStore()->getId();
if($customer->getGeneralTerms()=='0'){
$pageIdentifier = Mage::getModel('cms/page')->checkIdentifier("general-conditions", $storeId);
if ($pageIdentifier){
header('Location: '.Mage::getUrl('general-conditions')); // problem
die();
}
}
}
}
}
Found later, it was actually conflicting with extended version of my CMS Module.
I'm on Magento 1.7.0.2. How can I print invoices from backend with the same manner that frontend uses? I want it to be on HTML format not PDF.
Assuming that you want to print one invoice at a time from the admin order detail page
Create a custom admin module
Add a controller with the method below
public function printInvoiceAction()
{
$invoiceId = (int) $this->getRequest()->getParam('invoice_id');
if ($invoiceId) {
$invoice = Mage::getModel('sales/order_invoice')->load($invoiceId);
$order = $invoice->getOrder();
} else {
$order = Mage::registry('current_order');
}
if (isset($invoice)) {
Mage::register('current_invoice', $invoice);
}
$this->loadLayout('print');
$this->renderLayout();
}
Reference printInvoiceAction() in app/code/core/Mage/Sales/controllers/GuestController.php
Then in your custom layout.xml use <sales_guest_printinvoice> in /app/design/frontend/base/default/layout/sales.xml as your template
Then add a button with link to the following url (need to get invoice id from order) /customModule/controller/printInvoice/invoice_id/xxx
(Not tested, so let me know if you run into any issues)
You should create your custom css file for printing print.css. And you should add "Print Button", that will call window.print()
This is one of the most vital problems I have found since I started testing Magento for my web store. It's kind of a no-brainer that it's absolutely unnecessary and harmful to sales to empty cart before payment confirmation, which unfortunately, Magento does.
If the user selects PayPal (website standard) for payment method and for some reason clicks "Back to xxxx" (your business name at PayPal) on the PayPal payment page without paying, PayPal would redirect the user back to http://www.example.com/checkout/cart/, which now is an EMPTY cart.
I think it should be after payment confirmation / PayPal IPN that the cart be empty-ed, instead of any point before that.
Even if the user wants to continue again, he or she'd be annoyed from searching and adding all the products again and would very probably just leave.
Any idea how I can work around this?
This worked for me:
File: ~/app/code/core/Mage/Checkout/controllers/OnepageController.php
Replace this:
$this->getOnepage()->getQuote()->save();
/**
* when there is redirect to third party, we don't want to save order yet.
* we will save the order in return action.
*/
if (isset($redirectUrl)) {
$result['redirect'] = $redirectUrl;
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
With this one:
/**
* when there is redirect to third party, we don't want to save order yet.
* we will save the order in return action.
*/
if (isset($redirectUrl)) {
$result['redirect'] = $redirectUrl;
$this->getOnepage()->getQuote()->setIsActive(1) ;
}
$this->getOnepage()->getQuote()->save();
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
For Paypal I found the cancel action inside the app/code/core/Mage/Paypal/controllers/StandardController.php cancelAction
I changed the code like that for cancel action
public function cancelAction()
{
$session = Mage::getSingleton('checkout/session');
$cart = Mage::getSingleton('checkout/cart');
$session->setQuoteId($session->getPaypalStandardQuoteId(true));
if ($session->getLastRealOrderId()) {
$incrementId = $session->getLastRealOrderId();
if (empty($incrementId)) {
$session->addError($this->__('Your payment failed, Please try again later'));
$this->_redirect('checkout/cart');
return;
}
$order = Mage::getModel('sales/order')->loadByIncrementId($session->getLastRealOrderId());
$session->getQuote()->setIsActive(false)->save();
$session->clear();
try {
$order->setActionFlag(Mage_Sales_Model_Order::ACTION_FLAG_CANCEL, true);
$order->cancel()->save();
} catch (Mage_Core_Exception $e) {
Mage::logException($e);
}
$items = $order->getItemsCollection();
foreach ($items as $item) {
try {
$cart->addOrderItem($item);
} catch (Mage_Core_Exception $e) {
$session->addError($this->__($e->getMessage()));
Mage::logException($e);
continue;
}
}
$cart->save();
$session->addError($this->__('Your payment failed. Please try again later'));
}
$this->_redirect('checkout/cart');
}
It worked pretty good for me and there is no need to change any other place for that.
It marks the current order as Cancelled and restores the cart with using that order and redirects the user to cart again.
/app/code/core/Mage/Checkout/controllers/OnepageController.php this file is the actual controller file, but depends up on the payment method extensions it will change with Namespace/Modulename/Checkout/controllers/OnepageController.php
Find function saveOrderAction()
find these lines
$this->getOnepage()->getQuote()->save();
/**
* when there is redirect to third party, we don't want to save order yet.
* we will save the order in return action.
*/
if (isset($redirectUrl)) {
$result['redirect'] = $redirectUrl;
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
comment this line //$this->getOnepage()->getQuote()->save();
and add below codes inside the if condition so the condition will look like ..
//$this->getOnepage()->getQuote()->save();
if (isset($redirectUrl)) {
$result['redirect'] = $redirectUrl;
$this->getOnepage()->getQuote()->setIsActive(1) ;
}
$this->getOnepage()->getQuote()->save();
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
This is i have done with the third party Payment extension.
Since Magento version 1.6.0.0 (juli 2011) you can enable "Persistent Shopping Cart"
under
System > Configuration > Customers > Persistent Shopping Cart
This should solve this problem.
Use these settings to make it work
Enable Persistence = Yes
Persistence Lifetime (seconds) = 31536000
Enable "Remember Me" = Yes
"Remember Me" Default Value = Yes
Clear Persistence on Log Out = No
Persist Shopping Cart = Yes
Good luck :)
Your issue is with the way Mage_Checkout_OnepageController::saveOrderAction() behaves.
More specific: open app/code/core/Mage/Checkout/controllers/OnepageController.php
$this->getOnepage()->getQuote()->save();//this makes the cart empty (sets the quote as converted to order)
if (isset($redirectUrl)) {
$result['redirect'] = $redirectUrl;
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
}
You can replace the last part:
$this->getOnepage()->getQuote()->save();//....
with:
if (isset($redirectUrl)) {
$result['redirect'] = $redirectUrl;
$this->getOnepage()->getQuote()->setIsActive(1) ;
}
$this->getOnepage()->getQuote()->save();
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));