Send shipment email programmatically for the completed orders in magento - magento

I am using magento default shipment from the admin side.
so its working fine and sending email to the customers perfectly.
I want to create one script that can send email with the shipment details for all the completed orders in magento. This will be only for certain orders coming through CSV.
My script working fine when we are using the order_id of the processing orders but its not working for the completed orders . and not sending the Order items details in the email
please suggest me any solution for it..
Thanks a lot.
I am using the below script to do so :
function completeShipment($orderIncrementId,$shipmentTrackingNumber,$shipmentCarrierCode){
$shipmentCarrierTitle = $shipmentCarrierCode;
$customerEmailComments = '';
$order = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);
if (!$order->getId()) {
Mage::throwException("Order does not exist, for the Shipment process to complete");
}
try {
$shipment = Mage::getModel('sales/service_order', $order)->prepareShipment(_getItemQtys($order));
$arrTracking = array(
'carrier_code' => isset($shipmentCarrierCode) ? $shipmentCarrierCode : $order->getShippingCarrier()->getCarrierCode(),
'title' => isset($shipmentCarrierTitle) ? $shipmentCarrierTitle : $order->getShippingCarrier()->getConfigData('title'),
'number' => $shipmentTrackingNumber,
);
$track = Mage::getModel('sales/order_shipment_track')->addData($arrTracking);
$shipment->addTrack($track);
$shipment->register();
_saveShipment($shipment, $order, $customerEmailComments);
}catch (Exception $e) {
throw $e;
}
return $save;
}
function _getItemQtys(Mage_Sales_Model_Order $order){
$qty = array();
foreach ($order->getAllItems() as $_eachItem) {
if ($_eachItem->getParentItemId()) {
$qty[$_eachItem->getParentItemId()] = $_eachItem->getQtyOrdered();
} else {
$qty[$_eachItem->getId()] = $_eachItem->getQtyOrdered();
}
}
return $qty;
}
function _saveShipment(Mage_Sales_Model_Order_Shipment $shipment, Mage_Sales_Model_Order $order, $customerEmailComments = ''){
$shipment->getOrder()->setIsInProcess(true);
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($shipment)->addObject($order)->save();
//$emailSentStatus = $shipment->getData('email_sent');
$ship_data = $shipment->getOrder()->getData();
$customerEmail = $ship_data['customer_email'];
$emailSentStatus = $ship_data['email_sent'];
if (!is_null($customerEmail)) {
$shipment->sendEmail(true, $customerEmailComments);
$shipment->setEmailSent(true);
}
return $this;
}
Thanks a lot dagfr...! the below code works for me to get done my task:
function completeShipment($orderIncrementId,$shipmentIncreamentId){
$order = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);
$ship_data = $order->getData();
$customerEmail = $ship_data['customer_email'];
$shipment = Mage::getModel('sales/order_shipment')->loadByIncrementId($shipmentIncreamentId);
$customerEmailComments = '';
$sent = 0;
if (!is_null($customerEmail)) {
$sent = $shipment->sendEmail(true, $customerEmailComments);
$shipment->setEmailSent(true);
}
return $sent;
}

Your script tries to create the shipment then send the email.
For completed orders the shipment is already created and you can't create it again, so your try fails before the email sending.
Just before :
try {
$shipment = Mage::getModel('sales/service_order', $order)->prepareShipment(_getItemQtys($order));
Check the status of the order, if it's complete, just need to get the shipment and send the mail
$shipment->sendEmail(true, $customerEmailComments);
$shipment->setEmailSent(true);
Else you can perform your script.

I found success using the order_shipment_api instead of the service_order model.
If you want to include the tracking number in the shipment email, make sure you add the tracking first and then use Mage::getModel('sales/order_shipment_api')->sendInfo($shipmentIncrementId).
Code Snippet:
$shipmentApi = Mage::getModel('sales/order_shipment_api');
//pass false for email, unless you want Magento to send the shipment email without any tracking info
//could also be written as $shipmentIncrementId = $shipmentApi->create($order->getIncrementId());
$shipmentIncrementId = $shipmentApi->create($order->getIncrementId(), array(), '' , false, 0);
//add tracking info ($shippingCarrier is case sensitive)
$shipmentApi->addTrack($shipmentIncrementId, $shippingCarrier, $shippingTitle, $trackingNumber);
//send shipment email with tracking info
$shipmentApi->sendInfo($shipmentIncrementId);
See app\code\core\Mage\Sales\Model\Order\Shipment\Api.php for all methods.
You can(should) also perform checks first:
//check for existing shipments if you want
if ($order->getShipmentsCollection()->count() == 0){
}
// and/or
if($order->canShip()){
}

Related

I want to know how Magento save order when return after successful payment in paypal_express

Here is a condition in my latest project where I have to create order after successful payment done through Paypal Express programatically.
When I do it through Magento normal flow it is working very fine, but I want to do it programatically myself.
I tried this but it gives error that payment method is not available.
$quote->collectTotals();
$service = Mage::getModel("sales/service_quote", $quote);
$service->submitAll();
$order = $service->getOrder();
if($order) {
Mage::dispatchEvent("checkout_type_onepage_save_order_after", array("order" => $order, "quote" => $quote));
try {
$order->sendNewOrderEmail();
}
catch(Exception $e) {
Mage::logException($e);
}
}
I tried this also but nothing works
$quote = Mage::getModel("sales/quote")->setStore(Mage::getSingleton("core/store")->load(1))->load($shoppingCartId);
$checkout = Mage::getSingleton('paypal/express_checkout', array(
'config' => Mage::getModel('paypal/config', array(Mage_Paypal_Model_Config::METHOD_WPP_EXPRESS)),
'quote' => $quote,
));
$detailsBlock = new Mage_Paypal_Block_Express_Review_Details();
$detailsBlock->setQuote($quote);
$checkout->updateShippingMethod("ups_GND");
$session->setLastQuoteId($shoppingCartId)->setLastSuccessQuoteId($shoppingCartId);
$order = $checkout->getOrder();
if ($order){
$session->setLastOrderId($order->getId())->setLastRealOrderId($order->getIncrementId());
echo "<br>".$order->getData();
}
Any help is much appreciated. :)

