Update the product status in Magento 2
When updating the status of a product I get the following issue:
UpdateStatus.php
public function __construct(
ProductRepositoryInterface $productRepository,
SearchCriteriaBuilder $searchCriteriaBuilder,
Product $product,
Configurable $configurable,
StockItem $stockItem,
State $state
)
{
parent::__construct();
$this->productRepository = $productRepository;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->_product = $product;
$this->configurable = $configurable;
$this->stockItem = $stockItem;
$this->state = $state;
}
protected function execute(InputInterface $input, OutputInterface $output): ?int
{
$this->state->setAreaCode(Area::AREA_ADMINHTML);
$product = $this->_product->loadByAttribute('sku', '46-50953763');
$product->setStatus(2);
$product->save();
return 0;
}
And also I tried using the repository:
$product = $this->productRepository->get('46-50953763');
$product->setStatus(2);
try {
$this->productRepository->save($product);
} catch (\Exception $e) {
var_dump($e->getMessage());
}
What is the way to update a magento product from command line?
Related
I am new to magento. I need to automatically create a csv file whenever an order is placed by the customer.
I am using the event "sales_order_place_after" but the code in the observer is not working.
Can anyone guide me how to generate the csv file successfully whenever the order gets placed.
i keep getting errors like: Object of class Magento\Sales\Model\Order\Address could not be converted to string
Class Order implements ObserverInterface
{
protected $_request;
protected $_order;
protected $_productRepository;
protected $_scopeConfig;
protected $_customer;
protected $_storemanager;
public function __construct(
\Magento\Framework\App\RequestInterface $request,
\Magento\Sales\Model\Order $order,
\Magento\Framework\App\Response\Http\FileFactory $fileFactory,
Filesystem $filesystem,
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
\Magento\Customer\Model\Customer $customer,
\Magento\Store\Model\StoreManagerInterface $storemanager,
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Sales\Model\OrderFactory $orderFactory,
\Magento\Framework\ObjectManager\ObjectManager $objectManager,
\Psr\Log\LoggerInterface $logger,
\Magento\Catalog\Model\ProductFactory $productFactory,
\Magento\Catalog\Model\ProductRepository $productRepository
) {
$this->_scopeConfig = $scopeConfig;
$this->_customer = $customer;
$this->_storemanager = $storemanager;
$this->_request = $request;
$this->_order = $order;
$this->_fileFactory = $fileFactory;
$this->directory = $filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
$this->_productRepository = $productRepository;
}
public function execute(\Magento\Framework\Event\Observer $observer) {
$order = $observer->getEvent()->getOrder();
$websiteID = $this->_storemanager->getStore()->getWebsiteId();
$headers = array( 'Customer Name', 'Customer Email', ' Phone','Shipping Address' ,'SKU','Quantity','Price','Total','Weight');
$name = strtotime('now');
$file = 'customorderexport/'.$name.'_detailed_orderexport.csv';
$this->directory->create('customorderexport');
$stream = $this->directory->openFile($file, 'w+');
$stream->lock();
$stream->writeCsv($headers);
// $orderdetail['Customer Name'] =
$orderdetail['Customer Email'] = $order->getCustomerEmail();
$orderdetail['Contact Phone'] = $order->getTelephone();
$orderdetail['Shipping Address'] = $order->getShippingAddress();
$items = $order->getAllItems();
foreach ($items as $item) {
$orderdetail['SKU'] = $item->getSKU();
$orderdetail['Quantity'] = $item->getQtyOrdered();
$orderdetail['Price'] = $item->getPrice();
$orderdetail['Total'] = $item->getGrandTotal();
$orderdetail['Weight'] = $item->getWeight();
$stream->writeCsv($orderdetail);
}
$stream->unlock();
$stream->close();
}
}
This is because
$order->getShippingAddress();
will return a OrderAddressInterface object. (Magento\Sales\Api\Data\OrderAddressInterface)
You could do following for example:
$shippingAddress = $order->getShippingAddress();
$orderdetail['Shipping Address'] = $shippingAddress->getStreet()[0];
I am trying to fetch all child product Ids from configurable product Ids.
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$product = $objectManager->create('\Magento\Catalog\Model\Product');
$storeManager = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface');
$currentStore = $storeManager->getStore();
$mediaUrl = $currentStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
$productURL = $mediaUrl.'catalog/product';
$collection = $this->_productCollectionFactory->create();
$productCollection = $collection->addAttributeToSelect('*')->addAttributeToFilter('type_id','configurable');
$vendor_product = array();
$productData = $product->getData();
foreach($productCollection as $prodObj){
$productData = array();
$product = $product->load($prodObj->getId());
$productTypeInstance = $product->getTypeInstance();
$usedProducts = $productTypeInstance->getUsedProducts($product);
foreach ($usedProducts as $child) {
$productData['childrenIds'][] = $child->getId();
}
I get Ids of my first configurable product in all the cases
<?php
namespace Vendor\Module\Block;
class ParentAndChilds extends \Magento\Framework\View\Element\Template
{
/**
* #var Context
*/
protected $context;
/**
* #var ProductRepositoryInterface
*/
protected $productRepository;
/**
* #var SearchCriteriaBuilder
*/
protected $searchCriteriaBuilder;
/**
* #var LinkManagementInterface
*/
protected $linkManagement;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\ConfigurableProduct\Api\LinkManagementInterface $linkManagement,
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
\Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
array $data = []
)
{
$this->linkManagement = $linkManagement;
$this->productRepository = $productRepository;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
parent::__construct($context, $data);
}
public function getParentsAndChilds()
{
$searchCriteria = $this->searchCriteriaBuilder
->addFilter('type_id', 'configurable')
->create();
$configurableProducts = $this->productRepository
->getList($searchCriteria);
$parentAndChildProducts = array();
foreach ($configurableProducts->getItems() as $configurableProduct) {
$childProducts = $this->linkManagement
->getChildren($configurableProduct->getSku());
foreach ($childProducts as $childProduct) {
$parentAndChildProducts[$configurableProduct->getId()][] = $childProduct->getId();
}
}
return $parentAndChildProducts;
}
}
To get child product Ids from a configurable product, you can use below code:
public function __construct(
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository
) {
$this->productRepository = $productRepository;
}
public function execute()
{
$_productId=57786;
$_product=$this->productRepository->getById($_productId);
$childIs=$_product->getExtensionAttributes()->getConfigurableProductLinks();
print_r($childIs);
}
Output looks like:
Array
(
[31981] => 31981
[31982] => 31982
[31983] => 31983
)
Hope it will help you.
$_children = $_product->getTypeInstance()->getUsedProducts($_product);
foreach ($_children as $child){
$childProducts[] = $child;
}
$_product is the configurable product object
You can use the below code for getting Child ID.
$product = $block->getProduct();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$configurable_product_id = $product->getId();
$configurableProduct = $objectManager->get('Magento\Catalog\Model\ProductRepository')->getById($configurable_product_id);
$children = $configurableProduct->getTypeInstance()->getUsedProducts($configurableProduct); $childIds = array();
foreach ($children as $child){
$childIds[] = $child->getId();
}
sort($childIds);
print_r($childIds);
This is for sample code but I suggest do not use $objectManager directly, you can use Block on Plugin Method to get Product Object.
To get all simple children including out of stock products use:
$children = $product
->getTypeInstance()
->getChildrenIds($product->getId());
print_r($children);
I try to get order related information like order status, total amount, payment method etc.
I got order status using
$_order->getStatusLabel();
But how I get payment method-related information in Magento 2.
In Block file
/** #var \Magento\Sales\Model\ResourceModel\Order\Payment\Collection */
protected $_paymentCollectionFactory;
/** #var \Magento\Sales\Model\ResourceModel\Order\CollectionFactory */
protected $_orderCollectionFactory;
/** #var \Magento\Sales\Model\ResourceModel\Order\Collection */
protected $orders;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,\Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory, \Magento\Sales\Model\ResourceModel\Order\Payment\CollectionFactory $paymentCollectionFactory, array $data = []
) {
$this->_orderCollectionFactory = $orderCollectionFactory;
$this->_paymentCollectionFactory = $paymentCollectionFactory;
parent::__construct($context, $data);
}
public function getPaymentsCollection() {
$collection = $this->_paymentCollectionFactory->create()->addFieldToSelect('*');
return $collection;
}
public function getOrders($storeId) {
if (!$this->orders) {
$this->orders = $this->_orderCollectionFactory->create()->addFieldToSelect('*');
}
return $this->orders;
}
In phtml file
$_orders = $block->getOrders();
if ($_orders && count($_orders)) {
$payments = $block->getPaymentsCollection();
$chekmo = $cod = $free = $bank = $paypalgrp = 0;
foreach ($payments as $_payment) {
$method = $_payment->getMethod();
switch ($method) {
case 'checkmo' : $chekmo++;
break;
case 'cashondelivery' : $cod++;
break;
case 'free' : $free++;
break;
case 'banktransfer' : $bank++;
break;
case 'paypal_group_all_in_one' : $paypalgrp++;
break;
}
}
echo "Payment Methods<br>";
echo "Check / Money Order Methods " . $ckeckmo;
echo "Cash on Delivery Methods " . $cod;
echo "Free Methods " . $free;
echo "Bank Transfer Methods " . $bank;
echo "Paypal group all in one Methods " . $paypalgrp;
}
else{
echo "You have no Orders";
}
Following code will be helpful
$orderId = 1001;
$order = $this->order->load($orderId);
$method=$order->getPayment()->getMethod();
$expmonth=$order->getPayment()->getCcExpMonth();
$expyear=$order->getPayment()->getCcExpYear();
$cclast4=$order->getPayment()->getCcLast4();
$ipaddress=$order->getRemoteIp();
$billingaddress=$order->getBillingAddress();
$billingcity=$billingaddress->getCity();
$billingstreet=$billingaddress->getStreet();
$billingpostcode=$billingaddress->getPostcode();
$billingtelephone=$billingaddress->getTelephone();
$billingstate_code=$billingaddress->getRegionCode();
$shippingaddress=$order->getShippingAddress();
$shippingcity=$shippingaddress->getCity();
$shippingstreet=$shippingaddress->getStreet();
$shippingpostcode=$shippingaddress->getPostcode();
$shippingtelephone=$shippingaddress->getTelephone();
$shippingstate_code=$shippingaddress->getRegionCode();
$tax_amount=$order->getTaxAmount();
$total=$order->getGrandTotal();
It's work like a charm
I'm beginner for Zend Framework and using Zend Framework 2.5 veresion. I'm getting same issue and can't be resolved.My Model.php is different than show above.
Model.php
namespace User;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements AutoloaderProviderInterface, ConfigProviderInterface{
public function getAutoloaderConfig(){
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__.'/src/'.__NAMESPACE__,
)
)
);
}
public function getConfig(){
return include __DIR__. '/config/module.config.php';
}
}
My 'tbl_user' has fields with '_' like 'first_name', 'last_name', 'contact_num' which are not listing. other without underscore '_' fields are listing.
What is wrong with me, can anyone help me?
My output is:
User\Model\User Object
(
[id:protected] => 4
[first_name:protected] =>
[last_name:protected] =>
[contact_num:protected] =>
[email:protected] => dev#email.com
[designation:protected] => C++Programmer
[text:protected] =>
[name:protected] =>
[profile_pic:protected] =>
)
here is my Model 'User.php'
<?php
namespace User\Model;
class User implements UserInterface{
protected $id;
protected $first_name;
protected $last_name;
protected $contact_num;
protected $email;
protected $designation;
protected $text;
protected $name;
protected $profile_pic;
public function getId(){
return $this->id;
}
public function setId($id){
$this->id = $id;
}
public function getName(){
return $this->name;
}
public function setName($first_name, $last_name){
$this->name = $first_name.' '.$last_name;
}
public function getContact(){
return $this->contact_num;
}
public function setContact($contact_num){
$this->contact_num = $contact_num;
}
public function getEmail(){
return $this->email;
}
public function setEmail($email){
$this->email = $email;
}
public function getDesignation(){
return $this->designation;
}
public function setDesignation($designation){
$this->designation = $designation;
}
public function getProfilePic(){
return $this->profile_pic;
}
public function setProfilePic($profile_pic){
$this->profile_pic = $profile_pic;
}
/*public function getText(){
return $this->text;
}
public function setText($text){
$this->text = $text;
}*/
}
?>
and this is my 'ZendDbSqlMapper.php'
<?php
namespace User\Mapper;
use User\Model\UserInterface;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\Adapter\Driver\ResultInterface;
use Zend\Db\ResultSet\HydratingResultSet;
use Zend\Stdlib\Hydrator\HydratorInterface;
use Zend\Db\Sql\Sql;
use Zend\Db\Sql\Insert;
use Zend\Db\Sql\Update;
class ZendDbSqlMapper implements UserMapperInterface{
protected $dbAdapter;
protected $hydrator;
protected $userPrototype;
public function __construct(
AdapterInterface $dbAdapter,
HydratorInterface $hydrator,
UserInterface $userPrototype
){
$this->dbAdapter = $dbAdapter;
$this->hydrator = $hydrator;
$this->userPrototype = $userPrototype;
}
public function find($id){
$sql = new Sql($this->dbAdapter);
$select = $sql->select('tbl_users');
$select->where(array('id = ?' => $id));
$stmt = $sql->prepareStatementForSqlObject($select);
$result = $stmt->execute();
if($result instanceof ResultInterface && $result->isQueryResult() && $result->getAffectedRows()){
return $this->hydrator->hydrate($result->current(), $this->userPrototype);
}
throw new \InvalidArgumentException("User with given ID:{$id} not found");
}
public function findAll(){
$sql = new Sql($this->dbAdapter);
$select = $sql->select('tbl_users');
$stmt = $sql->prepareStatementForSqlObject($select);
$result = $stmt->execute();
//\Zend\Debug\Debug::dump($result); die;
if($result instanceof ResultInterface && $result->isQueryResult()){
//$resultSet = new ResultSet();
$resultSet = new HydratingResultSet($this->hydrator, $this->userPrototype);
//\Zend\Debug\Debug::dump($resultSet->initialize($result)); die;
return $resultSet->initialize($result);
}
return array();
}
public function save(UserInterface $userObject){
$userData = $this->hydrator->extract($userObject);
unset($userData['id']);
if($userObject->getId()){
$action = new Update('tbl_users');
$action->setData($userData);
$action->where(array('id = ?' => $userObject->getId()));
}else{
$action = new Insert('tbl_users');
$action->values($userData);
}
$sql = new Sql($this->dbAdapter);
$stmt = $sql->prepareStatementForSqlObject($action);
$result = $stmt->execute();
if($result instanceof ResultInterface){
if($newId = $result->getGeneratedValue()){
$userObject->setId($newId);
}
return $userObject;
}
return new \Exception("Database Error");
}
}
?>
here is 'ListController.php'
<?php
namespace User\Controller;
use User\Service\UserServiceInterface;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class ListController extends AbstractActionController{
protected $userService;
public function __construct(UserServiceInterface $userService){
$this->userService = $userService;
}
public function indexAction(){
return new ViewModel(array(
'users' => $this->userService->findAllUsers()
));
}
public function detailAction(){
$id = $this->params()->fromRoute('id');
try {
$user = $this->userService->findUser($id);
}catch(\InvalidArgumentException $ex){
return $this->redirect()->toRoute('user');
}
return new ViewModel(
array( 'user' =>$user )
);
}
}
?>
thank you.
In one of these php frameworks I've noticed a posibility to request the object Request in action as $this->request->paramName
class MyRequest extends Zend_Controller_Request_Http{
public $params = array();
public function __construct() {
$this->params = $this->getParams();
parent::__construct();
}
public function __get($name) {
if (isset($this->_params[$name])) {
return $this->_params[$name];
}
}
public function __isset($name) {
return isset($this->_params[$name]);
}
}
in MyController I've added variable request
public $request = null;
How can I change that standart Request to my one?
public function __construct(
Zend_Controller_Request_Abstract $request,
Zend_Controller_Response_Abstract $response,
array $invokeArgs = array()) {
$request = new MyRequest();
parent::__construct($request, $response, $invokeArgs);
$this->request = $this->getRequest();
}
This function has given no results.
Option 1 is make method _initRequest() in bootstrap:
protected function _initRequest() {
$this->bootstrap ( 'FrontController' );
$front = $this->getResource ( 'FrontController' );
$request = $front->getRequest ();
if (null === $front->getRequest ()) {
$request = new MyRequest();
$front->setRequest ( $request );
}
return $request;
}
A bit dirty and untested solution. Would love to hear if it works.
//Bootstrap:
public function _initRequest()
{
$this->bootstrap('frontController');
$front = $this->getResource('frontController');
$front->setRequest(new MyRequest());
}
Try this it might help you:
in controller file
public function exampleAction(){
$result = $this->_request;
$model = new Employer_Model_JobInfo();
$results = $model->sample($result);
}
// the above line stores the values sent from the client side in $result.then sends that values to Model file with parameter $result ..
in model file
class Employer_Model_JobInfo extends Gears_Db_Table_Abstract{
public function sample($param){
$paramVal = $param->getParam('name');
$paramVal1 = $param->getParam('email');
}
}
The name and email are what name used to sent the data from client to server.