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.
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 want to catch all placed order with an observer to use the data in a further process.
In my Observer I wrote:
class Custom_CrmApi_Model_Observer extends Varien_Object {
….
public function placeOrder( $observer ){
$order = $observer->getOrder();
$payment = $order->getPayment();
$transId = $order->getPayment()->getTransactionId();
//$transId = $order->getPayment()->getLastTransId();
....
But the transaction ID of all ebay orders is empty (but not in the backend). I am using the M2E extension for ebay integration. But that shouldn’t be the problem, because the observer catch any placed order, or? At this time the transaction Id supposed to be available. But for some reason it isn’t available.
Any ideas? Perhaps a work around?
Thank you so much in advanced,
Hannes
It may be too late for you but maybe works for someone else.
I used this code to get the Transaction id for my report. It is on a different place then the normal ones for m2epro orders.
$additional_data = $order->getPayment()->getData();
//print_r($additional_data['additional_data']);
$component_mode = $additional_data['additional_data'];
additional_data in payment gives you the information about the transaction.
I am getting channel, payment, channel_order_id, channel_final_fee, transaction_id, fee, sum and transaction_date from aditional_data of the order. It is possible to get the same data from the same place on placeOrder function in m2epro.
app\code\community\Ess\M2ePro\Model\Magento\Order.php -> placeOrder
if (version_compare(Mage::helper('M2ePro/Magento')->getVersion(false), '1.4.1', '>=')) {
/** #var $service Mage_Sales_Model_Service_Quote */
$service = Mage::getModel('sales/service_quote', $this->quote);
$service->submitAll();
// You can get this order before you return it and get the data maybe!
return $service->getOrder();
}
Worths to try.
Cheers
I am trying to build a Magento module that observes certain events and tries to proceed automatically to a new automatic status/state, based on payment method.
In order to do that, I organized some status on the backoffice based on payment method. For example:
event: sales_order_place_after
Automatic status: pp_1_pending - First status/state where a new placed order will automatically have this status if the payment method is paypal.
event: sales_order_payment_pay
Automatic status: pp_2_payment - Second status/state after an order is payed when the payment method is paypal
event: sales_order_invoice_save_after
Automatic status: pp_3_complete- Third and final status/state after an order is invoiced, ending the transaction.
For this to work I would need to collect all status with the prefix pp_ and after checking which was set on the order, proceed to the next status in order. This way this module would be scalable.
However I can't seem to get the status collection. I am trying:
$statuses = Mage::getModel('sales/order_status')
->getCollection()
->addAttributeToSelect('status')
->addAttributeToSelect('label')
->addFieldToFilter('status',array('like','pp_'));
Hope anyone can help me. Thanks all!
The addAttributeToSelect() function is used for EAV based models.For flat models use addFieildToSelect()
The code should be
$statuses = Mage::getModel('sales/order_status')
->getCollection()
->addFieldToSelect('status')
->addFieldToSelect('label')
->addFieldToFilter('status',array('like'=>'pp_%'));
Have a look at the generated SELECT query if it looks ok.
$collection->getSelect()->__toString();
you have to use the wildcard (%) in your query, because you want the statuses that begin with pp_:
$statuses = Mage::getModel('sales/order_status')
->getCollection()
->addAttributeToSelect('status')
->addAttributeToSelect('label')
->addFieldToFilter('status',array('like','pp_%'));
in case someone is wondering, to get both states and status together, here's a function for you:
private function _allStatusStateCollection($filter) {
$collection = Mage::getModel( 'sales/order_status' )
->getCollection()->joinStates();
if ($filter != '') { return $collection->addFieldToFilter('main_table.status',array('like'=>$filter.'%')); }
return $collection;
}
As the title says,i need to mass-assign products to a category and from the admin i can only edit one product at a time; i dont know why it just doesnt work to mass add them from the "category products" tab in the category page.
Thats why i need another method that's fast,like using phpMyAdmin or something alike.
Any help?
Thanks in advance!
I created a simple script to do this outside of Magento. Be sure to test this first on a single product and make sure it looks as you'd expect.
// Load Magento
require_once 'path/to/app/Mage.php';
Mage::app();
// $productIds is an array of the products you want to modify.
// Create it however you want, I did it like this...
$productsIds = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('sku', array('like' => 'something'))
->getAllIds();
// Array of category_ids to add.
$newCategories = array(20);
foreach ($productIds as $id) {
$product = Mage::getModel('catalog/product')->load($id);
$product->setCategoryIds(
array_merge($product->getCategoryIds(), $newCategories)
);
$product->save();
}
If you wish to overwrite a product's existing categories, change array_merge(...) to just $newCategories.
I would shy away from tackling this problem from the database side of things. If you do go that direction make sure and take lots of backups and do it during low usage.
The following thread on the Magento forum identifies the very same problem. One poster recommends a raw sql approach with example. Again, I would be careful - make sure you take backups.
The answer I like best from the thread (posted by Magento MVP):
Go into the category you don’t want them in, find the product list.
Click the check boxes on the products you want to remove and select
delete from the little dropdown.
Now go into the category where you
do want them, go to the product list. Select the NO dropdown so it
shows items not in the category. You might have to do a selective
search to limit stuff and do it in a couple iterations. Click the
check boxes and tell it to add stuff.
You may as well do this using the magento API
This is the script I use for mass adding products. sku.txt contains one sku per line.
<?php
$wsdlUrl = "magento-root/index.php/api/soap/?wsdl";
$proxy = new SoapClient($wsdlUrl);
$sessionId = $proxy->login('apiuser', 'apipasswd');
$listOfDiscountedSKUFile = "sku.txt";
function readinFile($filePath)
{
$fp = fopen($filePath,'r') or exit("Unable to open file!");
$dataItems = array();
while(!feof($fp))
{
$dataItems[] = trim(fgets($fp));
}
fclose($fp);
var_dump($dataItems);
return $dataItems;
}
function addToCategory($sku,$categoryId)
{
global $proxy,$sessionId;
$proxy->call($sessionId, 'category.assignProduct', array($categoryId, $sku));
}
function IsNullOrEmptyString($question){
return (!isset($question) || trim($question)==='');
}
$categoryId = 82;//e.g.
$listOfSKU = readinFile($listOfDiscountedSKUFile);
foreach($listOfSKU as $sku)
{
addToCategory($sku,$category);
}
?>
I managed to resolve the problem with the following code :
$write = Mage::getSingleton('core/resource')->getConnection('core_write');
$x = 1171;
$y = 2000;
$categoryID = 4;
$productPosition = 0;
while($x <= $y) {
$write->query("REPLACE INTO `catalog_category_product` (`category_id`, `product_id`, `position`) VALUES ($categoryID, $x++, $productPosition)");
}
echo "The job is done";
?>
I hope the code is clear for everyone,if it's not,reply and i'll try to explain it.
#nachito : here it is.
I'm trying to write a Magento (CE 1.4) extension to export order data once an order has been paid for. I’ve set up an observer that hooks in to the sales_order_invoice_save_after event, and that is working properly - my function gets executed when an invoice is generated. But I’m having trouble getting information about the order, such as the shipping address, billing address, items ordered, order total, etc.
This is my attempt:
class Lightbulb_Blastramp_Model_Observer {
public function sendOrderToBlastramp(Varien_Event_Observer $observer) {
$invoice = $observer->getEvent()->getInvoice();
$order = $invoice->getOrder();
$shipping_address = $order->getShippingAddress();
$billing_address = $order->getBillingAddress();
$items = $invoice->getAllItems();
$total = $invoice->getGrandTotal();
return $this;
}
}
I tried doing a print_r on all those variables, and ended up getting a lot of data back. Could someone point me in the right direction of getting the shipping address of an order?
Thanks!
Many Magento objects are based on Varien_Object, which has a method called getData() to get just the usually interesting data of the object (excluding the tons of other, but mostly useless data).
With your code you could either go for all the data at once:
$shipping_address = $order->getShippingAddress();
var_dump($shipping_address->getData());
or directly for specific single properties like this:
$shipping_address = $order->getShippingAddress();
var_dump(
$shipping_address->getFirstname(),
$shipping_address->getLastname(),
$shipping_address->getCity()
);
To understand how this works, I'd recommend to make yourself more familiar with the Varien_Object and read a bit about PHPs magic methods, like __call(), __get() and __set().
Try print_r($shipping_address->toArray());