Magento auto-confirm order instead of admin

I see my orders in my admin panel and all have status "pending".
Is it possible that the orders are auto-confirmed without the admin having to do this?
You can make a custom extension for it, you can get help from here.
http://www.atwix.com/magento/auto-invoice-and-custom-order-status-upon-checkout/
Or
http://inchoo.net/magento/magento-orders/automatically-invoice-ship-complete-order-in-magento/
Yes There is a way to achieve this use the below code and call in from a cron on ur time basis, The code will change the state from pending to processing after 1 hour of placing order.
<?php
require_once('app/Mage.php');
Mage::app('admin');
$orders = Mage::getModel('sales/order')->getCollection()
->addFieldToFilter('status','pending')
->addFieldToFilter('created_at', array('lt' => new Zend_Db_Expr("DATE_ADD('".now()."', INTERVAL -'60:00' HOUR_MINUTE)")))
->addAttributeToSelect('customer_email')
->addAttributeToSelect('increment_id');
Mage::log("cod diret run from script cron start");
foreach ($orders as $order) {
$incrementId = $order->getIncrementId();
$individualOrder = Mage::getModel("sales/order")->loadByIncrementId($incrementId);
try {
if(!$individualOrder->canInvoice())
{
Mage::throwException(Mage::helper('core')->__('Cannot create an invoice.'));
}
$invoice = Mage::getModel('sales/service_order', $individualOrder)->prepareInvoice();
Mage::log("next");
if (!$invoice->getTotalQty()) {
Mage::throwException(Mage::helper('core')->__('Cannot create an invoice without products.'));
}
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
$invoice->register();
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder());
$transactionSave->save();
}
catch (Mage_Core_Exception $e) {
}
$OrderStatus = Mage::getModel("sales/order")->loadByIncrementId($incrementId);
$OrderStatus->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();
$orderid= $individualOrder->getEntityId();
$email = $order->getCustomerEmail();
}

Magento Order History Comments: Modify Date

I am creating a script to add orders programmatically in Magento. I need help to change the date of the entries in the Comments History (quote, invoice, shipping, etc.). I can manipulate the date of the order itself (setCreatedAt) and some of the comments related to the creation of the order are correct (e.g. "Sep 29, 2008 8:59:25 AM|Pending Customer Notification Not Applicable"), but I cannot change the date of the comment when I use addStatusHistoryComment...
Here's a snippet of my code:
try {
if(!$order->canInvoice()) {
Mage::throwException(Mage::helper('core')->__('Cannot create an invoice.'));
}
$invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice();
if (!$invoice->getTotalQty()) {
Mage::throwException(Mage::helper('core')->__('Cannot create an invoice without products.'));
}
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_OFFLINE);
$invoice->setCreatedAt('2008-09-23 13:05:20');
$invoice->register();
$invoice->getOrder()->setCustomerNoteNotify(true);
$invoice->getOrder()->setIsInProcess(true);
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($invoice)
- >addObject($invoice->getOrder());
$transactionSave->save();
//END Handle Invoice
//START Handle Shipment
$shipment = $order->prepareShipment();
$shipment->setCreatedAt('2008-09-23 14:20:10');
$shipment->register();
$order->setIsInProcess(true);
$order->addStatusHistoryComment('Shipping message goes here...', true);
$shipment->setEmailSent(true);
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($shipment)
->addObject($shipment->getOrder())
->save();
$track = Mage::getModel('sales/order_shipment_track')
->setShipment($shipment)
->setData('title', 'Some tracking no.')
->setData('number', '111222333444')
->setData('carrier_code', 'fedex') //custom, fedex, ups, usps, dhl
->setData('order_id', $shipment->getData('order_id'))
->save();
//END Handle Shipment
}
catch (Mage_Core_Exception $ex) {
echo "Problem creating order invoice and/or shipment: ".$ex."\n";
}
Thanks in advance.
If I understand your question correctly, you just need to do this:
$comments = $order->getStatusHistoryCollection(true);
$comments now contains a collection of all the status history comments, and you can loop over them with whatever sort of criteria you like.
foreach ($comments as $c) {
if ( /* some stuff */ ) {
$c->setData('created_at',$new_date)->save();
}
}
So this is untested, but should work:
You need to create a new method based off addStatusHistoryComment:
/app/code/core/Mage/Sales/Model/Order.php
/*
* Add a comment to order
* Different or default status may be specified
*
* #param string $comment
* #param string $status
* #return Mage_Sales_Model_Order_Status_History
*/
public function addStatusHistoryComment($comment, $status = false)
{
if (false === $status) {
$status = $this->getStatus();
} elseif (true === $status) {
$status = $this->getConfig()->getStateDefaultStatus($this->getState());
} else {
$this->setStatus($status);
}
$history = Mage::getModel('sales/order_status_history')
->setStatus($status)
->setComment($comment)
->setEntityName($this->_historyEntityName);
->setCreatedAt('2008-09-23 14:20:10'); //I added this line
$this->addStatusHistory($history);
return $history;
}
Obviously you either need to rewrite this method, or refactor the code to do the same.

