From a specific order I want to create shipment of that order and also allot tracking number to it programmatically.
Please help .
Thanks
The question was just for knowledge sharing purpose .
One can understand some points from Ref_Link
// $order_id = Order ID
$_order = Mage::getModel('sales/order')->load($order_id);
if($_order->canShip())
{
$shipmentId = Mage::getModel('sales/order_shipment_api')->create($_order->getIncrementId(), $itemsarray ,'your_comment' ,false,1);
echo $shipmentId; // Outputs Shipment Increment Number
$trackmodel = Mage::getModel('sales/order_shipment_api')
->addTrack($shipmentId,'your_shipping_carrier_code','your_shipping_carrier_title','carrier_tracking_number');
}
$itemsarray = format explained here Ref_link
Thats it !
A simple code snippet .
Hope it helps someone .
The accepted answer is correct and worked for me on CE 1.9, but I wanted to expand on it.
You don't need to bother with the $itemsQty parameter, you can pass an empty array(), or leave it out altogether. It's an optional parameter, and the method prepareShipment() in app\code\core\Mage\Sales\Model\Service\Order.php will check for that data and perform a lookup if necessary.
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);
create() method signature:
public function create($orderIncrementId, $itemsQty = array(), $comment = null,
$email = false, $includeComment = false)
See app\code\core\Mage\Sales\Model\Order\Shipment\Api.php for all methods.
Related
I am developing a custom payment gateway. It uses OrderIncrementID to identify which Order was the payment made for. I have every functionality running after the Order has been placed, i.e. after checkout, except one in the checkout page itself.
In the checkout page, Order was not created, getting an OrderIncrementID seems very difficult. We have to overwrite the order creation in the checkout such that it will be created after the payment method selection which sounds very complicated and dangerous to overwrite the flow. An alternative is to use QuoteID, but the tradeoff is that I have to implement a convertion from QuoteID to OrderIncrementID.
What can I do in this case to get an OrderIncrementID in the checkout page? especially after the payment method selection
You actually already have a reserved order id on the quote.
You just have to do :
$quote = Mage::getSingleton('checkout/session')->getQuote();
$quote->getReservedOrderId(); // this will be your order_increment_id
I developed bellow code to get next increment ID
I am not sure this will give correct result always.
But, this can help you
Please bellow code in any resource model to call
For example : place code in Names_Test_Model_Resource_Test class
public function getNextIncrementId(){
$store = Mage::app()->getStore();
$resource = Mage::getSingleton('core/resource');
$readConnection = $resource->getConnection('core_read');
$entityStoreTable = $resource->getTableName('eav_entity_store');
$entityTypeTable = $resource->getTableName('eav_entity_type');
$selectEntity = $readConnection->select()->from($entityTypeTable, "*")
->where("entity_type_code = 'order'");
$entityTypeRow = $readConnection->fetchRow($selectEntity);
if(isset($entityTypeRow['entity_type_id']) && $entityTypeRow['entity_type_id'] > 0){
$orderEntityTypeId = $entityTypeRow['entity_type_id'];
$entityStoreSelect = $readConnection->select()->from($entityStoreTable, "*")
->where("store_id = ? AND entity_type_id = $orderEntityTypeId", $store->getId());
$row = $readConnection->fetchRow($entityStoreSelect);
$lastIncrementId = 0;
if(isset($row['increment_last_id'])){
$lastIncrementId = $row['increment_last_id'] + 1;
}
return $lastIncrementId;
}
return 0;
}
To call this function you can use
$nextIncrementId = Mage::getResourceModel('test/test')->getNextIncrementId();
We can also find last increment id from orders table
Please comment for better solutions
I am trying to integrate jomsocial events with jomsocial groups.
What i am trying to achieve is to automatically create a group when the event is being created.
Would anyone have some hints regarding such functionality?
The approach i have in mind is to utilize a function onEventCreate($event) from jomsocial API
to call the group creation mechanism. Is that the right way to do it?
Yes, this is the approach I'd take.
You can find method save() in groups.php controller. There you've got all of the required code to implement this.
The rough code :
$my =& CFactory::getUser();
$config =& CFactory::getConfig();
$group =& JTable::getInstance( 'Group' , 'CTable' );
$group->name = $name;
$group->description = $description;
$group->categoryid = $categoryId; // Category Id must not be empty and will cause failure on this group if its empty.
$group->website = $website;
$group->ownerid = $my->id;
$group->created = gmdate('Y-m-d H:i:s');
$group->approvals = 0;
$params = new CParameter( '' );
// Here you need some code from private _bindParams()
$group->params = $params->toString();
$group->published = ( $config->get('moderategroupcreation') ) ? 0 : 1;
$group->store();
// Other useful stuff:
// - store the creator / admin into the groups members table
// - add into activity stream
isn't this the right method to get Name of logged in customer?
<?php echo Mage::helper('customer')->getCustomer()->getName(); ?>
I have a website with live chat functionality. Yesterday I have been asked to pass email address and the name of the logged into the user into the Javascript Tracking variable code placed in the head section of the website. So that the operators could see who is on the website and whom are they talking to without any need to ask about their information.
So I passed the information from Magento into the Javascript code but now I see this very strange thing happening. For example,
If I am logged in with credentials Name = John Email =
john12#yahoo.com
Then This name and email variable values are changing with the change of pages. For example if I click on any product page the variable values which I am passing changes to some other user's information.
Name becomes Ricky Email becomes ricky23#gmail.com
this variable values are kept on changing back to john and from john to something else with the change of pages. So operator does not have any idea whom are they talking because the values are kept on changing. Also, user ricky or who ever it changes to also exist in the database. so it is picking up random person from the database.
This is what i did to pass the code to javascript. Please let me know if that is not the right code to pass the information. Please check the php code I am using to fetch information from Magento. Roughly, I receive incorrect value once in 5 times. Please provide some assistance. Thanks in advance.
<?php
$customer = Mage::getSingleton('customer/session')->getCustomer();
$email = $customer->getEmail();
$firstname = $customer->getFirstname();
$lastname= $customer->getLastname();
$name = $firstname . ' ' . $lastname;
?>
<script type="text/javascript">
if (typeof(lpMTagConfig) == "undefined"){ lpMTagConfig = {};}
if (typeof(lpMTagConfig.visitorVar) == "undefined"){ lpMTagConfig.visitorVar = [];}
lpMTagConfig.visitorVar[lpMTagConfig.visitorVar.length] = 'Email=<?php echo $email; ?>';
lpMTagConfig.visitorVar[lpMTagConfig.visitorVar.length] = 'Name=<?php echo $name; ?>';
</script>
I'm also attaching a snap shot
I'd be interested to hear how you're adding this code to the page? Is it in it's own block, or are you adding it to footer.phtml, or similar? If your adding to an existing block be sure to check the block caching settings of that template.
To confirm the caching hypothesis I'd ask the following:
Do you get the same name, all the time, on the same page? When you refresh the page, do you get the same name and email in the Javascript?
Does the problem persist with caching disabled?
This doesn't sound like a singleton problem at all. Each execution of the PHP script is isolated from the others, serving one page request. There's no chance of another customer's object moving between invokations of the script.
It is a matter of understanding the singleton pattern. If you call your code twice:
$customer_1 = Mage::helper('customer')->getCustomer()->getName();
$customer_2 = Mage::helper('customer')->getCustomer()->getName();
you get two different instances of the object. But... if one of them has already implemented a singleton pattern in its constructor or has implemented a singleton getInstance then both objects will actually point to the same thing.
Looking at the customer/helper/Data.php code you can see the function
public function getCustomer()
{
if (empty($this->_customer)) {
$this->_customer = Mage::getSingleton('customer/session')->getCustomer();
}
return $this->_customer;
}
That means that in one of the cases singleton is already implemented/called and in other one - not as the property is already set.
The correct way to work with quote/customer/cart in order to get always the correct data is always to use the singleton pattern.
So using this:
$customer = Mage::getSingleton('customer/session')->getCustomer();
always guarantee that you get the correct customer in that session. And as may be you know singleton pattern is based on registry pattern in app/Mage.php:
public static function getSingleton($modelClass='', array $arguments=array())
{
$registryKey = '_singleton/'.$modelClass;
if (!self::registry($registryKey)) {
self::register($registryKey, self::getModel($modelClass, $arguments));
}
return self::registry($registryKey);
}
and looking at app/Mage.php:
public static function register($key, $value, $graceful = false)
{
if (isset(self::$_registry[$key])) {
if ($graceful) {
return;
}
self::throwException('Mage registry key "'.$key.'" already exists');
}
self::$_registry[$key] = $value;
}
...
public static function registry($key)
{
if (isset(self::$_registry[$key])) {
return self::$_registry[$key];
}
return null;
}
you can see that Magento checks is it is already set. If so, Magento will either throw an Exception, which is the default behavior or return null.
Hope this will help you to understand the issue you face.
I have sorted this out. I have moved the code from footer.phtml to head.phtml and it's working fine now.Values are not changing anymore. If anyone know the logic behind please post and I will change my answer. So far this is working.
I need to make a change of payment method to an order after it is placed. I have the order ID ($orderID), the order object ($order), a proper payment object, etc.
$service->retrievePaymentType() Returns the payment in the form of Mage_Sales_Model_Order_Payment
All of this happens in an extension of Mage_Checkout_Model_Type_Onepage
Does anybody know how I would go about doing this?
$order = Mage::getModel('sales/order')->load($orderID);
$service = Mage::getModel('sales/service_quote', $this->getQuote());
// Update Saved Order Payment Method
// $order->getPaymentsCollection()->clear();
$order->setPayment($service->retrievePaymentType());
$order->getPaymentsCollection()->save();
$order->save();
Thanks in advance!
Unfortunately, I had to do a direct SQL query, which is not Magento spec, but it gets the job done. If someone want's the code, leave me a comment, and I will dig it up.
Thanks though!
EDIT:
I managed to in fact get this working with Magento API:
// The payment type I want to change the target order to
$service = Mage::getModel('sales/service_quote', $this->getQuote());
$payment = $service->retrievePaymentType();
$paymentData = $payment->getData();
$oldPayment = $order->getAllPayments();
$oldPayment = $oldPayment[0];
foreach ($paymentData as $n => $v) {
$oldPayment->setData($n,$v);
}
It is a little bit hackish, but pretty effective.
i am trying to create a order and assign a shipping no for that order when a order is placed. But i see that when i have an invoice created and a shipment added , magento sets the order status to 'complete' automatically. I tried to change the status manually but it wouldn work.
$order = Mage::getModel('sales/order');
$order->loadByIncrementId($orderId);
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true);
$order->save();
Could some one suggest me how to over come this?
Also, how i add a custom carrier ? The default ones are DHL, FedEx , UPS.. I want to add one similar to them. This is how i am doing it:
$carrier = "dhl";
$title = "DHL";
$trackNumber = '538099';
if (1) {
$itemsQty = $order->getItemsCollection()->count();
$shipment =Mage::getModel('sales/service_order',$order)->prepareShipment($itemsQty);
$shipment = new Mage_Sales_Model_Order_Shipment_Api();
$shipmentId = $shipment->create($orderId);
$shipment->addTrack($shipmentId,$carrier,$title,$trackNumber);
}
For the carrier and title, if i give a custom name, i get a error invalid carrier in a report. How do i go about this? Thanks.
You could use the addStatusToHistory function. This is also used for adding comments.
$order->addStatusToHistory('processing', 'Order is being processed', false);
param 1 (string): The new status
param 2 (string): Your Comment
param 3 (boolean): If you want to send the customer an email notification.