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
Related
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.
I have created a link in Magento admin to create the invoice for individual product, But while calling the function $order->prepareInvoice($qtys) it will add all the product in invoice even I am passing only one item.
I am using below code.
$order = Mage::getModel('sales/order')->load($this->getRequest()->getParam('order_id'));
$count = $order->getTotalItemCount();
$qtys = Array
(
[370] => 1
);
$invoice = $order->prepareInvoice($qtys);
if (!$invoice->getTotalQty()) {
Mage::throwException(Mage::helper('core')->__('Cannot create an invoice without products.'));
}
$amount = $invoice->getGrandTotal();
$invoice->register()->pay();
$invoice->getOrder()->setIsInProcess(true);
$history = $invoice->getOrder()->addStatusHistoryComment('Partial amount of $'. $amount .' captured automatically.', false);
$history->setIsCustomerNotified(true);
$order->save();
Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder())
->save();
$invoice->save();
Any Suggestion ?
The logic found in Mage_Sales_Model_Service_Order::prepareInvoice, the method which you are ultimately calling to prepare the invoice, reveals what is at play here. The following loop is employed, and the inner else-if block is where the qty is set when an array of qtys is passed in:
foreach ($this->_order->getAllItems() as $orderItem) {
if (!$this->_canInvoiceItem($orderItem, array())) {
continue;
}
$item = $this->_convertor->itemToInvoiceItem($orderItem);
if ($orderItem->isDummy()) {
$qty = $orderItem->getQtyOrdered() ? $orderItem->getQtyOrdered() : 1;
} else if (!empty($qtys)) {
if (isset($qtys[$orderItem->getId()])) {
$qty = (float) $qtys[$orderItem->getId()];
}
} else {
$qty = $orderItem->getQtyToInvoice();
}
$totalQty += $qty;
$item->setQty($qty);
$invoice->addItem($item);
}
The $qtys variable is the array which you are passing in to the prepareInvoice call. In your case, you are only passing an index for the item you wish to add to the invoice. Per the documentation (and the above loop), this should work, except for one minor problem: the above loop is not resetting the value of $qty at the top of the loop to 0. This does not pose a problem when called from the core code which processes initialization of the invoice when created from the admin via the pre-existing form, as the form which is being submitted will always contain a value for each item on the order, and in the case of only 1 item being invoiced, all others will hold a 0 qty value thus working around the failure to reset the value of $qty.
To solve your problem, try setting your $qtys variable like so (I'm assuming 370 and 371 are the two order item entity ids):
$qtys = array(
370 => 1,
371 => 0,
);
An alternative which I might suggest would be to simply have your "Create Invoice" link set the appropriate values in the form to invoice the individual item and then submit the form directly. This way you'll be relying on the known-to-be-working core controller for the heavy lifting. This will, of course, only work if you are not doing anything fairly customized beyond invoicing the single item. :)
I want to show popup when a product is first added to cart in Magento and don't want to show a popup if the product was added again or updated.In short, I want to know product which is going to be added in the cart is First occurence or not?
The answer largely depends on how you want to deal with parent/child type products (if you need to).
If you are only dealing only with simple products or you have parent/child type products and you need to test for child id's then:
$productId = 1;
$quote = Mage::getSingleton('checkout/session')->getQuote();
if (! $quote->hasProductId($productId)) {
// Product is not in the shopping cart so
// go head and show the popup.
}
Alternatively, if you are dealing with parent/child type products and you only want to test for the parent id then:
$productId = 1;
$quote = Mage::getSingleton('checkout/session')->getQuote();
$foundInCart = false;
foreach($quote->getAllVisibleItems() as $item) {
if ($item->getData('product_id') == $productId) {
$foundInCart = true;
break;
}
}
EDIT
The question was asked in a comment as to why setting a registry value in controller_action_predispatch_checkout_cart_add is not available to retrieve in cart.phtml.
Essentially registry value are only available through the life of a single request - you are posting to checkout/cart/add and then being redirected to checkout/cart/index - so your registry values are lost.
If you would like to persist a value across these then you can use the session instead:
In your observer:
Mage::getSingleton('core/session')->setData('your_var', 'your_value');
To retrieve the value
$yourVar = Mage::getSingleton('core/session')->getData('your_var', true);
The true flag being passed to getData will remove the value from the session for you.
In order check if the product is already in cart or not, you can simply use the following code:
$productId = $_product->getId(); //or however you want to get product id
$quote = Mage::getSingleton('checkout/session')->getQuote();
$items = $quote->getAllVisibleItems();
$isProductInCart = false;
foreach($items as $_item) {
if($_item->getProductId() == $productId){
$isProductInCart = true;
break;
}
}
var_dump($isProductInCart);
Hope this helps!
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 followed the steps in creating a payment method in this tutorial (http://www.magentocommerce.com/wiki/5_-_modules_and_development/payment/create-payment-method-module) everything works fine, but i need an additional functionality.
additional 6% charge to the total if the payment method is selected.
I also use this module - http://www.magentocommerce.com/magento-connect/payment-method-charge-4050.html but I need 2 condition. That is why I created new payment method.
1st payment method - 6% charge
2nd payment method - 2% charge
Thanks in advance.
More than likely your going to want to just create an observer to do what your are needing:
You'll need to look around for the proper observer event to hook into, however here is an example observer method:
public function updateShippingAmount( $observer )
{
$MyPaymentMethod = Mage::getSingleton('namespace/mypaymentmethod');
$order = $observer->getEvent()->getOrder();
$payment = $order->getPayment()->getData();
if( $payment['method'] == $MyPaymentMethod->getCode() )
{
$shipping_amount = $order->getShippingAmount();
$order->setShippingAmount( $shipping_amount + $MyPaymentMethod->getPostHandlingCost() );
}
}
Taken from this article:
http://www.candesprojects.com/magento/add-payment-method-handling-cost/
More reading on how to create an observer:
http://www.magentocommerce.com/wiki/5_-_modules_and_development/0_-_module_development_in_magento/customizing_magento_using_event-observer_method
Recently I have the same requirement and I fixed by implementing event-observer method.
In fact you can add any additional shipping cost to any shipping method for any condition by implementing event called sales_quote_collect_totals_before
And the observer model method(dummy code though) looks like:
public function salesQuoteCollectTotalsBefore(Varien_Event_Observer $observer)
{
/**#var Mage_Sales_Model_Quote $quote */
$quote = $observer->getQuote();
$someConditions = true; //this can be any condition based on your requirements
$newHandlingFee = 15;
$store = Mage::app()>getStore($quote>getStoreId());
$carriers = Mage::getStoreConfig('carriers', $store);
foreach ($carriers as $carrierCode => $carrierConfig) {
if($carrierCode == 'fedex'){
if($someConditions){
Mage::log('Handling Fee(Before):' . $store->getConfig("carriers/{$carrierCode}/handling_fee"), null, 'shipping-price.log');
$store->setConfig("carriers/{$carrierCode}/handling_type", 'F'); #F - Fixed, P - Percentage
$store->setConfig("carriers/{$carrierCode}/handling_fee", $newHandlingFee);
###If you want to set the price instead of handling fee you can simply use as:
#$store->setConfig("carriers/{$carrierCode}/price", $newPrice);
Mage::log('Handling Fee(After):' . $store->getConfig("carriers/{$carrierCode}/handling_fee"), null, 'shipping-price.log');
}
}
}
}