Prevent subscriber saving in observer newsletter_subscriber_save_before Magento

I created an Observer to monitor the event subscriber_save_before. In this observer I handle a new field, the value of that is saved, but if some errors occurs I wanna the record not to be saved and to display only my error message. The throwException seems not to do the trick. The only method I think could work is to force the email field to null but wasn't able to achieve this.
In the subscriberController.php (Mage Core) I have this:
$email = (string) $this->getRequest()->getPost('email');
try {
if (!Zend_Validate::is($email, 'EmailAddress')) {
Mage::throwException($this->__('Please enter a valid email address.'));
}
This is my code (not working):
public function NewsletterSaveSubscriber($observer)
{
$subscriber = $observer->getEvent()->getSubscriber();
$name = Mage::app()->getRequest()->getParam('subscriber_name');
// server side validation
// no name specified
if (!Zend_Validate::is(trim($name), 'NotEmpty')) {
$session = Mage::getSingleton('core/session');
try {
Mage::throwException(Mage::helper('newsletter')->__('The name field cannot be empty!'));
} catch (Mage_Core_Exception $e) {
$session->addException($e, Mage::helper('newsletter')->__('There was a problem: %s', $e->getMessage()));
}
$observer->getRequest()->setPost('email', ''); // this code doesn't work
Mage::app()->getRequest()->setPost('email', ''); // this too
// Ohh nooo! The subscriber is stored :-(
return $this;
}
// save the name
$name = htmlspecialchars($name);
$subscriber->setSubscriberName($name);
return $this;
}
This will solve your probem:
//Error Message
$session = Mage::getSingleton('core/session');
$session->getMessages(true);
$session->addError(Mage::helper('cartware_automaticreview')->__('CouldĀ“t save.'));
// Ohh nooo! The subscriber is not stored :)
$controller = $observer->getControllerAction()->setFlag('',Mage_Core_Controller_Varien_Action::FLAG_NO_DISPATCH,true);
$controller->getResponse()->setRedirect(Mage::app()->getRequest()->getServer('HTTP_REFERER'));
return;
Good luck!

Magento SOAP API v2: Get currently logged in customer email address

Is it possible to get the currently logged in customer's email address using the SOAP API?
I will NOT have the CustomerID.
I will be calling this from our ExpressionEngine installation.
This change in /code/core/Mage/Customer/Model/Customer/Api.php should return the currently logged in customer with all their info. I cannot currently test because I don't have SOAP installed in my PHP 5.2.14 installation.
public function info($customerId, $attributes = null)
{
// if we didn't pass a $customerId
if (!$customerId) {
// get current customer session
$custsess = Mage::getSingleton('customer/session');
// if the customer is logged in
if($custsess->isLoggedIn() == true) {
// get their ID to load below
$customerId = $custsess->getId();
unset($custsess);
}
}
$customer = Mage::getModel('customer/customer')->load($customerId);
if (!$customer->getId()) {
$this->_fault('not_exists');
}
if (!is_null($attributes) && !is_array($attributes)) {
$attributes = array($attributes);
}
$result = array();
foreach ($this->_mapAttributes as $attributeAlias=>$attributeCode) {
$result[$attributeAlias] = $customer->getData($attributeCode);
}
foreach ($this->getAllowedAttributes($customer, $attributes) as $attributeCode=>$attribute) {
$result[$attributeCode] = $customer->getData($attributeCode);
}
return $result;
}

Resources