I'm trying to create order from admin (for telephonic order). In that I've a situation that I need to get quote id from observer. I tried below observer(s)
sales_quote_save_after
sales_model_service_quote_submit_success
sales_quote_product_add_after
I tried to get id using this,
$id = $observer->getQuoteId();
And
I tried to print that quote items but I'm getting empty values.
Can any one help me to sort this out ?
In the event sales_quote_product_add_after the quote_item is passed to the Observer.
To get the quote from this Observer and the id:
public function yourMethod($observer)
{
$quoteItem = $observer->getEvent()->getQuoteItem();
$quote = $quoteItem->getQuote();
$id = $quote->getId();
}
In the event sales_model_service_quote_submit_success you have passed the order and the quote
public function yourMethod($observer)
{
$order= $observer->getEvent()->getOrder();
$quote= $observer->getEvent()->getQuote();
$id = $quote->getId();
}
In the event sales_quote_save_after you have passed quote since in app/code/core/Mage/Sales/Model/Quote.php
protected $_eventObject = 'quote';
Then in your observer you can get it:
public function yourMethod($observer)
{
$quote= $observer->getEvent()->getQuote();
$id = $quote->getId();
}
I fixed this using below solution,
I used below event
sales_quote_item_set_product
Actually I tried to set price for configurable product corresponding associated product's price. And my observer is,
$event = $observer->getEvent();
$quote_item = $event->getQuoteItem();
$storeId = $quote_item->getStoreId();
if(Mage::app()->getStore()->isAdmin()) {
$item = $observer->getQuoteItem();
$product = $observer->getProduct();
$sku = $product->getSku();
$productDetails = Mage::getModel('catalog/product')
->setStoreId($storeId)
->loadByAttribute('sku',$sku);
$price = $productDetails->getPrice();
$sprice = $productDetails->getFinalPrice();
$item->setOriginalCustomPrice($sprice);
$item->setOriginalPrice($price);
}
$quote = Mage::getSingleton('adminhtml/session_quote')->getQuote();
Related
I am trying to get product(s) name and price from product collection for that I have created a custom script for test.
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$state = $objectManager->get('\Magento\Framework\App\State');
$state->setAreaCode('adminhtml');
$collection = $objectManager->create('\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory')->create();
try {
echo $collection->addAttributeToSelect(['name','sku'])->getSelect();
} catch (Exception $exception) {
echo $exception->getMessage()."\n";
}
but when I run this script to check MySQL query I am getting below output:
SELECT `e`.* FROM `catalog_product_entity` AS `e`;
How can I get only product name and price instead of whole data?
As you're trying to get a product collection it's automatically going to get the main product entity table. It would need this in the query as a minimum as it needs the entity Id to be able to join with other tables to get the attributes required for the collection. You would not be able to retrieve your name attribute otherwise.
Note that this table is quite small and doesn't include any other attributes apart from the sku code.
If you dunp the data returned you'll see it doesn't actually grab all of the attributes, but it does need the main table.
If you have a specific need for only those two fields it would be better to use a custom query rather than a product collection.
I suggest you try this
public function getProductCollection()
{
$collection = $this->_productCollectionFactory->create();
$collection->addAttributeToSelect('*');
$collection->setPageSize(3); // fetching only 3 products
foreach ($productCollection as $product) {
$productPrice = $product->getPrice();
$productName = $product->getName();
}
}
Try this,
<?php
namespace BRINDA\HelloWorld\Block;
class HelloWorld extends \Magento\Framework\View\Element\Template
{
protected $productCollectionFactory;
protected $categoryFactory;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
\Magento\Catalog\Model\CategoryFactory $categoryFactory,
array $data = []
) {
$this->productCollectionFactory = $productCollectionFactory;
$this->categoryFactory = $categoryFactory;
parent::__construct($context, $data);
}
public function getProductCollection()
{
$collection = $this->productCollectionFactory->create();
$collection->setPageSize(3);
foreach ($collection as $product)
{
echo "<pre>";
print_r($product->getPrice());
print_r($product->getName());
}
return $collection;
}
}
<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$productCollection = $objectManager->create('Magento\Catalog\Model\ResourceModel\Product\CollectionFactory');
$collection = $productCollection->create()->addAttributeToSelect('*')->load();
foreach ($collection as $product){
echo 'Name = '.$product->getName().'<br>';
echo 'Price = '.$product->getFinalPrice().'<br>';
echo 'Url = '.$product->getProductUrl().'<br>';
echo 'Image = '.$product->getImage().'<br>';
}
?>
Try This.....
I am currently trying to add a product to my cart useing this code.
$quote = $this->_session->getQuote();
$quote->addProduct($product);
$this->_cartRepository->save($quote);
When I do this in a new session, the price of the product and the subtotal show as 0.00, but in the summary the Subtotal and Order Total are correct.
After editing the product quantity, the prices all function as they should.
I have tried to use $quote->collectTotals();, but this gives no visible changes.
How can I update cart so that the price of the product shows when I open the cart page?
Try with this code:
use Magento\Checkout\Model\Cart as Quote;
class Add {
protected $quote = null;
public function __construct( Quote $quote){
$this->quote = $quote;
}
public function test(\Magento\Catalog\Model\Product $product){
$options = ['qty'=> 1];
$this->quote->addProduct($product, $options);
//OR $this->quote->addProductsByIds([$product->getId()]);
$this->quote->save();
}
}
Or
public function test(\Magento\Catalog\Model\Product $product){
$quote = $this->_objectManager->get(\Magento\Checkout\Model\Cart:class);
$options = ['qty'=> 1];
$quote->addProduct($product, $options);
//OR $quote->addProductsByIds([$product->getId()]);
$quote->save();
}
You need to reload the quote from a DB to have all collectedTotals flags empty there.
/** #var \Magento\Quote\Api\CartRepositoryInterface $quoteRepository */
$quoteRepository->get($quoteId);
$quote->addProduct($product, $request);
$quote->collectTotals()->save();
See Magento\Quote\Model\Quote::collectTotals and Magento\Quote\Model\Quote\Address\Total\Subtotal::collect
Product Table
Product Attribute Table
My PostOrder Function
public function getPaymentStatus(Request $request){
if ($result->getState() == 'approved') {
$user_id = Auth::user()->id;
$user_email = Auth::user()->email;
//get shipping details
$shippingDetails = DeliveryAddress::where(['user_email'=>$user_email])->first();
$order = new Order;
$order->user_id = $user_id;
$order->user_email = $user_email;
$order->name = $shippingDetails->name;
$order->address = $shippingDetails->address;
$order->city = $shippingDetails->city;
$order->state = $shippingDetails->state;
$order->country = $shippingDetails->country;
$order->postcode = $shippingDetails->postcode;
$order->mobile = $shippingDetails->mobile;
$order->coupon_code = $coupon_code;
$order->coupon_amount = $coupon_amount;
$order->order_status = "New";
$order->grand_total = Session::get('grand_total');
$order->save();
$order_id = DB::getPdo()->lastInsertId();
$cartProducts = DB::table('cart')->where(['user_email'=>$user_email])->get();
foreach($cartProducts as $pro){
$cartPro = new OrdersProduct;
$cartPro->order_id = $order_id;
$cartPro->user_id = $user_id;
$cartPro->product_id = $pro->product_id;
$cartPro->product_code = $pro->product_code;
$cartPro->product_name = $pro->product_name;
$cartPro->product_size = $pro->size;
$cartPro->product_color = $pro->product_color;
$cartPro->product_price = $pro->price;
$cartPro->product_qty = $pro->quantity;
$cartPro->save();
}
return redirect('/thank-you');
}
i have a table "products" which store product details and a table "products_attribute" which store the stock of the product. I don't know how link this to products_attribute table. Please Help.
It looks like you already have a grasp of Eloquent Models with your Order and DeliveryAddress model.
To setup relationships between your Product and Product Attribute simply define the relationship method inside your Product model:
<?php
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
public function attributes()
{
return $this->hasMany('ProductAttribute');
}
}
Eloquent will use snake case in determining the name of foreign key, which in this case would be product_id. If your foreign key is defined differently you may specify the name as a second argument:
return $this->hasMany('ProductAttribute', 'my_product_id');
If you want to have a relationship from ProductAttribute to Product use the belongsTo method:
<?php
use Illuminate\Database\Eloquent\Model;
class ProductAttribute extends Model
{
public function product()
{
return $this->belongsTo('Product');
}
}
You may also specify a custom foreign key name similar to the hasMany method:
return $this->belongsTo('Product', 'my_product_id');
To update the quauntity you could do something like this:
foreach($cartProducts as $pro){
$cartPro = new OrdersProduct;
$cartPro->order_id = $order_id;
$cartPro->user_id = $user_id;
$cartPro->product_id = $pro->product_id;
$cartPro->product_code = $pro->product_code;
$cartPro->product_name = $pro->product_name;
$cartPro->product_size = $pro->size;
$cartPro->product_color = $pro->product_color;
$cartPro->product_price = $pro->price;
$cartPro->product_qty = $pro->quantity;
$cartPro->save();
$product = Product::find($pro->product_id);
if (null !== $product) {
// you will need a sku or some other unique identifier
// from your attribute to determine the correct attribute
// to modify after your order is complete
$attribute = $product->attributes()-where('sku', $sku)->first();
$attribute->quantity = $attribute->quantity - $pro->quantity;
$attribute->save();
}
}
you should use relationships here
first you create ProductModel
after that you create one method like attributes
and use hasMany relationships
so you can do whatever you want
I am building an order form and I warn you in advance I am a noob with backend dev :)
So my first component takes all data from the order form and saves it to the database, then I use this same data to generate a quote. After this I have a thrird part which generates the invoice if the quote is accepted, so far my code looks like this:
// this runs when order is submitted on front end (runs from same component)
public function onAddOrder() {
$this->submitOrder();
$this->submitQuote();
Flash::success('Order successfully submitted!');
return Redirect::to('/home');
}
public function submitOrder() {
// Add it to the database
$order = new Order();
$order ->quote_no = $this->generateQuoteNo();
$order ->company_name = Input::get('company_name');
$order ->client_name = Input::get('client_name');
$order ->client_email = Input::get('client_email');
$order ->emergency_contact = Input::get('emergency_contact');
$order ->due_date = Input::get('due_date');
$order ->project_name = Input::get('project_name');
$order ->quote_query = Input::get('quote_query');
$order ->order_no = Input::get('order_no');
$order ->order_type = Input::get('order_type');
$order ->save();
}
}
public function submitQuote() {
$quote = new Quote();
$quote->quote_no = $this->generateQuoteNo();
$quote->customer = Input::get('company_name');
$quote->job_name = Input::get('project_name');
$quote->order_no = Input::get('order_no');
$quote->proof_price = $this->calculateProofPrice();
$quote->sub_total = $this->calculateSubTotal();
$quote->vat = $this->calculateVat();
$quote->total = $this->calculateTotal();
$quote->save();
}
This works fine but then I would like to run another function if a selection is made but this component is under a different class and I am not sure how to reference it.
if (Input::get('quote_query') === 'Order') {
$this->AcmeInvoice->onSubmitInvoice();
}
If someone could help me to fire the public function onSubmitInvoice() I will really appreciate it.
You can instantiate the object in the class & fire it off? eg: $invoice = new AcmeInvoice(); //add namespace if not in the name space; $invoice->onSubmitInvoice();
if (Input::get('query') === 'Invoice') {
$invoice = new AcmeInvoice();
$invoice->onSubmitInvoice('quote_no');
}
I have a product that get values from another script and I have a product attribute name custom_value, I want to set the values from another script programmatically. I tried different methods but could not get it done. I tried this, it didn't worked
$quoteItem = $observer->getItem();
if ($additionalOptions = $quoteItem->getOptionByCode('stamp_design')) {
$orderItem = $observer->getOrderItem();
$options = $orderItem->getProductOptions();
$options['stamp_design'] = unserialize($additionalOptions->getValue());
$orderItem->setProductOptions($options);
}
I also tried this and it also didn't worked.
$product = $observer->getEvent()->getProduct();
// Write a new line to var/log/product-updates.log
$name = $product->getName();
$sku = $product->getSku();
$orderItem = $observer->getEvent()->getItem();
$options = $product->getProductOptions();
var_dump($options);
$options['custom_value'] = $_SESSION['generated_value'];
$product->setProductOptions($options);
$options = $product->getOptions();
They are giving Fatal error: Call to a member function xxxx on a non-object.
Can everybody provide me some solution, Magento version is 1.7 thanks.