I am new to Magneto. and i searched and tried different solution online but they didn't work. I have an observer from which I generate CSV file whenever a customer place an order. I'm using <sales_order_place_after> to get it triggered. now i want to add the code to send the email with the generated CSV file in attachment to the customer. What's the way to do this in Magento 2.4. the solution i found online is not working. I want to add the code in the execute(\Magento\Framework\Event\Observer $observer) function of this file.
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('Company Name', 'Contact Name', 'Contact Email', 'Contact Phone','Shipping Address' ,'SKU','QTY','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['Company Name'] = "";
$orderdetail['Contact Name'] = $order->getCustomerName();
$orderdetail['Contact Email'] = $order->getCustomerEmail();
$orderdetail['Contact Phone'] = $order->getShippingAddress()->getTelephone();
$streetadd = $order->getShippingAddress()->getStreet();
$orderdetail['Shipping Address'] = $streetadd[0];
$items = $order->getAllItems();
foreach ($items as $item) {
$orderdetail['SKU'] = $item->getSKU();
$orderdetail['QTY'] = $item->getQtyOrdered();
$orderdetail['Price'] = $item->getPrice();
$orderdetail['Total'] = $item->getRowTotalInclTax();
$quantity = $item->getQtyOrdered();
$orderdetail['Weight'] = $item->getWeight() * $quantity ;
$stream->writeCsv($orderdetail);
}
$stream->unlock();
$stream->close();
}
}
CodePudding user response:
You need to use Plugin for this -
Note - Use you csv generation code before mail send to attach the file
Create di.xml inside etc folder
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Sales\Model\Order\Email\Sender\OrderSender"> <plugin name="AttachEmail" type="Vendor\Module_Name\Plugin\Model\Email\Sender\OrderSender"/> </type> <type name="Magento\Framework\Mail\TransportInterface"> <plugin name="AttachEmailTransport" type="Vendor\Module_Name\Plugin\Model\Transport"/> </type> </config>
Inside the OrderSender Model
Important file to identify if order email
<?php
namespace Vendor\Module_Name\Plugin\Model\Email\Sender;
use Magento\Framework\Registry;
class OrderSender
{
public function __construct(
Registry $registry
) {
$this->registry = $registry;
}
public function beforeSend(
$subject,
$order
) {
$this->registry->unregister('email_attachments_type');
$this->registry->unregister('email_attachments_source');
$this->registry->register('email_attachments_type', 'order');
$this->registry->register('email_attachments_source', $order);
}
}
?>
- Vendor\Module_Name\Plugin\Model\Transport
In this file -
<?php
namespace Vendor\Module_Name\Plugin\Model;
use Magento\Framework\Mail\TransportInterface as Subject;
use Magento\Framework\Registry;
use Zend\Mime\Message;
use Zend\Mime\Part;
use Zend_Mime;
use function GuzzleHttp\Psr7\mimetype_from_filename;
use Magento\Framework\Filesystem;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\ObjectManagerInterface;
class Transport
{
protected $_filterProvider;
protected $_storeManager;
protected $_blockFactory;
public function __construct(
Registry $registry,
Filesystem $filesystem,
ObjectManagerInterface $objectManager,
\Magezon\Core\Helper\Data $coreHelper,
\Magezon\EmailAttachments\Helper\Data $dataHelper,
\Magento\Cms\Model\Template\FilterProvider $filterProvider,
\Magento\Store\Model\StoreManagerInterface $storeManager
) {
$this->objectManager = $objectManager;
$this->registry = $registry;
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
$this->coreHelper = $coreHelper;
$this->dataHelper = $dataHelper;
$this->_filterProvider = $filterProvider;
$this->_storeManager = $storeManager;
}
public function beforeSendMessage(
Subject $subject
) {
$type = $this->registry->registry('mgz_email_attachments_type');
$source = $this->registry->registry('mgz_email_attachments_source');
if($source && $type == 'order'){
try {
//pass file name and it will get from media directory
$filename = '';
$this->prepareMessage(
$message,
file_get_contents($this->getAbsolutePathFile($filename)),
'test.csv',
mimetype_from_filename($this->getFileUrl($filename))
);
} catch (\Exception $e) {
}
}
}
}
public function prepareMessage($message, $content, $name, $type)
{
$this->setParts($message->getBody()->getParts());
$this->createAttachment(
$content,
$type,
Zend_Mime::DISPOSITION_ATTACHMENT,
Zend_Mime::ENCODING_BASE64,
$name
);
$parts = $this->getParts();
$mimeMessage = new Message();
$mimeMessage->setParts($parts);
$message->setBody($mimeMessage);
}
public function createAttachment(
$body,
$mimeType,
$disposition = Zend_Mime::DISPOSITION_ATTACHMENT,
$encoding = Zend_Mime::ENCODING_BASE64,
$filename = null
) {
$mp = new Part($body);
$mp->encoding = $encoding;
$mp->type = $mimeType;
$mp->disposition = $disposition;
$mp->filename = $filename;
$this->_addAttachment($mp);
return $mp;
}
/**
* Adds an existing attachment to the mail message
*
* @param Zend_Mime_Part $attachment
* @return Zend_Mail Provides fluent interface
*/
public function _addAttachment($attachment)
{
$this->addPart($attachment);
return $this;
}
/**
* @param Zend_Mime_Part $part
*/
public function addPart($part)
{
$this->_parts[] = $part;
}
/**
* @return array
*/
public function getParts()
{
return $this->_parts;
}
/**
* @param array $parts
*/
public function setParts($parts)
{
$this->_parts = $parts;
return $this;
}
/**
* @return string
*/
public function getAbsolutePathFile($fileName)
{
return $this->mediaDirectory->getAbsolutePath($fileName);
}
/**
* @return string
*/
public function getFileUrl($fileName)
{
return $this->coreHelper->getMediaUrl() . $fileName;
}
protected function generateLog($message){
$writer = new \Zend_Log_Writer_Stream(BP . '/var/log/ETicket.log');
$logger = new \Zend_Log();
$logger->addWriter($writer);
$logger->info($message);
}
protected function generateLogCreditMemo($message){
$writer = new \Zend_Log_Writer_Stream(BP . '/var/log/CreditMemo.log');
$logger = new \Zend_Log();
$logger->addWriter($writer);
$logger->info($message);
}
}
Hope this will help